<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Snadend3</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Snadend3"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Snadend3"/>
	<updated>2026-05-16T16:28:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152912</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152912"/>
		<updated>2023-12-14T16:57:13Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''user_has_needed_privileges?:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def user_has_needed_privileges?(user_rights, required_privilege)&lt;br /&gt;
        return false unless user_rights.present? &amp;amp;&amp;amp; user_rights['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*'''current_user_has_super_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_instructor_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_ta_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_student_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_assignment_participant:'''&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_teaching_staff_of_assignment:'''&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_a:'''&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_id:'''&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_created_bookmark_id:'''&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_can_submit:'''&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_can_submit?(token, user_id)&lt;br /&gt;
   current_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_can_review:'''&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def current_user_can_review?(token, user_id)&lt;br /&gt;
   current_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_can_take_quiz:'''&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   current_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_can_read:'''&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def current_user_can_read?(token, user_id)&lt;br /&gt;
   current_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*'''Generate a JWT token using Postman:'''&lt;br /&gt;
&lt;br /&gt;
1.Open Postman and create a new request or collection.&lt;br /&gt;
&lt;br /&gt;
2.In the request, go to the &amp;quot;Authorization&amp;quot; tab and choose &amp;quot;Bearer Token&amp;quot; as the type.&lt;br /&gt;
&lt;br /&gt;
3.Click &amp;quot;Get New Access Token&amp;quot; to open the &amp;quot;Token&amp;quot; modal.&lt;br /&gt;
&lt;br /&gt;
4.Configure the token with a name, grant type, token endpoint URL, client ID, secret, scope, etc.&lt;br /&gt;
&lt;br /&gt;
5.Click &amp;quot;Request Token&amp;quot; to obtain the token, and enter additional credentials if prompted.&lt;br /&gt;
&lt;br /&gt;
6.The generated token is displayed in the &amp;quot;Token&amp;quot; modal and is automatically added to the request's &amp;quot;Authorization&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
7.Use the token to authenticate subsequent requests.&lt;br /&gt;
&lt;br /&gt;
8.Configure Postman to handle token expiry and automatic token refresh if needed.&lt;br /&gt;
&lt;br /&gt;
9.Save the token configuration for reuse.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Decode JWT Token:'''&lt;br /&gt;
&lt;br /&gt;
The JWT token can be decoded using jwt.io.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Run the rails server and confirm its successful execution:'''&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* '''Rspec Test cases file:'''&lt;br /&gt;
Rspec test cases file is run, and all the tests have passed.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
For more detailed explanation of the project, here is the [https://youtu.be/VJhz1xKAde4 Demo Link].&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
== Pull Request ==&lt;br /&gt;
[https://github.com/expertiza/reimplementation-back-end/pull/67 Pull Request]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152911</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152911"/>
		<updated>2023-12-14T16:54:10Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* New methods created */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''user_has_needed_privileges?:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def user_has_needed_privileges?(user_rights, required_privilege)&lt;br /&gt;
        return false unless user_rights.present? &amp;amp;&amp;amp; user_rights['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*'''current_user_has_super_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_instructor_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_ta_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_student_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_assignment_participant:'''&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_teaching_staff_of_assignment:'''&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_a:'''&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_id:'''&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_created_bookmark_id:'''&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_submit:'''&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_review:'''&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_take_quiz:'''&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_read:'''&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*'''Generate a JWT token using Postman:'''&lt;br /&gt;
&lt;br /&gt;
1.Open Postman and create a new request or collection.&lt;br /&gt;
&lt;br /&gt;
2.In the request, go to the &amp;quot;Authorization&amp;quot; tab and choose &amp;quot;Bearer Token&amp;quot; as the type.&lt;br /&gt;
&lt;br /&gt;
3.Click &amp;quot;Get New Access Token&amp;quot; to open the &amp;quot;Token&amp;quot; modal.&lt;br /&gt;
&lt;br /&gt;
4.Configure the token with a name, grant type, token endpoint URL, client ID, secret, scope, etc.&lt;br /&gt;
&lt;br /&gt;
5.Click &amp;quot;Request Token&amp;quot; to obtain the token, and enter additional credentials if prompted.&lt;br /&gt;
&lt;br /&gt;
6.The generated token is displayed in the &amp;quot;Token&amp;quot; modal and is automatically added to the request's &amp;quot;Authorization&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
7.Use the token to authenticate subsequent requests.&lt;br /&gt;
&lt;br /&gt;
8.Configure Postman to handle token expiry and automatic token refresh if needed.&lt;br /&gt;
&lt;br /&gt;
9.Save the token configuration for reuse.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Decode JWT Token:'''&lt;br /&gt;
&lt;br /&gt;
The JWT token can be decoded using jwt.io.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Run the rails server and confirm its successful execution:'''&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* '''Rspec Test cases file:'''&lt;br /&gt;
Rspec test cases file is run, and all the tests have passed.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
For more detailed explanation of the project, here is the [https://youtu.be/VJhz1xKAde4 Demo Link].&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
== Pull Request ==&lt;br /&gt;
[https://github.com/expertiza/reimplementation-back-end/pull/67 Pull Request]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152420</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152420"/>
		<updated>2023-12-05T00:40:15Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*'''Error Handling:''' The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges(user_info, required_privilege):''' The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*'''Updating existing methods in the helper wherever session is being used.'''&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*'''current_user_has_super_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_instructor_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_ta_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_student_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_assignment_participant:'''&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_teaching_staff_of_assignment:'''&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_a:'''&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_id:'''&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_created_bookmark_id:'''&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_submit:'''&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_review:'''&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_take_quiz:'''&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_read:'''&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*'''Generate a JWT token using Postman:'''&lt;br /&gt;
&lt;br /&gt;
1.Open Postman and create a new request or collection.&lt;br /&gt;
&lt;br /&gt;
2.In the request, go to the &amp;quot;Authorization&amp;quot; tab and choose &amp;quot;Bearer Token&amp;quot; as the type.&lt;br /&gt;
&lt;br /&gt;
3.Click &amp;quot;Get New Access Token&amp;quot; to open the &amp;quot;Token&amp;quot; modal.&lt;br /&gt;
&lt;br /&gt;
4.Configure the token with a name, grant type, token endpoint URL, client ID, secret, scope, etc.&lt;br /&gt;
&lt;br /&gt;
5.Click &amp;quot;Request Token&amp;quot; to obtain the token, and enter additional credentials if prompted.&lt;br /&gt;
&lt;br /&gt;
6.The generated token is displayed in the &amp;quot;Token&amp;quot; modal and is automatically added to the request's &amp;quot;Authorization&amp;quot; header.&lt;br /&gt;
&lt;br /&gt;
7.Use the token to authenticate subsequent requests.&lt;br /&gt;
&lt;br /&gt;
8.Configure Postman to handle token expiry and automatic token refresh if needed.&lt;br /&gt;
&lt;br /&gt;
9.Save the token configuration for reuse.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Decode JWT Token:'''&lt;br /&gt;
&lt;br /&gt;
The JWT token can be decoded using jwt.io.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*'''Run the rails server and confirm its successful execution:'''&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* '''Rspec Test cases file:'''&lt;br /&gt;
Rspec test cases file is run, and all the tests have passed.&lt;br /&gt;
&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152414</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152414"/>
		<updated>2023-12-05T00:26:52Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*'''Error Handling:''' The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges(user_info, required_privilege):''' The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*'''Updating existing methods in the helper wherever session is being used.'''&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*'''current_user_has_super_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_instructor_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_ta_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_student_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_assignment_participant:'''&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_teaching_staff_of_assignment:'''&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_a:'''&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_id:'''&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_created_bookmark_id:'''&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_submit:'''&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_review:'''&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_take_quiz:'''&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_read:'''&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152413</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152413"/>
		<updated>2023-12-05T00:25:24Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Existing methods updated */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*'''Error Handling:''' The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges(user_info, required_privilege):''' The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*'''Updating existing methods in the helper wherever session is being used.'''&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*'''current_user_has_super_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_admin_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_instructor_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_ta_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_student_privileges:'''&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_assignment_participant:'''&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''current_user_teaching_staff_of_assignment:'''&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_is_a:'''&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_has_id:'''&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''current_user_created_bookmark_id:'''&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_submit:'''&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_review:'''&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_take_quiz:'''&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''given_user_can_read:'''&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152412</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152412"/>
		<updated>2023-12-05T00:23:23Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* New methods created */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*'''Error Handling:''' The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges(user_info, required_privilege):''' The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*'''Updating existing methods in the helper wherever session is being used.'''&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*'''jwt_verify_and_decode:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges:'''&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152411</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152411"/>
		<updated>2023-12-05T00:22:41Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Methods Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*'''Error Handling:''' The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''check_user_privileges(user_info, required_privilege):''' The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*'''Updating existing methods in the helper wherever session is being used.'''&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152410</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152410"/>
		<updated>2023-12-05T00:18:56Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Existing methods to be updated */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152409</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152409"/>
		<updated>2023-12-05T00:18:29Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
== Existing methods to be updated ==&lt;br /&gt;
*current_user_has_super_admin_privileges&lt;br /&gt;
*current_user_is_a?&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
'''Token Encoding:'''&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
'''Token Decoding:'''&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
'''Token Expiry Handling:'''&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
'''Token Signature Verification:'''&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
'''Role-Based Access Control (RBAC):'''&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
'''Privilege Validation Methods:'''&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
'''User ID Verification:'''&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
'''User Role Verification:'''&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
'''Method Refactoring:'''&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
'''Unit Testing:'''&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152408</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152408"/>
		<updated>2023-12-05T00:15:30Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
== Existing methods to be updated ==&lt;br /&gt;
*current_user_has_super_admin_privileges&lt;br /&gt;
*current_user_is_a?&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
        return false unless user_info.present? &amp;amp;&amp;amp; user_info['role'].present?&lt;br /&gt;
    &lt;br /&gt;
        case required_privilege&lt;br /&gt;
        when 'Super-Administrator'&lt;br /&gt;
        return user_info['role'] == 'Super-Administrator'&lt;br /&gt;
        when 'Administrator'&lt;br /&gt;
        return user_info['role'] == 'Administrator'&lt;br /&gt;
        when 'Instructor'&lt;br /&gt;
        return user_info['role'] == 'Instructor'&lt;br /&gt;
        when 'Teaching Assistant'&lt;br /&gt;
        return user_info['role'] == 'Teaching Assistant'&lt;br /&gt;
        when 'Student'&lt;br /&gt;
        return user_info['role'] == 'Student'&lt;br /&gt;
        else&lt;br /&gt;
        return false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
Token Encoding:&lt;br /&gt;
Ensure that a user's information (e.g., user_id, role) is properly encoded into a JWT token during the authentication process.&lt;br /&gt;
Token Decoding:&lt;br /&gt;
Implement a method to decode and verify JWT tokens.&lt;br /&gt;
Confirm that the decoding process is successful and returns the expected user information.&lt;br /&gt;
Token Expiry Handling:&lt;br /&gt;
Check that the system handles token expiry properly and denies access or requests re-authentication when a token is expired.&lt;br /&gt;
Token Signature Verification:&lt;br /&gt;
Validate that the system verifies the signature of the JWT token to ensure its authenticity.&lt;br /&gt;
&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
Role-Based Access Control (RBAC):&lt;br /&gt;
Integrate RBAC using JWT claims to determine user roles.&lt;br /&gt;
Update methods that check for specific privileges to rely on JWT claims instead of other mechanisms.&lt;br /&gt;
Privilege Validation Methods:&lt;br /&gt;
Update existing methods (e.g., current_user_has_admin_privileges?) to utilize information from JWT claims.&lt;br /&gt;
Ensure that the system grants or denies access based on the user's role and privileges stored in the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
ser ID Verification:&lt;br /&gt;
Update methods that validate the user's identity (current_user_has_id?) to use the user_id claim from the JWT token.&lt;br /&gt;
Ensure that the system checks the user's ID against the one provided in the token.&lt;br /&gt;
User Role Verification:&lt;br /&gt;
Implement methods to check if the user has a specific role (current_user_is_a?) based on JWT claims.&lt;br /&gt;
Verify that the system accurately identifies the user's role using the JWT token.&lt;br /&gt;
&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
Method Refactoring:&lt;br /&gt;
Refactor existing authentication and authorization methods to utilize JWT claims for user information.&lt;br /&gt;
Ensure that methods no longer rely on separate data stores for user roles or privileges.&lt;br /&gt;
Unit Testing:&lt;br /&gt;
Create unit tests for each updated method to ensure that they work correctly with JWT claims.&lt;br /&gt;
Verify that the methods return expected results for various scenarios, such as different roles and expired tokens.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
*mgcghcmhv&lt;br /&gt;
[[File:E2379 postman.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*mbcgfjhgf&lt;br /&gt;
[[File:E2379 token.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*jtfjgkjhbj&lt;br /&gt;
[[File:E2379 RubyOnRails.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
* Rspec Test cases file:&lt;br /&gt;
[[File:E2379 TestsSuccess.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152288</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152288"/>
		<updated>2023-12-04T17:09:41Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Authorization Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
*'''Role Verification:'''&lt;br /&gt;
The module allows you to determine if the current user possesses specific roles such as Super-Admin, Admin, Instructor, TA (Teaching Assistant), or Student. This is pivotal for identifying the user's overarching responsibilities and access levels within the system.&lt;br /&gt;
*'''Assignment-related Checks:'''&lt;br /&gt;
You can use the module to check whether the user is a participant in a particular assignment, holds the role of an instructor for an assignment, or has TA mappings (Teaching Assistant assignments) associated with a specific task. These checks are instrumental in understanding the user's involvement and responsibilities in the context of assignments.&lt;br /&gt;
*'''Action Permissions:'''&lt;br /&gt;
The AuthorizationHelper module provides methods to determine if the current user is allowed to perform specific actions. For instance, you can check if the user can submit work, conduct reviews, or take quizzes. This functionality ensures that user actions align with their assigned roles and responsibilities.&lt;br /&gt;
*'''Access Control:'''&lt;br /&gt;
Through the aforementioned checks, the module facilitates robust access control by enabling you to tailor the user experience based on their roles and permissions. This is vital for maintaining system security and ensuring that users can only perform actions for which they are authorized.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
&lt;br /&gt;
JSON Web Tokens (JWT) are commonly used for implementing authorization in web applications. The AuthorizationHelper module can leverage JWT tokens to determine the privileges and roles of a user. Here's a general overview of how JWT tokens are typically used for authorization:&lt;br /&gt;
*'''Token Generation:'''&lt;br /&gt;
When a user logs in or authenticates, a JWT token is generated on the server-side. This token typically includes information such as the user's ID, roles, and any other relevant claims.&lt;br /&gt;
*'''Token Issuance:'''&lt;br /&gt;
The server issues the JWT token to the client after successful authentication. The client then stores this token, usually in a secure manner such as in an HTTP-only cookie or local storage.&lt;br /&gt;
*'''Token Inclusion in Requests:'''&lt;br /&gt;
For subsequent requests to the server that require authorization, the client includes the JWT token in the request headers. This can be done using the &amp;quot;Authorization&amp;quot; header with a value like &amp;quot;Bearer &amp;lt;token&amp;gt;&amp;quot;.&lt;br /&gt;
*'''Token Verification on the Server:'''&lt;br /&gt;
The server-side AuthorizationHelper module receives the JWT token from the client in the request. It then verifies the token's integrity and authenticity using a secret key known only to the server.&lt;br /&gt;
*'''Decoding the Token:'''&lt;br /&gt;
Once the token is verified, the server decodes its content. The decoded payload includes information about the user, such as their roles, which the AuthorizationHelper module can use for authorization checks.&lt;br /&gt;
*'''Authorization Checks:'''&lt;br /&gt;
The AuthorizationHelper module performs checks based on the decoded information from the JWT token. For example, it may check if the user has the required roles or permissions to access certain resources or perform specific actions.&lt;br /&gt;
*'''Access Granted or Denied:'''&lt;br /&gt;
Based on the results of the authorization checks, the server responds to the client's request by either allowing or denying access to the requested resource.&lt;br /&gt;
&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
== Existing methods to be updated ==&lt;br /&gt;
*current_user_has_super_admin_privileges&lt;br /&gt;
*current_user_is_a?&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
      return false unless user_info.present? &amp;amp;&amp;amp; user_info[:role].present?&lt;br /&gt;
  &lt;br /&gt;
      case required_privilege&lt;br /&gt;
      when 'Super-Administrator'&lt;br /&gt;
        return user_info[:role] == 'Super-Administrator'&lt;br /&gt;
      when 'Administrator'&lt;br /&gt;
        return user_info[:role] == 'Administrator'&lt;br /&gt;
      when 'Instructor'&lt;br /&gt;
        return user_info[:role] == 'Instructor'&lt;br /&gt;
      when 'Teaching Assistant'&lt;br /&gt;
        return user_info[:role] == 'Teaching Assistant'&lt;br /&gt;
      when 'Student'&lt;br /&gt;
        return user_info[:role] == 'Student'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152287</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=152287"/>
		<updated>2023-12-04T16:48:32Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki. The Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
== Existing methods to be updated ==&lt;br /&gt;
*current_user_has_super_admin_privileges&lt;br /&gt;
*current_user_is_a?&lt;br /&gt;
&lt;br /&gt;
== New methods created==&lt;br /&gt;
*jwt_verify_and_decode:&lt;br /&gt;
Description:&lt;br /&gt;
This method is part of the JWT (JSON Web Token) Authentication Integration in the application. It serves the purpose of verifying and decoding a given JWT token using the JsonWebToken class. JWT tokens are commonly used for authentication and authorization purposes in web applications.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
token (String): The JWT token that needs to be verified and decoded.&lt;br /&gt;
&lt;br /&gt;
Returns:&lt;br /&gt;
If the provided JWT token is valid, the method decodes the token using the JsonWebToken.decode method.&lt;br /&gt;
If decoding is successful, the decoded information is converted into a HashWithIndifferentAccess to provide easy access to the user information with indifferent access to symbol and string keys.&lt;br /&gt;
If the token is invalid or decoding fails (raises JWT::DecodeError), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Code'''&lt;br /&gt;
    def jwt_verify_and_decode(token)&lt;br /&gt;
      begin&lt;br /&gt;
        decoded_token = JsonWebToken.decode(token)&lt;br /&gt;
        return HashWithIndifferentAccess.new(decoded_token)&lt;br /&gt;
      rescue JWT::DecodeError&lt;br /&gt;
        return nil&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges:&lt;br /&gt;
Description:&lt;br /&gt;
This method is responsible for checking user privileges based on the claims provided in a JWT (JSON Web Token). Given the user information extracted from the JWT and a required privilege, the method determines if the user possesses the specified privilege. The method primarily validates the user's role against the required privilege.&lt;br /&gt;
&lt;br /&gt;
Parameters:&lt;br /&gt;
user_info (HashWithIndifferentAccess): User information extracted from the JWT, typically containing details like the user's role.&lt;br /&gt;
&lt;br /&gt;
required_privilege (String): The required privilege that the method checks against the user's role.&lt;br /&gt;
Returns:&lt;br /&gt;
true if the user possesses the required privilege.&lt;br /&gt;
false otherwise, including cases where the user information is not present (nil) or lacks a role.&lt;br /&gt;
&lt;br /&gt;
'''Code''':&lt;br /&gt;
    def check_user_privileges(user_info, required_privilege)&lt;br /&gt;
      return false unless user_info.present? &amp;amp;&amp;amp; user_info[:role].present?&lt;br /&gt;
  &lt;br /&gt;
      case required_privilege&lt;br /&gt;
      when 'Super-Administrator'&lt;br /&gt;
        return user_info[:role] == 'Super-Administrator'&lt;br /&gt;
      when 'Administrator'&lt;br /&gt;
        return user_info[:role] == 'Administrator'&lt;br /&gt;
      when 'Instructor'&lt;br /&gt;
        return user_info[:role] == 'Instructor'&lt;br /&gt;
      when 'Teaching Assistant'&lt;br /&gt;
        return user_info[:role] == 'Teaching Assistant'&lt;br /&gt;
      when 'Student'&lt;br /&gt;
        return user_info[:role] == 'Student'&lt;br /&gt;
      else&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
== Existing methods updated==&lt;br /&gt;
*current_user_has_super_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Super-Admin. It checks if the user has Super-Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Super-Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_super_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Super-Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_admin_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Admin (or higher). It checks if the user has Administrator privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Administrator')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_admin_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Administrator') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_instructor_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Instructor')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_instructor_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Instructor') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_ta_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of an Instructor (or higher). It checks if the user has Instructor privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Teaching Assistant')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_ta_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Teaching Assistant') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_has_student_privileges:&lt;br /&gt;
Determine if the currently logged-in user has the privileges of a Student (or higher). It checks if the user has Student privileges based on the JWT token. The method calls check_user_privileges with the appropriate privilege and returns the result.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_student_privileges?&lt;br /&gt;
   current_user_has_privileges_of?('Student')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_student_privileges?(token)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return check_user_privileges(user_info, 'Student') if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_is_assignment_participant:&lt;br /&gt;
Determine if the currently logged-in user is participating in an Assignment based on the assignment_id argument. It checks if the user is a participant in a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(assignment_id)&lt;br /&gt;
   if user_logged_in?&lt;br /&gt;
     return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: session[:user].id)&lt;br /&gt;
   end&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_assignment_participant?(token, assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return AssignmentParticipant.exists?(parent_id: assignment_id, user_id: user_info[:id]) if user_info.present?&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*current_user_teaching_staff_of_assignment:&lt;br /&gt;
Determine if the currently logged-in user is teaching staff of an Assignment based on the assignment_id argument. It checks if the user is an instructor or has TA mapping for a specific assignment based on the JWT token.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
         current_user_instructs_assignment?(assignment) ||&lt;br /&gt;
         current_user_has_ta_mapping_for_assignment?(assignment)&lt;br /&gt;
       )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_teaching_staff_of_assignment?(token, assignment_id)&lt;br /&gt;
   assignment = Assignment.find(assignment_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
     (&lt;br /&gt;
       current_user_instructs_assignment?(assignment, user_info) ||&lt;br /&gt;
       current_user_has_ta_mapping_for_assignment?(assignment, user_info)&lt;br /&gt;
     )&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_is_a:&lt;br /&gt;
Determine if the currently logged-in user IS of the given role name. It checks if the user's role in the JWT token matches the provided role name.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_is_a?(role_name)&lt;br /&gt;
   current_user_and_role_exist? &amp;amp;&amp;amp; session[:user].role.name == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_is_a?(token, role_name)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:role] == role_name&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_has_id:&lt;br /&gt;
Determine if the current user has the passed-in id value. It checks if the user's ID in the JWT token matches the provided ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_has_id?(id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; session[:user].id.eql?(id.to_i)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_has_id?(token, id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp; user_info[:id].to_i == id.to_i&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*current_user_created_bookmark_id:&lt;br /&gt;
Determine if the currently logged-in user created the bookmark with the given ID. It checks if the user in the JWT token created the bookmark with the specified ID.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(bookmark_id)&lt;br /&gt;
   user_logged_in? &amp;amp;&amp;amp; !bookmark_id.nil? &amp;amp;&amp;amp; Bookmark.find(bookmark_id.to_i).user_id == session[:user].id&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def current_user_created_bookmark_id?(token, bookmark_id)&lt;br /&gt;
   user_info = jwt_verify_and_decode(token)&lt;br /&gt;
   return user_info.present? &amp;amp;&amp;amp;&lt;br /&gt;
          !bookmark_id.nil? &amp;amp;&amp;amp;&lt;br /&gt;
          Bookmark.find(bookmark_id.to_i).user_id == user_info[:id]&lt;br /&gt;
 rescue ActiveRecord::RecordNotFound&lt;br /&gt;
   false&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_submit:&lt;br /&gt;
Determine if the given user can submit work. It checks if the user in the JWT token can submit work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_submit?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_submit?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'submit')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_review:&lt;br /&gt;
Determine if the given user can review work. It checks if the user in the JWT token can review work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_review?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_review?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'review')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_take_quiz:&lt;br /&gt;
Determine if the given user can take quizzes. It checks if the user in the JWT token can take quizzes.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(user_id)&lt;br /&gt;
   given_user_can?(user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Updated Code''':&lt;br /&gt;
 def given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
   given_user_can?(token, user_id, 'take_quiz')&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*given_user_can_read:&lt;br /&gt;
Determine if the given user can read work. It checks if the user in the JWT token can read work.&lt;br /&gt;
&lt;br /&gt;
'''Old Code''':&lt;br /&gt;
 def given_user_can_read?(user_id)&lt;br /&gt;
    given_user_can_take_quiz?(user_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' Updated Code ''':&lt;br /&gt;
 def given_user_can_read?(token, user_id)&lt;br /&gt;
   given_user_can_take_quiz?(token, user_id)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=151773</id>
		<title>CSC/ECE 517 Fall 2023 - E2379. Reimplement authorization helper.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2379._Reimplement_authorization_helper.rb&amp;diff=151773"/>
		<updated>2023-11-16T05:46:22Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2379 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza currently uses session-based authentication in its AuthorizationHelper module. The reimplementation back end uses JSON Web Token (JWT) based authentication. This requires a redesign of the AuthorizationHelper module to accommodate JWT-based authentication.&lt;br /&gt;
&lt;br /&gt;
== About Helper==&lt;br /&gt;
The AuthorizationHelper module provides methods to check a user's privileges and roles within the system. It allows you to determine if the current user has specific roles like Super-Admin, Admin, Instructor, TA, or Student. You can also check if the user is a participant in a particular assignment, instructs an assignment, or has TA mappings for an assignment. Additionally, it provides methods to identify if the current user can perform actions like submitting work, reviewing, or taking quizzes. These functions are essential for managing user permissions and access control in the application.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
*JWT Authentication Integration: Modify the AuthorizationHelper module to integrate JWT-based authentication, allowing users to authenticate and authorize requests using JWT tokens instead of sessions. &lt;br /&gt;
*Token Verification: Implement methods to verify and decode JWT tokens to extract user information and permissions.&lt;br /&gt;
*Privilege Verification: Update the existing methods (e.g., current_user_has_super_admin_privileges?, current_user_is_a?, etc) to use JWT claims to determine a user's privileges. Users will be granted access based on their role and claims within the JWT.&lt;br /&gt;
*User Identity Verification: Implement a method to verify the identity of the current user based on the JWT token. Ensure that the user's role is validated correctly.&lt;br /&gt;
*Methods should be updated to use the user's JWT claims.&lt;br /&gt;
*Error Handling: Implement appropriate error handling to deal with JWT verification failures or unauthorized access attempts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods to be implemented==&lt;br /&gt;
*jwt_verify_and_decode(token): This method will verify and decode a JWT token and return the user's information, including role and claims.&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): Given user information from the JWT and a required privilege, this method will determine if the user has the required privilege.&lt;br /&gt;
*Update and adapt the existing methods to use JWT claims for authentication and authorization.&lt;br /&gt;
&lt;br /&gt;
== Deliverables ==&lt;br /&gt;
*A modified and fully functional AuthorizationHelper module with JWT-based authentication.&lt;br /&gt;
*Updated methods to ensure JWT claims are used for authentication and authorization.&lt;br /&gt;
*Appropriate error handling to handle JWT-related issues.&lt;br /&gt;
*Unit tests should cover different scenarios and edge cases to ensure that each function works as expected&lt;br /&gt;
*Comments for every function.&lt;br /&gt;
&lt;br /&gt;
== JWT Token ==&lt;br /&gt;
A JWT contains three parts:&lt;br /&gt;
&lt;br /&gt;
*Header: Consists of two parts: The signing algorithm that’s being used and the type of token.&lt;br /&gt;
*Payload: The payload contains the claims or the JSON object.&lt;br /&gt;
*Signature: A string that is generated via a cryptographic algorithm that can be used to verify the integrity of the JSON payload.&lt;br /&gt;
&lt;br /&gt;
[[File:Jwt-structure.png]]&lt;br /&gt;
&lt;br /&gt;
== Methods Details ==&lt;br /&gt;
*Error Handling: The method is wrapped in a begin and rescue block to handle JWT::DecodeError. If an error occurs during the decoding process (e.g., an invalid signature or expired token), the method returns nil.&lt;br /&gt;
&lt;br /&gt;
'''Error Handling'''&lt;br /&gt;
 rescue JWT::DecodeError&lt;br /&gt;
   nil&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*check_user_privileges(user_info, required_privilege): The check_user_privileges method is responsible for determining whether a user, based on their role and claims stored in a JSON Web Token (JWT), possesses the required privilege within the context of the application. &lt;br /&gt;
&lt;br /&gt;
'''Pseudo Code'''&lt;br /&gt;
 function check_user_privileges(user_info, required_privilege):&lt;br /&gt;
    Check if User info is null&lt;br /&gt;
        return false&lt;br /&gt;
    switch statement:&lt;br /&gt;
            case 'Administrator':&lt;br /&gt;
            return user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'&lt;br /&gt;
            case 'Student':&lt;br /&gt;
            return user_info[:role] == 'Student' OR user_info[:role] == 'Teaching Assistant' OR user_info[:role] == 'Instructor' OR user_info[:role] == 'Administrator' OR user_info[:role] == 'Super-Administrator'     &lt;br /&gt;
            Other cases&lt;br /&gt;
            default:&lt;br /&gt;
             return false&lt;br /&gt;
&lt;br /&gt;
*Updating existing methods in the helper wherever session is being used.&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
*'''JWT Authentication Integration'''&lt;br /&gt;
'''Objectives:'''&lt;br /&gt;
&lt;br /&gt;
*'''Verify JWT Token Processing:'''&lt;br /&gt;
Confirm that JWT tokens are correctly processed, verified, and decoded.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Ensure that user privileges are correctly verified based on JWT claims.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Confirm that the user's identity is accurately verified based on the JWT token.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Validate that existing methods are successfully updated to use JWT claims.&lt;br /&gt;
&lt;br /&gt;
===Test Cases===&lt;br /&gt;
*'''JWT Token Processing:'''&lt;br /&gt;
Verify that a valid JWT token is successfully processed and decoded.&lt;br /&gt;
Test with an invalid token to ensure proper error handling.&lt;br /&gt;
*'''User Privilege Verification:'''&lt;br /&gt;
Check user privileges for various roles (super admin, admin, instructor, TA, student).&lt;br /&gt;
Verify user privileges for specific actions (submitting work, reviewing, etc.).&lt;br /&gt;
*'''Error Handling:'''&lt;br /&gt;
Test error handling for JWT verification failures.&lt;br /&gt;
Attempt unauthorized access and validate appropriate error handling.&lt;br /&gt;
*'''User Identity Verification:'''&lt;br /&gt;
Verify the correct identification of the current user based on the JWT token.&lt;br /&gt;
Test with various roles to ensure accurate identification.&lt;br /&gt;
*'''Existing Methods Update:'''&lt;br /&gt;
Confirm that existing methods are updated to use JWT claims for authentication and authorization.&lt;br /&gt;
Validate the behavior of updated methods with various scenarios.&lt;br /&gt;
&lt;br /&gt;
== Existing methods to be updated ==&lt;br /&gt;
*current_user_has_super_admin_privileges&lt;br /&gt;
*current_user_is_a?&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
===Mentor===&lt;br /&gt;
*Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
===Members===&lt;br /&gt;
*Sravya Karanam (skarana)&lt;br /&gt;
*Sucharitha Nadendla (snadend3)&lt;br /&gt;
*Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151259</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151259"/>
		<updated>2023-11-07T05:01:06Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/4ef5ef04388d9a578a1a367a10656764bee00c94 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed. Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity. Here is the link to [https://github.com/abhi934/expertiza/commit/16e295a4ccc9f8e01ee8b6a72f967858ff57cbf3 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/a8969c314854e1b216523657cdf4b9592545874c GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
* When dropping topic if submission already done.&lt;br /&gt;
* When deadline from dropping topic has passed.&lt;br /&gt;
* Deleting topic when topic cannot be found.&lt;br /&gt;
* Signup in case when user cannot be found.&lt;br /&gt;
* Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
* Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&gt;
-&amp;gt;'''The instructor assigns a student to a topic: '''&lt;br /&gt;
#Log in as an instructor using the credentials: username - instructor6, password - password.&lt;br /&gt;
#Select Manage -&amp;gt; Assignments, go to Etc, there add the student to participant.&lt;br /&gt;
#Then select a topic which you want to assign to that student.&lt;br /&gt;
-&amp;gt;'''Set/updates deadlines to that topic'''&lt;br /&gt;
#To set/update deadlines, select Manage -&amp;gt; Assignments &lt;br /&gt;
#Enable the staggered deadline checkbox&lt;br /&gt;
#Go to Topics, then select start show/ due date&lt;br /&gt;
#There you can assign the deadline, and click on save&lt;br /&gt;
-&amp;gt;'''Drop/Delete student from the topic'''&lt;br /&gt;
#Now go to Manage-&amp;gt; Assignments -&amp;gt;Topics&lt;br /&gt;
#We can see the assigned users to the topic&lt;br /&gt;
#Click on the ‘drop student’, then that student would be dropped from the topic.&lt;br /&gt;
&lt;br /&gt;
Here is the [https://www.youtube.com/watch?v=f98fqcRbA2U Demo Link] for manual testing.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 Pull_Request]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151257</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151257"/>
		<updated>2023-11-07T04:58:52Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/4ef5ef04388d9a578a1a367a10656764bee00c94 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed. Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity. Here is the link to [https://github.com/abhi934/expertiza/commit/16e295a4ccc9f8e01ee8b6a72f967858ff57cbf3 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/a8969c314854e1b216523657cdf4b9592545874c GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
* When dropping topic if submission already done.&lt;br /&gt;
* When deadline from dropping topic has passed.&lt;br /&gt;
* Deleting topic when topic cannot be found.&lt;br /&gt;
* Signup in case when user cannot be found.&lt;br /&gt;
* Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
* Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&gt;
-&amp;gt;'''The instructor assigns a student to a topic: '''&lt;br /&gt;
#Log in as an instructor using the credentials: username - instructor6, password - password.&lt;br /&gt;
#Select Manage -&amp;gt; Assignments, go to Etc, there add the student to participant.&lt;br /&gt;
#Then select a topic which you want to assign to that student.&lt;br /&gt;
-&amp;gt;'''Set/updates deadlines to that topic'''&lt;br /&gt;
#To set/update deadlines, select Manage -&amp;gt; Assignments &lt;br /&gt;
#Enable the staggered deadline checkbox&lt;br /&gt;
#Go to Topics, then select start show/ due date&lt;br /&gt;
#There you can assign the deadline, and click on save&lt;br /&gt;
-&amp;gt;'''Drop/Delete student from the topic'''&lt;br /&gt;
#Now go to Manage-&amp;gt; Assignments -&amp;gt;Topics&lt;br /&gt;
#We can see the assigned users to the topic&lt;br /&gt;
#Click on the ‘drop student’, then that student would be dropped from the topic.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 Pull_Request]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151256</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151256"/>
		<updated>2023-11-07T04:58:20Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/4ef5ef04388d9a578a1a367a10656764bee00c94 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed. Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity. Here is the link to [https://github.com/abhi934/expertiza/commit/16e295a4ccc9f8e01ee8b6a72f967858ff57cbf3 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/a8969c314854e1b216523657cdf4b9592545874c GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
* When dropping topic if submission already done.&lt;br /&gt;
* When deadline from dropping topic has passed.&lt;br /&gt;
* Deleting topic when topic cannot be found.&lt;br /&gt;
* Signup in case when user cannot be found.&lt;br /&gt;
* Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
* Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&gt;
-&amp;gt;The instructor assigns a student to a topic: &lt;br /&gt;
#Log in as an instructor using the credentials: username - instructor6, password - password.&lt;br /&gt;
#Select Manage -&amp;gt; Assignments, go to Etc, there add the student to participant.&lt;br /&gt;
#Then select a topic which you want to assign to that student.&lt;br /&gt;
-&amp;gt;Set/updates deadlines to that topic&lt;br /&gt;
#To set/update deadlines, select Manage -&amp;gt; Assignments &lt;br /&gt;
#Enable the staggered deadline checkbox&lt;br /&gt;
#Go to Topics, then select start show/ due date&lt;br /&gt;
#There you can assign the deadline, and click on save&lt;br /&gt;
-&amp;gt;Drop/Delete student from the topic&lt;br /&gt;
#Now go to Manage-&amp;gt; Assignments -&amp;gt;Topics&lt;br /&gt;
#We can see the assigned users to the topic&lt;br /&gt;
#Click on the ‘drop student’, then that student would be dropped from the topic.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 Pull_Request]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151249</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151249"/>
		<updated>2023-11-07T03:54:11Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/4ef5ef04388d9a578a1a367a10656764bee00c94 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed. Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity. Here is the link to [https://github.com/abhi934/expertiza/commit/16e295a4ccc9f8e01ee8b6a72f967858ff57cbf3 GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/a8969c314854e1b216523657cdf4b9592545874c GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.Here is the link to [https://github.com/abhi934/expertiza/commits/main GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151244</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151244"/>
		<updated>2023-11-07T03:45:42Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
Here is the link to [https://github.com/abhi934/expertiza/commit/372d0cdc0c29b78266a9a6e845e5a7464fa3182d GitHub commit].&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151232</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151232"/>
		<updated>2023-11-07T02:55:18Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
The RSpec test cases for the `SignUpSheetController` in `signup_sheet_controller.rb` are designed to thoroughly evaluate the functionality of managing sign-up topics for assignments. These test cases cover various scenarios, including creating new topics, updating topic properties, deleting topics, switching from original to suggested topics, and more. They verify that the controller correctly handles actions by students and instructors, respecting deadlines and submission status. Additionally, the test cases ensure that actions such as setting priorities for topics and saving topic deadlines work as intended.&lt;br /&gt;
&lt;br /&gt;
All these tests aim to validate that the controller's actions respond appropriately to user input, and that the underlying logic, database interactions, and authorization checks are functioning as expected. With these tests, developers can have confidence that the `SignUpSheetController` is working correctly and that it provides a robust platform for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151231</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151231"/>
		<updated>2023-11-07T02:50:56Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151229</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151229"/>
		<updated>2023-11-07T02:48:57Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
*'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
#unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
#Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
#Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151228</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151228"/>
		<updated>2023-11-07T02:46:27Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
#The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
#'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
#'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
#'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
#'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151227</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151227"/>
		<updated>2023-11-07T02:43:37Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
'''Refactoring the Update method'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''Improved Method names as follows'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Refactoring List Method'''&lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
 def list&lt;br /&gt;
    # Fetch the AssignmentParticipant based on the given ID&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    # Retrieve the assignment associated with the participant&lt;br /&gt;
    @assignment = @participant.assignment&lt;br /&gt;
    # Find the number of slots filled and waitlisted for sign-up topics&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)  &lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    # Fetch sign-up topics for the assignment&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
    @max_team_size = @assignment.max_team_size&lt;br /&gt;
    # Fetch the team ID if exists&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
    if @assignment.is_intelligent&lt;br /&gt;
      handle_intelligent_assignment&lt;br /&gt;
    end&lt;br /&gt;
    # Extract code related to intelligent assignment handling&lt;br /&gt;
    # Find the number of sign-up topics available&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
    # Retrieve important deadline information&lt;br /&gt;
    @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
    @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # Fetch student bids if available&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
    # Check if certain deadlines have passed to determine whether to show actions&lt;br /&gt;
    handle_deadlines&lt;br /&gt;
    # Rendering the appropriate view based on the assignment type&lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  # Handle intelligent assignment scenarios&lt;br /&gt;
  def handle_intelligent_assignment&lt;br /&gt;
    # Fetch the team ID (if it exists)&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    # Fetch bids for the team (if any) and order them by priority&lt;br /&gt;
    @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
    signed_up_topics = []&lt;br /&gt;
    @bids.each do |bid|&lt;br /&gt;
      sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
      signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
    end&lt;br /&gt;
    # Find topics that have been signed up and update the available sign-up topics&lt;br /&gt;
    signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
    @sign_up_topics -= signed_up_topics&lt;br /&gt;
    @bids = signed_up_topics&lt;br /&gt;
  end&lt;br /&gt;
  # Extract code related to handling deadlines into a separate method&lt;br /&gt;
  def handle_deadlines&lt;br /&gt;
    unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
      if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
        @show_actions = false&lt;br /&gt;
      end&lt;br /&gt;
      # Find whether the user has signed up for any topics; if so, the user won't be able to sign up again&lt;br /&gt;
      # unless the former was a waitlisted topic&lt;br /&gt;
      users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
      @selected_topics = if users_team.empty?&lt;br /&gt;
                           nil&lt;br /&gt;
                         else&lt;br /&gt;
                           SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                         end&lt;br /&gt;
    end  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''Refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
'''Refactoring Delete_signup and delete_signup_as_instructor''' &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''Refactored Code'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
'''Code Climate Issues'''&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Edge Cases===&lt;br /&gt;
&lt;br /&gt;
# When dropping topic if submission already done.&lt;br /&gt;
# When deadline from dropping topic has passed.&lt;br /&gt;
# Deleting topic when topic cannot be found.&lt;br /&gt;
# Signup in case when user cannot be found.&lt;br /&gt;
# Create signup_sheet when sign_up_topic cannot be found.&lt;br /&gt;
# Destroy signup_sheet when other topics with the same assignment exists.&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151220</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151220"/>
		<updated>2023-11-07T02:22:49Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* RSpec */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151219</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151219"/>
		<updated>2023-11-07T02:22:29Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* RSpec */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|800px|center]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151218</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151218"/>
		<updated>2023-11-07T02:21:58Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Team Members */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*sign_up_sheet_controller_spec.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
*badges_controller_spec.rb&lt;br /&gt;
*pair_programming_controller_spec.rb&lt;br /&gt;
*participants_helper_spec.rb&lt;br /&gt;
*collusion_cycle_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharitha Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151213</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151213"/>
		<updated>2023-11-07T02:09:20Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151212</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151212"/>
		<updated>2023-11-07T02:04:37Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
&amp;quot;After Refactoring&amp;quot; code is the replacement of the safe navigation operator (&amp;amp;.) used in the original code with a combination of nil? and empty? checks to maintain the same functionality while being compatible with Ruby 2.1.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The refactored code utilizes if params[:id].present? instead, which is a more concise way to check if the params[:id] is not nil or not an empty string, maintaining the same functionality. We have assigned session[:user].id to current_user and review.map.assignment to assignment, which enhances readability and code clarity. The refactored code consolidates the logic to find or create a FeedbackResponseMap based on certain conditions and maintains better code structure with straightforward if-else logic.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
The edit method is now broken down into smaller, more focused methods such as load_response_data and handle_team_reviewing.Each method is responsible for specific tasks: load_response_data handles the loading and processing of response data, while handle_team_reviewing deals with team reviewing scenarios.This separation of concerns improves code organization and readability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
The refactored code changes the conditional check for setting flash messages to use nil? and empty? instead of the safe navigation operator (&amp;amp;.), as the safe navigation operator is available from Ruby 2.3 onwards. The refactored version separates the logic for redirection based on different params[:return] values into the redirect_based_on_return method. It centralizes and isolates the redirection logic for improved readability and maintainability.&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151209</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151209"/>
		<updated>2023-11-07T01:36:41Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
The refactored version is more concise and readable. It uses the Rails 'update_attributes' method to update multiple attributes of the @topic object in a single call. It also sets a success flash message when the topic is updated successfully, which was missing in the original code. Additionally, it removes redundant calls to @topic.save after attribute assignments.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
The refactored code organizes the list method by breaking it down into smaller, more specialized methods (handle_intelligent_assignment and handle_deadlines). Here, the refactored version improves code readability, maintainability, and organization by breaking down the method into smaller, specialized functions and separating concerns, resulting in a more structured and manageable codebase.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
The refactored version assigns params[:assignment_id] and params[:topic_id] to assignment_id and topic_id variables, respectively, to avoid repetitive use of these parameters and increase code readability. The refactored version enhances readability by using meaningful variable names (assignment_id and topic_id), the string interpolation (&amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;) is used, providing a more elegant way of embedding user.id within the string. The redirection statement is cleaner, referencing the previously defined assignment_id variable (redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)), reducing repetition and enhancing code clarity.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user. &lt;br /&gt;
&lt;br /&gt;
A new method, delete_signup_common, centralizes the shared functionality, reducing redundancy and improving maintainability. The refactored code uses the who_user parameter to determine the type of user performing the deletion action, allowing a single method to handle both cases. By utilizing a shared method and parameters, the code is more concise, easier to understand, and maintain.&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151204</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151204"/>
		<updated>2023-11-07T01:21:45Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Issues/Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. &lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151203</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151203"/>
		<updated>2023-11-07T01:21:11Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Issues */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues/Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151201</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151201"/>
		<updated>2023-11-07T01:20:48Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Test Login Credentials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151200</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151200"/>
		<updated>2023-11-07T01:20:07Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Test Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151199</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151199"/>
		<updated>2023-11-07T01:19:44Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
&lt;br /&gt;
== Test Login Credentials ==&lt;br /&gt;
&amp;lt;li&amp;gt;UserId: instructor6&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Password: password&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function &amp;quot;delete_signup_common&amp;quot; to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 def delete_signup&lt;br /&gt;
  who_user = &amp;quot;student&amp;quot;&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  who_user = &amp;quot;instructor&amp;quot;&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(who_user,participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
===RSpec===&lt;br /&gt;
&lt;br /&gt;
[[File:rspec_champions.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151183</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151183"/>
		<updated>2023-11-06T21:37:53Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Modified Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Code Climate issues&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Code Climate Issues:&lt;br /&gt;
*unexpected token error (Using Ruby 2.1 parser; configure using TargetRubyVersion parameter, under AllCops): Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
   flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
&lt;br /&gt;
*Method new_feedback has a Cognitive Complexity of 6 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def new_feedback&lt;br /&gt;
    review = Response.find(params[:id]) unless params[:id].nil?&lt;br /&gt;
    if review&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: session[:user].id, parent_id: review.map.assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
        map = FeedbackResponseMap.create(reviewed_object_id: review.id, reviewer_id: reviewer.id, reviewee_id: review.map.reviewer.id)&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 def new_feedback&lt;br /&gt;
      # Replaced unless params[:id].nil? with if params[:id].present? for a more concise condition&lt;br /&gt;
    review = Response.find(params[:id]) if params[:id].present?&lt;br /&gt;
  &lt;br /&gt;
    if review&lt;br /&gt;
      #Assigned session[:user] and  review.map.assignment to variables for clarity&lt;br /&gt;
      current_user = session[:user]&lt;br /&gt;
      assignment = review.map.assignment&lt;br /&gt;
      reviewer = AssignmentParticipant.where(user_id: current_user.id, parent_id: assignment.id).first&lt;br /&gt;
      map = FeedbackResponseMap.where(reviewed_object_id: review.id, reviewer_id: reviewer.id).first&lt;br /&gt;
      &lt;br /&gt;
      # if no feedback exists by dat user den only create for dat particular response/review&lt;br /&gt;
      if map.nil?&lt;br /&gt;
        map = FeedbackResponseMap.create(&lt;br /&gt;
          reviewed_object_id: review.id,&lt;br /&gt;
          reviewer_id: reviewer.id,&lt;br /&gt;
          reviewee_id: review.map.reviewer.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
  &lt;br /&gt;
      redirect_to action: 'new', id: map.id, return: 'feedback'&lt;br /&gt;
    else&lt;br /&gt;
      redirect_back fallback_location: root_path&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method edit has 29 lines of code (exceeds 25 allowed). Method edit has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
    # Added for E1973, team-based reviewing&lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    if @map.team_reviewing_enabled&lt;br /&gt;
      @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
      if @response.nil?&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    # set more handy variables for the view&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def edit&lt;br /&gt;
    assign_action_parameters&lt;br /&gt;
    load_response_data&lt;br /&gt;
    render action: 'response'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  def handle_team_reviewing&lt;br /&gt;
    return unless @map.team_reviewing_enabled&lt;br /&gt;
  &lt;br /&gt;
    @response = Lock.get_lock(@response, current_user, Lock::DEFAULT_TIMEOUT)&lt;br /&gt;
    response_lock_action if @response.nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def load_response_data&lt;br /&gt;
    @prev = Response.where(map_id: @map.id)&lt;br /&gt;
    @review_scores = @prev.to_a&lt;br /&gt;
  &lt;br /&gt;
    if @prev.present?&lt;br /&gt;
      @sorted = @review_scores.sort do |m1, m2|&lt;br /&gt;
        if m1.version_num.to_i &amp;amp;&amp;amp; m2.version_num.to_i&lt;br /&gt;
          m2.version_num.to_i &amp;lt;=&amp;gt; m1.version_num.to_i&lt;br /&gt;
        else&lt;br /&gt;
          m1.version_num ? -1 : 1&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @largest_version_num = @sorted[0]&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    @map = @response.map&lt;br /&gt;
    handle_team_reviewing&lt;br /&gt;
    @modified_object = @response.response_id&lt;br /&gt;
    set_content&lt;br /&gt;
    @review_scores = []&lt;br /&gt;
    @review_questions.each do |question|&lt;br /&gt;
      @review_scores &amp;lt;&amp;lt; Answer.where(response_id: @response.response_id, question_id: question.id).first&lt;br /&gt;
    end&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method redirect has 27 lines of code (exceeds 25 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id&amp;amp;.empty?&lt;br /&gt;
    flash[:note] = message_id unless message_id&amp;amp;.empty?&lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team&lt;br /&gt;
      # the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 def redirect&lt;br /&gt;
    error_id = params[:error_msg]&lt;br /&gt;
    message_id = params[:msg]&lt;br /&gt;
    flash[:error] = error_id unless error_id.nil? || error_id.empty?&lt;br /&gt;
    # Safe navigation operator &amp;amp;. is available from Ruby 2.3. Currently replaced it with nil check conditional statement &lt;br /&gt;
    flash[:note] = message_id unless message_id.nil? || message_id.empty?&lt;br /&gt;
    &lt;br /&gt;
    @map = Response.find_by(map_id: params[:id])&lt;br /&gt;
    &lt;br /&gt;
    redirect_based_on_return&lt;br /&gt;
  end&lt;br /&gt;
   def redirect_based_on_return&lt;br /&gt;
    case params[:return]&lt;br /&gt;
    when 'feedback'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view_my_scores', id: @map.reviewer.id&lt;br /&gt;
    when 'teammate'&lt;br /&gt;
      redirect_to view_student_teams_path student_id: @map.reviewer.id&lt;br /&gt;
    when 'instructor'&lt;br /&gt;
      redirect_to controller: 'grades', action: 'view', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'assignment_edit'&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'edit', id: @map.response_map.assignment.id&lt;br /&gt;
    when 'selfreview'&lt;br /&gt;
      redirect_to controller: 'submitted_content', action: 'edit', id: @map.response_map.reviewer_id&lt;br /&gt;
    when 'survey'&lt;br /&gt;
      redirect_to controller: 'survey_deployment', action: 'pending_surveys'&lt;br /&gt;
    when 'bookmark'&lt;br /&gt;
      bookmark = Bookmark.find(@map.response_map.reviewee_id)&lt;br /&gt;
      redirect_to controller: 'bookmarks', action: 'list', id: bookmark.topic_id&lt;br /&gt;
    when 'ta_review' # Page should be directed to list_submissions if TA/instructor performs the review&lt;br /&gt;
      redirect_to controller: 'assignments', action: 'list_submissions', id: @map.response_map.assignment.id&lt;br /&gt;
    else&lt;br /&gt;
      # if reviewer is team, then we have to get the id of the participant from the team. the id in reviewer_id is of an AssignmentTeam&lt;br /&gt;
      reviewer_id = @map.response_map.reviewer.get_logged_in_reviewer_id(current_user.try(:id))&lt;br /&gt;
      redirect_to controller: 'student_review', action: 'list', id: reviewer_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method create has a Cognitive Complexity of 8 (exceeds 5 allowed). Method create has 29 lines of code (exceeds 25 allowed). Consider refactoring:&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
    map_id = params[:id]&lt;br /&gt;
    unless params[:map_id].nil?&lt;br /&gt;
      map_id = params[:map_id]&lt;br /&gt;
    end # pass map_id as a hidden field in the review form&lt;br /&gt;
    @map = ResponseMap.find(map_id)&lt;br /&gt;
    if params[:review][:questionnaire_id]&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
      @round = params[:review][:round]&lt;br /&gt;
    else&lt;br /&gt;
      @round = nil&lt;br /&gt;
    end&lt;br /&gt;
    is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
    @response = Response.where(map_id: @map.id, round: @round.to_i).order(created_at: :desc).first&lt;br /&gt;
    if @response.nil?&lt;br /&gt;
      @response = Response.create(map_id: @map.id, additional_comment: params[:review][:comments],&lt;br /&gt;
                                  round: @round.to_i, is_submitted: is_submitted)&lt;br /&gt;
    end&lt;br /&gt;
    was_submitted = @response.is_submitted&lt;br /&gt;
    # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
    @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
    # :version_num=&amp;gt;@version)&lt;br /&gt;
    # Change the order for displaying questions for editing response views.&lt;br /&gt;
    questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
    create_answers(params, questions) if params[:responses]&lt;br /&gt;
    msg = 'Your response was successfully saved.'&lt;br /&gt;
    error_msg = ''&lt;br /&gt;
    # only notify if is_submitted changes from false to true&lt;br /&gt;
    if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
      @response.notify_instructor_on_difference&lt;br /&gt;
      @response.email&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def create&lt;br /&gt;
  setup_response&lt;br /&gt;
  process_response&lt;br /&gt;
  finalize_response&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def setup_response&lt;br /&gt;
  map_id = params[:map_id].presence || params[:id]&lt;br /&gt;
  @map = ResponseMap.find(map_id)&lt;br /&gt;
  if params[:review][:questionnaire_id]&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:review][:questionnaire_id])&lt;br /&gt;
    @round = params[:review][:round]&lt;br /&gt;
  else&lt;br /&gt;
    @round = nil&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def process_response&lt;br /&gt;
  is_submitted = (params[:isSubmit] == 'Yes')&lt;br /&gt;
  @response = find_or_create_response&lt;br /&gt;
  was_submitted = @response.is_submitted&lt;br /&gt;
  # ignore if autoupdate try to save when the response object is not yet created.s&lt;br /&gt;
  @response.update(additional_comment: params[:review][:comments], is_submitted: is_submitted)&lt;br /&gt;
  # :version_num=&amp;gt;@version)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def finalize_response&lt;br /&gt;
  # Change the order for displaying questions for editing response views.&lt;br /&gt;
  questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  create_answers(params, questions) if params[:responses]&lt;br /&gt;
  msg = 'Your response was successfully saved.'&lt;br /&gt;
  error_msg = ''&lt;br /&gt;
  # only notify if is_submitted changes from false to true&lt;br /&gt;
  if should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
    @response.notify_instructor_on_difference&lt;br /&gt;
    @response.email&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
              return: params.permit(:return)[:return], msg: msg, error_msg: error_msg, review: params.permit(:review)[:review], save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def find_or_create_response&lt;br /&gt;
  round = @round.to_i&lt;br /&gt;
  is_submitted = params[:isSubmit] == 'Yes'&lt;br /&gt;
    # There could be multiple responses per round, when re-submission is enabled for that round.&lt;br /&gt;
    # Hence we need to pick the latest response.&lt;br /&gt;
  @response = Response.where(map_id: @map.id, round: round).order(created_at: :desc).first&lt;br /&gt;
  @response ||= Response.create(map_id: @map.id, additional_comment: params[:review][:comments], round: round, is_submitted: is_submitted)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def should_notify_instructor_on_difference?(was_submitted)&lt;br /&gt;
  @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; (!was_submitted &amp;amp;&amp;amp; @response.is_submitted) &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Method action_allowed? has a Cognitive Complexity of 6 (exceeds 5 allowed).&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      response = Response.find(params[:id])&lt;br /&gt;
      user_id = response.map.reviewer.user_id if response.map.reviewer&lt;br /&gt;
    end&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, user_id)&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, user_id)&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    response = user_id = nil&lt;br /&gt;
    action = params[:action]&lt;br /&gt;
    response = find_response_for_actions(action)&lt;br /&gt;
    case action&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      # If response has been submitted, no further editing allowed.&lt;br /&gt;
      return false if response&amp;amp;.is_submitted&lt;br /&gt;
      # Else, return true if the user is a reviewer for that response.&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    # Deny access to anyone except reviewer &amp;amp; author's team&lt;br /&gt;
    when 'delete', 'update'&lt;br /&gt;
      current_user_is_reviewer?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    when 'view'&lt;br /&gt;
      response_edit_allowed?(response.map, response_reviewer_user_id(response))&lt;br /&gt;
    else&lt;br /&gt;
      user_logged_in?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def find_response_for_actions(action)&lt;br /&gt;
    # Initialize response and user id if action is edit or delete or update or view.&lt;br /&gt;
    if %w[edit delete update view].include?(action)&lt;br /&gt;
      Response.find(params[:id])&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def response_reviewer_user_id(response)&lt;br /&gt;
    response.map.reviewer&amp;amp;.user_id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Method update has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
    begin&lt;br /&gt;
      # the response to be updated&lt;br /&gt;
      # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
      @questionnaire = questionnaire_from_response&lt;br /&gt;
      questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
      # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
      create_answers(params, questions) unless params[:responses].nil?&lt;br /&gt;
      if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
        @response.update_attribute('is_submitted', true)&lt;br /&gt;
      end&lt;br /&gt;
      if (@map.is_a? ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
        @response.notify_instructor_on_difference&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring''' &lt;br /&gt;
&lt;br /&gt;
 def update&lt;br /&gt;
    render nothing: true unless action_allowed?&lt;br /&gt;
    msg = ''&lt;br /&gt;
     # the response to be updated&lt;br /&gt;
     # Locking functionality added for E1973, team-based reviewing&lt;br /&gt;
    begin&lt;br /&gt;
      if @map.team_reviewing_enabled &amp;amp;&amp;amp; !Lock.lock_between?(@response, current_user)&lt;br /&gt;
        response_lock_action&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      update_response_attributes&lt;br /&gt;
      process_questionnaire&lt;br /&gt;
      create_answers_if_needed&lt;br /&gt;
      submit_response_if_requested&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = &amp;quot;Your response was not saved. Cause:189 #{$ERROR_INFO}&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    log_and_redirect_response_save(msg)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def update_response_attributes&lt;br /&gt;
    @response.update_attribute('additional_comment', params[:review][:comments])&lt;br /&gt;
    @response.update_attribute('is_submitted', true) if params['isSubmit'] &amp;amp;&amp;amp; params['isSubmit'] == 'Yes'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def process_questionnaire&lt;br /&gt;
    @questionnaire = questionnaire_from_response&lt;br /&gt;
    @questions = sort_questions(@questionnaire.questions)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # for some rubrics, there might be no questions but only file submission (Dr. Ayala's rubric)&lt;br /&gt;
  def create_answers_if_needed&lt;br /&gt;
    create_answers(params, @questions) unless params[:responses].nil?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def submit_response_if_requested&lt;br /&gt;
    @response.notify_instructor_on_difference if @map.is_a?(ReviewResponseMap) &amp;amp;&amp;amp; @response.is_submitted &amp;amp;&amp;amp; @response.significant_difference?&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def log_and_redirect_response_save(msg)&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].name, &amp;quot;Your response was submitted: #{@response.is_submitted}&amp;quot;, request)&lt;br /&gt;
    redirect_to controller: 'response', action: 'save', id: @map.map_id,&lt;br /&gt;
                return: params.permit(:return)[:return], msg: msg, review: params.permit(:review)[:review],&lt;br /&gt;
                save_options: params.permit(:save_options)[:save_options]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
*response_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
  describe '#update' do&lt;br /&gt;
    context 'when topic cannot be found' do&lt;br /&gt;
      it 'shows an error flash message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(SignUpTopic).to receive(:find).with('1').and_return(nil)&lt;br /&gt;
        request_params = { id: 1, assignment_id: 1 }&lt;br /&gt;
        post :update, params: request_params&lt;br /&gt;
        expect(flash[:error]).to eq('The topic could not be updated.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit#tabs-2')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  describe '#delete_signup_as_instructor' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      allow(Team).to receive(:find).with('1').and_return(team)&lt;br /&gt;
      allow(TeamsUser).to receive(:find_by).with(team_id: 1).and_return(double('TeamsUser', user: student))&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: 8, parent_id: 1).and_return(participant)&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    end&lt;br /&gt;
 context 'when either submitted files or hyperlinks of current team are not empty' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(assignment).to receive(:instructor).and_return(instructor)&lt;br /&gt;
        request_params = { id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('The student has already submitted their work, so you are not allowed to remove them.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is not nil and its due date has already passed' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        due_date.due_at = DateTime.now.in_time_zone - 1.day&lt;br /&gt;
        allow(assignment).to receive(:due_dates).and_return(due_date)&lt;br /&gt;
        allow(due_date).to receive(:find_by).with(deadline_type_id: 6).and_return(due_date)&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        request_params = { &lt;br /&gt;
          id: 1,&lt;br /&gt;
          due_date: {&lt;br /&gt;
            '1_submission_1_due_date' =&amp;gt; nil,&lt;br /&gt;
            '1_review_1_due_date' =&amp;gt; nil&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('You cannot drop a student after the drop topic deadline!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is nil' do&lt;br /&gt;
      it 'shows a flash success message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        allow(SignedUpTeam).to receive(:find_team_users).with(1, 6).and_return([team])&lt;br /&gt;
        allow(team).to receive(:t_id).and_return(1)&lt;br /&gt;
        request_params = { id: 1, topic_id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:success]).to eq('You have successfully dropped the student from the topic!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151015</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151015"/>
		<updated>2023-10-31T04:01:54Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
&lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
  describe '#update' do&lt;br /&gt;
    context 'when topic cannot be found' do&lt;br /&gt;
      it 'shows an error flash message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(SignUpTopic).to receive(:find).with('1').and_return(nil)&lt;br /&gt;
        request_params = { id: 1, assignment_id: 1 }&lt;br /&gt;
        post :update, params: request_params&lt;br /&gt;
        expect(flash[:error]).to eq('The topic could not be updated.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit#tabs-2')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  describe '#delete_signup_as_instructor' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      allow(Team).to receive(:find).with('1').and_return(team)&lt;br /&gt;
      allow(TeamsUser).to receive(:find_by).with(team_id: 1).and_return(double('TeamsUser', user: student))&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: 8, parent_id: 1).and_return(participant)&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    end&lt;br /&gt;
 context 'when either submitted files or hyperlinks of current team are not empty' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(assignment).to receive(:instructor).and_return(instructor)&lt;br /&gt;
        request_params = { id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('The student has already submitted their work, so you are not allowed to remove them.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is not nil and its due date has already passed' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        due_date.due_at = DateTime.now.in_time_zone - 1.day&lt;br /&gt;
        allow(assignment).to receive(:due_dates).and_return(due_date)&lt;br /&gt;
        allow(due_date).to receive(:find_by).with(deadline_type_id: 6).and_return(due_date)&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        request_params = { &lt;br /&gt;
          id: 1,&lt;br /&gt;
          due_date: {&lt;br /&gt;
            '1_submission_1_due_date' =&amp;gt; nil,&lt;br /&gt;
            '1_review_1_due_date' =&amp;gt; nil&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('You cannot drop a student after the drop topic deadline!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is nil' do&lt;br /&gt;
      it 'shows a flash success message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        allow(SignedUpTeam).to receive(:find_team_users).with(1, 6).and_return([team])&lt;br /&gt;
        allow(team).to receive(:t_id).and_return(1)&lt;br /&gt;
        request_params = { id: 1, topic_id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:success]).to eq('You have successfully dropped the student from the topic!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151012</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151012"/>
		<updated>2023-10-31T04:00:10Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
  describe '#update' do&lt;br /&gt;
    context 'when topic cannot be found' do&lt;br /&gt;
      it 'shows an error flash message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(SignUpTopic).to receive(:find).with('1').and_return(nil)&lt;br /&gt;
        request_params = { id: 1, assignment_id: 1 }&lt;br /&gt;
        post :update, params: request_params&lt;br /&gt;
        expect(flash[:error]).to eq('The topic could not be updated.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit#tabs-2')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  describe '#delete_signup_as_instructor' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      allow(Team).to receive(:find).with('1').and_return(team)&lt;br /&gt;
      allow(TeamsUser).to receive(:find_by).with(team_id: 1).and_return(double('TeamsUser', user: student))&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: 8, parent_id: 1).and_return(participant)&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    end&lt;br /&gt;
 context 'when either submitted files or hyperlinks of current team are not empty' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(assignment).to receive(:instructor).and_return(instructor)&lt;br /&gt;
        request_params = { id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('The student has already submitted their work, so you are not allowed to remove them.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is not nil and its due date has already passed' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        due_date.due_at = DateTime.now.in_time_zone - 1.day&lt;br /&gt;
        allow(assignment).to receive(:due_dates).and_return(due_date)&lt;br /&gt;
        allow(due_date).to receive(:find_by).with(deadline_type_id: 6).and_return(due_date)&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        request_params = { &lt;br /&gt;
          id: 1,&lt;br /&gt;
          due_date: {&lt;br /&gt;
            '1_submission_1_due_date' =&amp;gt; nil,&lt;br /&gt;
            '1_review_1_due_date' =&amp;gt; nil&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('You cannot drop a student after the drop topic deadline!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is nil' do&lt;br /&gt;
      it 'shows a flash success message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        allow(SignedUpTeam).to receive(:find_team_users).with(1, 6).and_return([team])&lt;br /&gt;
        allow(team).to receive(:t_id).and_return(1)&lt;br /&gt;
        request_params = { id: 1, topic_id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:success]).to eq('You have successfully dropped the student from the topic!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151011</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151011"/>
		<updated>2023-10-31T03:59:36Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|left]]&lt;br /&gt;
[[File:Methodname2.jpeg|500px|center]]&lt;br /&gt;
[[File:Methodname3.jpeg|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
  describe '#update' do&lt;br /&gt;
    context 'when topic cannot be found' do&lt;br /&gt;
      it 'shows an error flash message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(SignUpTopic).to receive(:find).with('1').and_return(nil)&lt;br /&gt;
        request_params = { id: 1, assignment_id: 1 }&lt;br /&gt;
        post :update, params: request_params&lt;br /&gt;
        expect(flash[:error]).to eq('The topic could not be updated.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit#tabs-2')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  describe '#delete_signup_as_instructor' do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
      allow(Team).to receive(:find).with('1').and_return(team)&lt;br /&gt;
      allow(TeamsUser).to receive(:find_by).with(team_id: 1).and_return(double('TeamsUser', user: student))&lt;br /&gt;
      allow(AssignmentParticipant).to receive(:find_by).with(user_id: 8, parent_id: 1).and_return(participant)&lt;br /&gt;
      allow(participant).to receive(:team).and_return(team)&lt;br /&gt;
    end&lt;br /&gt;
context 'when either submitted files or hyperlinks of current team are not empty' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(assignment).to receive(:instructor).and_return(instructor)&lt;br /&gt;
        request_params = { id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('The student has already submitted their work, so you are not allowed to remove them.')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is not nil and its due date has already passed' do&lt;br /&gt;
      it 'shows a flash error message and redirects to assignment#edit page' do&lt;br /&gt;
        due_date.due_at = DateTime.now.in_time_zone - 1.day&lt;br /&gt;
        allow(assignment).to receive(:due_dates).and_return(due_date)&lt;br /&gt;
        allow(due_date).to receive(:find_by).with(deadline_type_id: 6).and_return(due_date)&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        request_params = { &lt;br /&gt;
          id: 1,&lt;br /&gt;
          due_date: {&lt;br /&gt;
            '1_submission_1_due_date' =&amp;gt; nil,&lt;br /&gt;
            '1_review_1_due_date' =&amp;gt; nil&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:error]).to eq('You cannot drop a student after the drop topic deadline!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when both submitted files and hyperlinks of current team are empty and drop topic deadline is nil' do&lt;br /&gt;
      it 'shows a flash success message and redirects to assignment#edit page' do&lt;br /&gt;
        allow(team).to receive(:submitted_files).and_return([])&lt;br /&gt;
        allow(team).to receive(:hyperlinks).and_return([])&lt;br /&gt;
        allow(SignedUpTeam).to receive(:find_team_users).with(1, 6).and_return([team])&lt;br /&gt;
        allow(team).to receive(:t_id).and_return(1)&lt;br /&gt;
        request_params = { id: 1, topic_id: 1 }&lt;br /&gt;
        user_session = { user: instructor }&lt;br /&gt;
        get :delete_signup_as_instructor, params: request_params, session: user_session&lt;br /&gt;
        expect(flash[:success]).to eq('You have successfully dropped the student from the topic!')&lt;br /&gt;
        expect(response).to redirect_to('/assignments/1/edit')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151001</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=151001"/>
		<updated>2023-10-31T03:52:41Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
*The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
*Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
*signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150998</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150998"/>
		<updated>2023-10-31T03:51:08Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2684 https://github.com/expertiza/expertiza/pull/2684]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2678 https://github.com/expertiza/expertiza/pull/2678]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2677 https://github.com/expertiza/expertiza/pull/2677]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2669 https://github.com/expertiza/expertiza/pull/2669]&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150980</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150980"/>
		<updated>2023-10-31T03:38:21Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup&lt;br /&gt;
  # delete_signup method&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  # delete_signup_as_instructor method&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150963</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150963"/>
		<updated>2023-10-31T03:27:51Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png|500px|center]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
 def delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for already submitted work: #{topic_id}&amp;quot;)&lt;br /&gt;
  elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
    flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Dropping topic for ended work: #{topic_id}&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
    flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Student has dropped the topic: #{topic_id}&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# delete_signup method&lt;br /&gt;
def delete_signup&lt;br /&gt;
  participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
  assignment = participant.assignment&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to action: 'list', id: params[:id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
# delete_signup_as_instructor method&lt;br /&gt;
def delete_signup_as_instructor&lt;br /&gt;
  team = Team.find(params[:id])&lt;br /&gt;
  assignment = Assignment.find(team.parent_id)&lt;br /&gt;
  user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
  participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
  drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
  topic_id = params[:topic_id]&lt;br /&gt;
&lt;br /&gt;
  delete_signup_common(participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_conroller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150953</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150953"/>
		<updated>2023-10-31T03:24:17Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: /* Modified Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*sign_up_sheet_conroller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Methodname1.png&amp;diff=150950</id>
		<title>File:Methodname1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Methodname1.png&amp;diff=150950"/>
		<updated>2023-10-31T03:20:29Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: Snadend3 uploaded a new version of File:Methodname1.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Methodname1.png&amp;diff=150942</id>
		<title>File:Methodname1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Methodname1.png&amp;diff=150942"/>
		<updated>2023-10-31T03:19:29Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150931</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150931"/>
		<updated>2023-10-31T03:16:13Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*signup_sheet_conroller.rb&lt;br /&gt;
&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;br /&gt;
&lt;br /&gt;
==Pull Request==&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150927</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150927"/>
		<updated>2023-10-31T03:14:45Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
#[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
#[https://github.com/palvitgarg99/expertiza https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
#[https://github.com/expertiza/expertiza/pull/2345 https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*signup_sheet_conroller.rb&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150920</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150920"/>
		<updated>2023-10-31T03:12:30Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
*CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb&lt;br /&gt;
[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
*[https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*signup_sheet_conroller.rb&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150917</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150917"/>
		<updated>2023-10-31T03:10:28Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
*[https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2223._Refactor_sign_up_sheet_controller.rb]&lt;br /&gt;
*[https://github.com/palvitgarg99/expertiza]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/pull/2345]&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*signup_sheet_conroller.rb&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150915</id>
		<title>CSC/ECE 517 Fall 2023 - E2357. Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2023_-_E2357._Refactor_sign_up_sheet_controller.rb&amp;diff=150915"/>
		<updated>2023-10-31T03:08:39Z</updated>

		<summary type="html">&lt;p&gt;Snadend3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2257 OSS assignment for Fall 2023, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Expertiza is an open source project developed on Ruby on Rails. This web application is maintained by the student and faculty at NC State. This application gives complete control to the instructor to maintain the assignments in their class. With multiple functionalities such as adding topics, creating groups, and peer reviews, Expertiza is a well-developed application that can handle all types of assignments. To learn more about the full functionality Expertiza has to offer, visit the Expertiza wiki.&lt;br /&gt;
&lt;br /&gt;
== About Controller ==&lt;br /&gt;
The sign up sheet controller contains all functions related to the management of the signup sheet for an assignment:&lt;br /&gt;
&lt;br /&gt;
*Allows an instructor to add/remove topics to an assignment.&lt;br /&gt;
*Allows an instructor to edit properties of topics.&lt;br /&gt;
*Allows an instructor to assign/remove students to topics &lt;br /&gt;
*Allows a student to see the list of available topics which they can bid on for a given OSS assignment.&lt;br /&gt;
&lt;br /&gt;
== Issues ==&lt;br /&gt;
*Naming is inconsistent.  When used as a verb, “sign up” is two words.  When an adjective or a noun, it should be one word, e.g., “signup_sheet_controller.”  Cf. “sign_up_as_instructor”.  Please make the naming consistent.  Of course, this will result in changes in calling methods as well. [Mostly fixed by previous version of project.]&lt;br /&gt;
*Update method has a plethora of instance variables defined before updating. These might not be necessary (e.g., look at update method of bookmarks_controller). Decide whether so many instance variables are really needed. Refactor the variables not needed out. [This may have already been fixed, but save_topic_deadline also has these problems.]&lt;br /&gt;
*Add_signup_topics_staggered does not do anything different from add_signup_topics. Separate functions are needed, because add_signup_topics_staggered needs to make sure that the deadlines are set. [Assignment 1042 has staggered deadlines]&lt;br /&gt;
*Several method names can be improved (including: load_add_signup_topics, list, ad_info etc.)&lt;br /&gt;
*What are differences between signup_as_instructor and signup_as_instructor_action methods? Investigate if they are needed and improve the method names if both are needed. Provide comments as to what each method does.&lt;br /&gt;
*The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods.&lt;br /&gt;
*Refactor participants variable in  load_add_signup_topics&lt;br /&gt;
#[In retrospect, the meaning of this is not clear.  The @participants variable is used in a way that is very obscure, with code spread across several views, and no comments saying what it is doing.  It used to be that participants (individual students) signed up for topics.  Now, only teams can sign up for topics.  So @participants does not make sense.&lt;br /&gt;
*Signup_as_instructor_action has if-else ladder. It can be made more elegant. [If it is worth keeping this method at all.]&lt;br /&gt;
*Delete_signup and delete_signup_as_instructor have much in common and violate the DRY principle. Refactor.&lt;br /&gt;
*Also see Code Climate issues. To reduce the size of the file, you could move some methods to sign_up_sheet_helper.rb [We are trying to fix how you access Code Climate, but haven’t fixed it yet.]&lt;br /&gt;
&lt;br /&gt;
==Previous Version of Project==&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
1. The naming inconsistency issue has already been fixed by the previous version of the project. It has been verified by us.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring the Update method&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring'''&lt;br /&gt;
  def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      @topic.topic_identifier = params[:topic][:topic_identifier]&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.category = params[:topic][:category]&lt;br /&gt;
      @topic.topic_name = params[:topic][:topic_name]&lt;br /&gt;
      @topic.micropayment = params[:topic][:micropayment]&lt;br /&gt;
      @topic.description = params[:topic][:description]&lt;br /&gt;
      @topic.link = params[:topic][:link]&lt;br /&gt;
      @topic.save&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def update&lt;br /&gt;
    @topic = SignUpTopic.find(params[:id])&lt;br /&gt;
    if @topic&lt;br /&gt;
      update_max_choosers @topic&lt;br /&gt;
      @topic.update_attributes(topic_identifier: params[:topic][:topic_identifier], category: params[:topic][:category],&lt;br /&gt;
      topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      undo_link(&amp;quot;The topic: \&amp;quot;#{@topic.topic_name}\&amp;quot; has been successfully updated. &amp;quot;)&lt;br /&gt;
      flash[:success] = 'The topic has been updated.'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The topic could not be updated.'&lt;br /&gt;
    end&lt;br /&gt;
    # Akshay - correctly changing the redirection url to topics tab in edit assignment view.&lt;br /&gt;
    redirect_to edit_assignment_path(params[:assignment_id]) + '#tabs-2'&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. &lt;br /&gt;
&lt;br /&gt;
4. Improved Method names as follows:&lt;br /&gt;
[[File:Methodname1.png]]&lt;br /&gt;
&lt;br /&gt;
5. signup_as_instructor_action is used to sign up a student for a particular topic for an assignment as an instructor. signup_as_instructor function does nothing. It is an empty function. The function is not being called anywhere in the code. The method is not needed and hence removed.&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor_action '''&lt;br /&gt;
&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' signup_as_instructor function'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor; end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6. The list method is too long and is sparsely commented. Provide comments and identify if the method can be split or made cleaner by moving code to models or helper methods. This issue is fixed by  refactoring the List Method using helper methods. Here the 'list' method is doing a lot of different things, making it quite lengthy and potentially harder to maintain. So by refactoring and restructuring we can improve readability and maintainability. &lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring'''&lt;br /&gt;
&lt;br /&gt;
  def list &lt;br /&gt;
     @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
     @assignment = @participant.assignment&lt;br /&gt;
     @slots_filled = SignUpTopic.find_slots_filled(@assignment.id)&lt;br /&gt;
     @slots_waitlisted = SignUpTopic.find_slots_waitlisted(@assignment.id)&lt;br /&gt;
     @show_actions = true&lt;br /&gt;
     @priority = 0&lt;br /&gt;
     @sign_up_topics = SignUpTopic.where(assignment_id: @assignment.id, private_to: nil)&lt;br /&gt;
     @max_team_size = @assignment.max_team_size&lt;br /&gt;
     team_id = @participant.team.try(:id)&lt;br /&gt;
     @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
     if @assignment.is_intelligent&lt;br /&gt;
       @bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
       signed_up_topics = []&lt;br /&gt;
       @bids.each do |bid|&lt;br /&gt;
         sign_up_topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
         signed_up_topics &amp;lt;&amp;lt; sign_up_topic if sign_up_topic&lt;br /&gt;
       end&lt;br /&gt;
       signed_up_topics &amp;amp;= @sign_up_topics&lt;br /&gt;
       @sign_up_topics -= signed_up_topics&lt;br /&gt;
       @bids = signed_up_topics&lt;br /&gt;
     end&lt;br /&gt;
     @num_of_topics = @sign_up_topics.size&lt;br /&gt;
     @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
     @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
     @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
     unless @assignment.due_dates.find_by(deadline_type_id: 1).nil?&lt;br /&gt;
       @show_actions = false if !@assignment.staggered_deadline? &amp;amp;&amp;amp; (@assignment.due_dates.find_by(deadline_type_id: 1).due_at &amp;lt; Time.now)&lt;br /&gt;
       # Find whether the user has signed up for any topics; if so the user won't be able to&lt;br /&gt;
       # sign up again unless the former was a waitlisted topic&lt;br /&gt;
       # if team assignment, then team id needs to be passed as parameter else the user's id&lt;br /&gt;
       users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
       @selected_topics = if users_team.empty?&lt;br /&gt;
                            nil&lt;br /&gt;
                          else&lt;br /&gt;
                            SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
                          end&lt;br /&gt;
     end&lt;br /&gt;
     render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
 &lt;br /&gt;
 #Controller method&lt;br /&gt;
 def display_topics_and_signup_info&lt;br /&gt;
   find_participant_and_assignment&lt;br /&gt;
   load_signup_topic_details&lt;br /&gt;
   process_intelligent_topics if @assignment.is_intelligent&lt;br /&gt;
   load_deadlines&lt;br /&gt;
   check_user_signup_topics&lt;br /&gt;
   render_intelligent_topic_selection if @assignment.is_intelligent&lt;br /&gt;
  end&lt;br /&gt;
  private&lt;br /&gt;
  # Helper method: Find participant and assignment&lt;br /&gt;
  def find_participant_and_assignment&lt;br /&gt;
   @participant = find_participant&lt;br /&gt;
   @assignment = @participant.assignment&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Find participant based on the given ID&lt;br /&gt;
  def find_participant&lt;br /&gt;
   AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load sign-up topic details&lt;br /&gt;
  def load_signup_topic_details&lt;br /&gt;
   @slots_filled = SignUpTopic.slots_filled_for(@assignment.id)&lt;br /&gt;
   @slots_waitlisted = SignUpTopic.slots_waitlisted_for(@assignment.id)&lt;br /&gt;
   @signup_topics = SignUpTopic.public_topics_for_assignment(@assignment.id)&lt;br /&gt;
   @max_team_size = @assignment.max_team_size&lt;br /&gt;
   @use_bookmark = @assignment.use_bookmark&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Process intelligent topics&lt;br /&gt;
  def process_intelligent_topics&lt;br /&gt;
   @bids, signed_up_topics = retrieve_bids_and_signed_topics&lt;br /&gt;
   @signup_topics -= signed_up_topics&lt;br /&gt;
   @bids = signed_up_topics&lt;br /&gt;
   @num_of_topics = @signup_topics.size&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Retrieve bids and signed topics&lt;br /&gt;
 def retrieve_bids_and_signed_topics&lt;br /&gt;
  team_id = @participant.team.try(:id)&lt;br /&gt;
  bids = team_id.nil? ? [] : Bid.where(team_id: team_id).order(:priority)&lt;br /&gt;
  signed_up_topics = bids.each_with_object([]) do |bid, topics|&lt;br /&gt;
    topic = SignUpTopic.find_by(id: bid.topic_id)&lt;br /&gt;
    topics &amp;lt;&amp;lt; topic if topic&lt;br /&gt;
  end&lt;br /&gt;
   [bids, signed_up_topics &amp;amp; @signup_topics]&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Load deadlines&lt;br /&gt;
  def load_deadlines&lt;br /&gt;
   @signup_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 7)&lt;br /&gt;
   @drop_topic_deadline = @assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
   @student_bids = @participant.team.nil? ? [] : Bid.where(team_id: @participant.team.id)&lt;br /&gt;
  end&lt;br /&gt;
  # Helper method: Check user signup topics&lt;br /&gt;
  def check_user_signup_topics&lt;br /&gt;
   return unless (due_date = @assignment.due_dates.find_by(deadline_type_id: 1))&lt;br /&gt;
   @show_actions = !@assignment.staggered_deadline? &amp;amp;&amp;amp; (due_date.due_at &amp;lt; Time.now)&lt;br /&gt;
   users_team = SignedUpTeam.find_team_users(@assignment.id, session[:user].id)&lt;br /&gt;
   @selected_topics = users_team.empty? ? nil : SignedUpTeam.find_user_signup_topics(@assignment.id, users_team.first.t_id)&lt;br /&gt;
  end&lt;br /&gt;
 # Helper method: Render intelligent topic selection&lt;br /&gt;
 def render_intelligent_topic_selection&lt;br /&gt;
  render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
7.&lt;br /&gt;
&lt;br /&gt;
8.Signup_as_instructor_action has if-else ladder. Made this function more elegant. The `assignment_id` and `topic_id` are assigned to variables at the beginning of the method. This makes the code more concise and improves clarity. The refactored code reduces nesting by breaking down the conditions into separate if statements. This avoids deep nesting and makes the code more linear.&lt;br /&gt;
&lt;br /&gt;
'''Before refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
 def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
    if user.nil? # validate invalid user&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      if AssignmentParticipant.exists? user_id: user.id, parent_id: params[:assignment_id]&lt;br /&gt;
        if SignUpSheet.signup_team(params[:assignment_id], user.id, params[:topic_id])&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor signed up student for topic: ' + params[:topic_id].to_s)&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'The student is not registered for the assignment: ' &amp;lt;&amp;lt; user.id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
''' After refactoring Signup_as_instructor_action'''&lt;br /&gt;
&lt;br /&gt;
  # Signs up a student for a specific topic in an assignment by an instructor&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
    user = User.find_by(name: params[:username])&lt;br /&gt;
  # validate invalid user&lt;br /&gt;
    if user.nil?&lt;br /&gt;
      flash[:error] = 'That student does not exist!'&lt;br /&gt;
    else&lt;br /&gt;
      #assign params[:assignment_id] and params[:topic_id] to variables and use these variables to avoid repetition &lt;br /&gt;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]&lt;br /&gt;
      if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
        if SignUpSheet.signup_team(assignment_id, user.id, topic_id)&lt;br /&gt;
          flash[:success] = 'You have successfully signed up the student for the topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Instructor signed up student for topic: #{topic_id}&amp;quot;))&lt;br /&gt;
        else&lt;br /&gt;
          flash[:error] = 'The student has already signed up for a topic!'&lt;br /&gt;
          ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Instructor is signing up a student who already has a topic')&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
        ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;The student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to(controller: 'assignments', action: 'edit', id: assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9. Delete_signup and delete_signup_as_instructor violate the DRY principle. Refactored this. Created a new private function handle_signup_deletion to handle deletion for both instructor as well as student. A new function, check_signup_eligibility, generates the error message that the topic cannot be dropped. The redirect_path function is used to redirect the user.&lt;br /&gt;
&lt;br /&gt;
'''Before Refactoring Delete_signup and delete_signup_as_instructor'''&lt;br /&gt;
&lt;br /&gt;
 def delete_signup&lt;br /&gt;
    participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
    assignment = participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    # A student who has already submitted work should not be allowed to drop his/her topic!&lt;br /&gt;
    # (A student/team has submitted if participant directory_num is non-null or submitted_hyperlinks is non-null.)&lt;br /&gt;
    # If there is no drop topic deadline, student can drop topic at any time (if all the submissions are deleted)&lt;br /&gt;
    # If there is a drop topic deadline, student cannot drop topic after this deadline.&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted a work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], session[:user].id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped your topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has dropped the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    # find participant using assignment using team and topic ids&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    participant = AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id)&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      flash[:error] = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Drop failed for ended work: ' + params[:topic_id].to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + params[:topic_id].to_s)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring Delete_signup and delete_signup_as_instructor'''    &lt;br /&gt;
  def delete_signup&lt;br /&gt;
    handle_signup_deletion(params[:id], session[:user].id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    user = TeamsUser.find_by(team_id: team.id).user&lt;br /&gt;
    assignment = Assignment.find(team.parent_id)&lt;br /&gt;
    handle_signup_deletion(user.id, session[:user].id, assignment.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private def handle_signup_deletion(participant_id, user_id, assignment_id = nil)&lt;br /&gt;
    participant = AssignmentParticipant.find(participant_id)&lt;br /&gt;
    assignment ||= participant.assignment&lt;br /&gt;
    drop_topic_deadline = assignment.due_dates.find_by(deadline_type_id: 6)&lt;br /&gt;
    error_message = check_signup_eligibility(participant.team, drop_topic_deadline, user_id, params[:topic_id])&lt;br /&gt;
    if error_message&lt;br /&gt;
      flash[:error] = error_message&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, &amp;quot;Drop failed for #{error_message}: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, params[:topic_id], user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the topic!'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, user_id, &amp;quot;Student has dropped the topic: #{params[:topic_id]}&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to redirect_path(participant_id, assignment_id)&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def check_signup_eligibility(team, drop_topic_deadline, user_id, topic_id)&lt;br /&gt;
    if !team.submitted_files.empty? || !team.hyperlinks.empty?&lt;br /&gt;
      'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    elsif !drop_topic_deadline.nil? &amp;amp;&amp;amp; (Time.now &amp;gt; drop_topic_deadline.due_at)&lt;br /&gt;
      'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def redirect_path(participant_id, assignment_id)&lt;br /&gt;
    if assignment_id&lt;br /&gt;
      controller: 'assignments', action: 'edit', id: assignment_id&lt;br /&gt;
    else&lt;br /&gt;
      action: 'list', id: participant_id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
*signup_sheet_conroller.rb&lt;br /&gt;
==Tests==&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
* Ameya Vaichalikar (agvaicha)&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
* Sravya Karanam (skarana)&lt;br /&gt;
* Sucharita Nadendla (snadend3)&lt;br /&gt;
* Abhishek Desai (adesai7)&lt;/div&gt;</summary>
		<author><name>Snadend3</name></author>
	</entry>
</feed>