<?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=Aasatput</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=Aasatput"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Aasatput"/>
	<updated>2026-06-03T18:16:37Z</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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160823</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160823"/>
		<updated>2024-12-04T22:51:34Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Motivations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Refactor the save_topic_deadlines method to seperate out functionality for creating/updating deadlines this will also help with maintainability.&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_signup_student.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring of the save_topic_deadlines method&lt;br /&gt;
   Current Issue: The method is long and meandering and has basic functionality such as creating and updating topic due dates in place.&lt;br /&gt;
   Plan: We will refactor this method by refactoring it so that basic functionality like creates and updates can be moved to helper methods.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
As of Dec 3 we have covered these issues which were mentioned in our previous design doc. Only issue number 2 has been changed.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
    Refactoring the save_topic_deadlines method to make it modular and remove CRUD functionality as to modularize method logic.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
   Renaming the sign_up_as_instructor method&lt;br /&gt;
        Rename the method to clearly define the functionality it refers to and get rid of ambiguity.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://youtu.be/Qi_wiruk628&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160822</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160822"/>
		<updated>2024-12-04T20:52:17Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Issues and Plan of Action */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Refactor the save_topic_deadlines method to seperate out functionality for creating/updating deadlines this will also help with maintainability.&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_signup_student.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Refactoring of the save_topic_deadlines method&lt;br /&gt;
   Current Issue: The method is long and meandering and has basic functionality such as creating and updating topic due dates in place.&lt;br /&gt;
   Plan: We will refactor this method by refactoring it so that basic functionality like creates and updates can be moved to helper methods.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
As of Dec 3 we have covered these issues which were mentioned in our previous design doc. Only issue number 2 has been changed.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://youtu.be/Qi_wiruk628&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160821</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160821"/>
		<updated>2024-12-04T20:48:16Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Proposed Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Refactor the save_topic_deadlines method to seperate out functionality for creating/updating deadlines this will also help with maintainability.&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_signup_student.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://youtu.be/Qi_wiruk628&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160262</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160262"/>
		<updated>2024-12-03T22:50:52Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_signup_student.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://youtu.be/Qi_wiruk628&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160247</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160247"/>
		<updated>2024-12-03T22:42:43Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_signup_student.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_signup_student.png&amp;diff=160246</id>
		<title>File:Oodd signup student.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_signup_student.png&amp;diff=160246"/>
		<updated>2024-12-03T22:42:26Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160245</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160245"/>
		<updated>2024-12-03T22:41:20Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160244</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160244"/>
		<updated>2024-12-03T22:40:39Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_set_deadline.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_set_deadline.png&amp;diff=160243</id>
		<title>File:Oodd set deadline.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_set_deadline.png&amp;diff=160243"/>
		<updated>2024-12-03T22:40:21Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160242</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160242"/>
		<updated>2024-12-03T22:39:55Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''The instructor assigns a student to a topic: '''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
*'''Set/updates deadlines to that topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160241</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160241"/>
		<updated>2024-12-03T22:39:25Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:Oodd_drop_deadline.png|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160239</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=160239"/>
		<updated>2024-12-03T22:38:18Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Manual Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''Drop/Delete student from the topic'''&lt;br /&gt;
[[File:.jpeg|1000px|center]]&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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_drop_deadline.png&amp;diff=160238</id>
		<title>File:Oodd drop deadline.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_drop_deadline.png&amp;diff=160238"/>
		<updated>2024-12-03T22:36:48Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159973</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159973"/>
		<updated>2024-12-02T03:42:32Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Coverage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite covers a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159972</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159972"/>
		<updated>2024-12-02T03:41:42Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
*Make the method naming consistent.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
  assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
  @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
  @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
  due_dates = params[:due_date]&lt;br /&gt;
  topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
  review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
  topics.each_with_index do |topic, index|&lt;br /&gt;
    (1..review_rounds).each do |i|&lt;br /&gt;
      @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
      @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
      @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
      @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
&lt;br /&gt;
      %w[submission review].each do |deadline_type|&lt;br /&gt;
        deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
        next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
        topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first rescue nil&lt;br /&gt;
        if topic_due_date.nil?&lt;br /&gt;
          create_topic_due_date(topic, deadline_type, deadline_type_id, i)&lt;br /&gt;
        else&lt;br /&gt;
          update_topic_due_date(topic_due_date, deadline_type, i)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def create_topic_due_date(topic, deadline_type, deadline_type_id, round)&lt;br /&gt;
  TopicDueDate.create(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    deadline_type_id: deadline_type_id,&lt;br /&gt;
    parent_id: topic.id,&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    round: round,&lt;br /&gt;
    flag: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].flag,&lt;br /&gt;
    threshold: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].threshold,&lt;br /&gt;
    delayed_job_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].delayed_job_id,&lt;br /&gt;
    deadline_name: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].deadline_name,&lt;br /&gt;
    description_url: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].description_url,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id,&lt;br /&gt;
    type: 'TopicDueDate'&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
def update_topic_due_date(topic_due_date, deadline_type, round)&lt;br /&gt;
  topic_due_date.update_attributes(&lt;br /&gt;
    due_at: instance_variable_get('@topic_' + deadline_type + '_due_date'),&lt;br /&gt;
    submission_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id,&lt;br /&gt;
    review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_allowed_id,&lt;br /&gt;
    review_of_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].review_of_review_allowed_id,&lt;br /&gt;
    quiz_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].quiz_allowed_id,&lt;br /&gt;
    teammate_review_allowed_id: instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].teammate_review_allowed_id&lt;br /&gt;
  )&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Made the method naming consistent'''&lt;br /&gt;
Changed the method names which contained signup in their names. When used as a verb, &amp;quot;sign up&amp;quot; is two words. When used as an adjective or a noun, it should be one word. Made the changes to all the places where it these methods were getting called. Changed the rspec test cases accordingly. Resulting in removing any ambiguity and a more consistent naming of methods.&lt;br /&gt;
&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159881</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159881"/>
		<updated>2024-12-01T04:36:32Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====Minor Bug Fix====&lt;br /&gt;
We fixed a minor bug on the topics page where topics without links specified would still have the widget for external link show up. The page was setting the link as an empty string so we have modified the checks in _topic_names.html.erb to also check for an empty string.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159877</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159877"/>
		<updated>2024-12-01T04:29:19Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Modified Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
*Several method names are improved.&lt;br /&gt;
*The method load_add_signup_topics is refactored and added comments for better understanding.&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
*'''Refactored load_add_signup_topics method and modified the method name to load_signup_data_for_assignment'''&lt;br /&gt;
&lt;br /&gt;
Added comments to show the consistent usage of @participant instance variable&lt;br /&gt;
&lt;br /&gt;
'''After Refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  # retrieves all the data associated with the given assignment. Includes all topics,&lt;br /&gt;
  def load_signup_data_for_assignment(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Set the instance variable to store the assignment ID&lt;br /&gt;
    @id = assignment_id&lt;br /&gt;
&lt;br /&gt;
    #Fetch all sign-up topics associated with the given assignment ID&lt;br /&gt;
    @sign_up_topics = SignUpTopic.where('assignment_id = ?', assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots filled for the sign-up topics in the assignment&lt;br /&gt;
    @slots_filled = SignUpTopic.find_slots_filled(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Retrieve the number of slots waitlisted for the sign-up topics in the assignment&lt;br /&gt;
    @slots_waitlisted = SignUpTopic.find_slots_waitlisted(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    #Get the assignment details for the given ID&lt;br /&gt;
    @assignment = Assignment.find(assignment_id)&lt;br /&gt;
&lt;br /&gt;
    # Fetch participants (from signed-up teams table) for the assignment.&lt;br /&gt;
    # This includes both teams that have successfully signed up and those on the waitlist.&lt;br /&gt;
    # The `session[:ip]` is used here, to filter or log participant-related data based on the user's session IP.&lt;br /&gt;
    @participants = SignedUpTeam.find_team_participants(assignment_id, session[:ip])&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
4. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
5. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* _topic_names.html.erb&lt;br /&gt;
* routes.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159853</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159853"/>
		<updated>2024-11-30T22:37:45Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
====User Sign-up Process====&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
====Assignment-Specific Features====&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
====Error Handling and Edge Cases====&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
====Notable Test Cases====&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
====Test Coverage====&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
====Mocking and Stubbing====&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
====Assertions and Expectations====&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159852</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159852"/>
		<updated>2024-11-30T22:37:00Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
====Overview of SignUpSheetController Tests====&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
User Sign-up Process&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
Assignment-Specific Features&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
Error Handling and Edge Cases&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
Notable Test Cases&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
Test Coverage&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
Mocking and Stubbing&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
Assertions and Expectations&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159851</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159851"/>
		<updated>2024-11-30T22:36:38Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
'''Overview of SignUpSheetController Tests'''&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
User Sign-up Process&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
Assignment-Specific Features&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
Error Handling and Edge Cases&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
Notable Test Cases&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
Test Coverage&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
Mocking and Stubbing&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
Assertions and Expectations&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159850</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159850"/>
		<updated>2024-11-30T22:34:50Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
Overview of SignUpSheetController Tests&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
* Tests for creating new sign-up topics&lt;br /&gt;
* Verifying topic updates&lt;br /&gt;
* Ensuring proper handling of duplicate topics&lt;br /&gt;
* Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
User Sign-up Process&lt;br /&gt;
&lt;br /&gt;
*  Testing student sign-up functionality&lt;br /&gt;
*  Verifying instructor sign-up on behalf of students&lt;br /&gt;
*  Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
Assignment-Specific Features&lt;br /&gt;
&lt;br /&gt;
*  Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
*  Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
Error Handling and Edge Cases&lt;br /&gt;
&lt;br /&gt;
*  Testing responses to non-existent topics or users&lt;br /&gt;
*  Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
Notable Test Cases&lt;br /&gt;
&lt;br /&gt;
*  New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
*  Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
*  Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
*  Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
*  Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
Test Coverage&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
*  CRUD operations for topics&lt;br /&gt;
*  User interactions (both student and instructor)&lt;br /&gt;
*  Different assignment configurations&lt;br /&gt;
*  Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
Mocking and Stubbing&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
*  Mocking of User, Assignment, and Topic models&lt;br /&gt;
*  Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
Assertions and Expectations&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
*  Correct HTTP responses and redirects&lt;br /&gt;
*  Proper setting of flash messages&lt;br /&gt;
*  Database state changes&lt;br /&gt;
*  Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159849</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159849"/>
		<updated>2024-11-30T22:33:06Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
Overview of SignUpSheetController Tests&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
1. Tests for creating new sign-up topics&lt;br /&gt;
2. Verifying topic updates&lt;br /&gt;
3. Ensuring proper handling of duplicate topics&lt;br /&gt;
4. Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
User Sign-up Process&lt;br /&gt;
&lt;br /&gt;
1. Testing student sign-up functionality&lt;br /&gt;
2. Verifying instructor sign-up on behalf of students&lt;br /&gt;
3. Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
Assignment-Specific Features&lt;br /&gt;
&lt;br /&gt;
1. Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
2. Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
Error Handling and Edge Cases&lt;br /&gt;
&lt;br /&gt;
1. Testing responses to non-existent topics or users&lt;br /&gt;
2. Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
Notable Test Cases&lt;br /&gt;
&lt;br /&gt;
1. New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
2. Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
3. Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
4. Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
5. Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
Test Coverage&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
1. CRUD operations for topics&lt;br /&gt;
2. User interactions (both student and instructor)&lt;br /&gt;
3. Different assignment configurations&lt;br /&gt;
4. Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
Mocking and Stubbing&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
1. Mocking of User, Assignment, and Topic models&lt;br /&gt;
2. Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
Assertions and Expectations&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
1. Correct HTTP responses and redirects&lt;br /&gt;
2. Proper setting of flash messages&lt;br /&gt;
3. Database state changes&lt;br /&gt;
4. Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159848</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159848"/>
		<updated>2024-11-30T22:30:30Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Test Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
Overview of SignUpSheetController Tests&lt;br /&gt;
This document describes the comprehensive test suite for the SignUpSheetController in a Ruby on Rails application. The tests cover various aspects of sign-up sheet functionality, including topic management, user sign-ups, and assignment-specific features.&lt;br /&gt;
Test Structure&lt;br /&gt;
The tests are organized using RSpec, a popular testing framework for Ruby. They utilize let statements for setting up test objects and before blocks for common setup operations.&lt;br /&gt;
Key Test Areas&lt;br /&gt;
Topic Creation and Management&lt;br /&gt;
&lt;br /&gt;
    Tests for creating new sign-up topics&lt;br /&gt;
    Verifying topic updates&lt;br /&gt;
    Ensuring proper handling of duplicate topics&lt;br /&gt;
    Testing topic deletion (single and multiple)&lt;br /&gt;
&lt;br /&gt;
User Sign-up Process&lt;br /&gt;
&lt;br /&gt;
    Testing student sign-up functionality&lt;br /&gt;
    Verifying instructor sign-up on behalf of students&lt;br /&gt;
    Handling of multiple topic sign-ups&lt;br /&gt;
&lt;br /&gt;
Assignment-Specific Features&lt;br /&gt;
&lt;br /&gt;
    Testing for different assignment types (microtask, staggered deadline, private)&lt;br /&gt;
    Verifying behavior for intelligent topic selection&lt;br /&gt;
&lt;br /&gt;
Error Handling and Edge Cases&lt;br /&gt;
&lt;br /&gt;
    Testing responses to non-existent topics or users&lt;br /&gt;
    Verifying proper error messages and redirects&lt;br /&gt;
&lt;br /&gt;
Notable Test Cases&lt;br /&gt;
&lt;br /&gt;
    New Topic Creation: Ensures a new topic can be created and saved successfully.&lt;br /&gt;
    Topic Deletion: Tests single topic deletion and bulk deletion of selected topics.&lt;br /&gt;
    Intelligent Topic Selection: Verifies the correct rendering of the intelligent topic selection page for applicable assignments.&lt;br /&gt;
    Instructor Sign-up Actions: Tests the functionality allowing instructors to sign up students for topics.&lt;br /&gt;
    Assignment Type Specific Behavior: Separate tests for microtask, staggered deadline, and private assignments.&lt;br /&gt;
&lt;br /&gt;
Test Coverage&lt;br /&gt;
The test suite appears to cover a wide range of scenarios, including:&lt;br /&gt;
&lt;br /&gt;
    CRUD operations for topics&lt;br /&gt;
    User interactions (both student and instructor)&lt;br /&gt;
    Different assignment configurations&lt;br /&gt;
    Error states and edge cases&lt;br /&gt;
&lt;br /&gt;
Mocking and Stubbing&lt;br /&gt;
The tests make extensive use of mocking and stubbing to isolate the controller tests from external dependencies:&lt;br /&gt;
&lt;br /&gt;
    Mocking of User, Assignment, and Topic models&lt;br /&gt;
    Stubbing of current user for authentication scenarios&lt;br /&gt;
&lt;br /&gt;
Assertions and Expectations&lt;br /&gt;
The tests use a variety of expectations to verify:&lt;br /&gt;
&lt;br /&gt;
    Correct HTTP responses and redirects&lt;br /&gt;
    Proper setting of flash messages&lt;br /&gt;
    Database state changes&lt;br /&gt;
    Instance variable assignments&lt;br /&gt;
&lt;br /&gt;
This comprehensive test suite ensures robust functionality of the SignUpSheetController across various scenarios and configurations.&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;
*'''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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159847</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159847"/>
		<updated>2024-11-30T22:14:48Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/b26d44a7ea1ad05618564025ba36ab4a9acc53ce Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
Before refactoring:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def signup_as_instructor; end  ##In signup sheet controller   &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), signup_as_instructor_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;     ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
 get :signup_as_instructor   ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
After Refactoring&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def select_student_for_signup; end    ##In signup sheet controller&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;%= link_to image_tag('signup.png', :border =&amp;gt; 0, :title =&amp;gt; 'Sign Up Student', :align =&amp;gt; 'middle'), select_student_for_signup_sign_up_sheet_index_path( assignment_id: params[:id], topic_id: topic.id) %&amp;gt;      ##In app/views/sign_up_sheet/_topic_names.html.erb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 get :select_student_for_signup     ##config/routes.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159846</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159846"/>
		<updated>2024-11-30T21:52:32Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor method [https://github.com/DarthAsh/expertiza/commit/05282328acac2387a3b4c364f0e50b99536b583d Commit]'''&lt;br /&gt;
The signup_as_instructor method was wrongly named. This method is only used to redirect the user to a page where the student to be signed up is selected. To solve this situation we have renamed this method to select_student_for_signup. This also involved renaming the paths and the template.&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159845</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159845"/>
		<updated>2024-11-30T21:19:45Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
&lt;br /&gt;
    @assignment_submission_due_dates, @assignment_review_due_dates = fetch_assignment_due_dates(assignment)&lt;br /&gt;
&lt;br /&gt;
    topics.each do |topic|&lt;br /&gt;
     (1..review_rounds).each do |round|&lt;br /&gt;
       process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
   redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end      &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functionality moved to signup_sheet_helper.rb&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def extract_due_dates(assignment, deadline_type_id)&lt;br /&gt;
    assignment.due_dates.select { |due_date| due_date.deadline_type_id == deadline_type_id }.map { |due_date| format_due_date(due_date.due_at) }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def format_due_date(due_at)&lt;br /&gt;
    DateTime.parse(due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_topic_deadline(topic, round, deadline_type, due_dates, assignment_due_dates)&lt;br /&gt;
    topic_due_date_key = &amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;&lt;br /&gt;
    topic_due_date = due_dates[topic_due_date_key]&lt;br /&gt;
    assignment_due_date = assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
&lt;br /&gt;
    return if topic_due_date == assignment_due_date&lt;br /&gt;
&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    topic_due_date_record = TopicDueDate.where(&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      round: round&lt;br /&gt;
    ).first_or_initialize&lt;br /&gt;
  &lt;br /&gt;
    save_or_update_deadline(topic_due_date_record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def save_or_update_deadline(record, topic_due_date, assignment_due_dates, deadline_type, round)&lt;br /&gt;
    assignment_due_date_details = instance_variable_get('@assignment_' + deadline_type + '_due_dates')[round - 1].submission_allowed_id&lt;br /&gt;
#assignment_due_dates[deadline_type.to_sym][round - 1]&lt;br /&gt;
    puts assignment_due_date_details &lt;br /&gt;
&lt;br /&gt;
    attributes = {&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date_details.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date_details.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date_details.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date_details.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date_details.teammate_review_allowed_id,&lt;br /&gt;
      round: round,&lt;br /&gt;
      flag: assignment_due_date_details.flag,&lt;br /&gt;
      threshold: assignment_due_date_details.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date_details.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date_details.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date_details.description_url,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    }&lt;br /&gt;
    record.update(attributes)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_assignment_due_dates(assignment)&lt;br /&gt;
    submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
   [submission_due_dates, review_due_dates]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_due_dates_for_topic_and_round(topic, round, due_dates)&lt;br /&gt;
   %w[submission review].each do |deadline_type|&lt;br /&gt;
    topic_due_date = due_dates[&amp;quot;#{topic.id}_#{deadline_type}_#{round}_due_date&amp;quot;]&lt;br /&gt;
    assignment_due_date = @assignment_submission_due_dates if deadline_type == 'submission'&lt;br /&gt;
    assignment_due_date ||= @assignment_review_due_dates&lt;br /&gt;
    current_due_date = assignment_due_date[round - 1]&lt;br /&gt;
    next if topic_due_date == current_due_date.due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
    deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
    existing_due_date = TopicDueDate.find_by(parent_id: topic.id, deadline_type_id: deadline_type_id, round: round)&lt;br /&gt;
    if existing_due_date&lt;br /&gt;
      update_topic_due_date(existing_due_date, current_due_date, topic_due_date)&lt;br /&gt;
    else&lt;br /&gt;
      create_topic_due_date(topic, current_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def create_topic_due_date(topic, assignment_due_date, deadline_type_id, round, topic_due_date)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      deadline_type_id: deadline_type_id,&lt;br /&gt;
      parent_id: topic.id,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id,&lt;br /&gt;
      flag: assignment_due_date.flag,&lt;br /&gt;
      threshold: assignment_due_date.threshold,&lt;br /&gt;
      delayed_job_id: assignment_due_date.delayed_job_id,&lt;br /&gt;
      deadline_name: assignment_due_date.deadline_name,&lt;br /&gt;
      description_url: assignment_due_date.description_url,&lt;br /&gt;
      round: round,&lt;br /&gt;
      type: 'TopicDueDate'&lt;br /&gt;
    )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def update_topic_due_date(existing_due_date, assignment_due_date, topic_due_date)&lt;br /&gt;
    existing_due_date.update(&lt;br /&gt;
      due_at: topic_due_date,&lt;br /&gt;
      submission_allowed_id: assignment_due_date.submission_allowed_id,&lt;br /&gt;
      review_allowed_id: assignment_due_date.review_allowed_id,&lt;br /&gt;
      review_of_review_allowed_id: assignment_due_date.review_of_review_allowed_id,&lt;br /&gt;
      quiz_allowed_id: assignment_due_date.quiz_allowed_id,&lt;br /&gt;
      teammate_review_allowed_id: assignment_due_date.teammate_review_allowed_id&lt;br /&gt;
   )&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159844</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159844"/>
		<updated>2024-11-30T21:14:38Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159018</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159018"/>
		<updated>2024-11-12T03:24:07Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
===Motivations===&lt;br /&gt;
1. Single Responsibility Principle (SRP)&lt;br /&gt;
&lt;br /&gt;
    Consistent Naming Conventions&lt;br /&gt;
        Ensures each method and variable has a clear, singular responsibility, reducing ambiguity.&lt;br /&gt;
&lt;br /&gt;
    Improving Method Names&lt;br /&gt;
        Provides clarity by giving each method a name that directly reflects its purpose.&lt;br /&gt;
&lt;br /&gt;
    Clarifying the @participants Variable Usage&lt;br /&gt;
        Refactors ambiguous terminology, giving each variable a clear role and responsibility.&lt;br /&gt;
&lt;br /&gt;
    DRY Principle for Delete Methods&lt;br /&gt;
        Consolidates shared functionality into a helper function, allowing each method to perform a single, specific task.&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Moves methods to helper files, promoting separation of concerns and keeping each file focused on specific tasks.&lt;br /&gt;
&lt;br /&gt;
2. Open/Closed Principle (OCP)&lt;br /&gt;
&lt;br /&gt;
    Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
        Refactors the if-else ladder to facilitate easier extension of functionality without modifying existing logic, promoting modularity.&lt;br /&gt;
&lt;br /&gt;
3. Interface Segregation Principle (ISP)&lt;br /&gt;
&lt;br /&gt;
    Method Consolidation for Signup Topics&lt;br /&gt;
        Ensures each method is specialized for a distinct purpose, preventing overlapping or unnecessary functionality.&lt;br /&gt;
&lt;br /&gt;
4. Dependency Inversion Principle (DIP)&lt;br /&gt;
&lt;br /&gt;
    Code Climate Issues and Method Relocation&lt;br /&gt;
        Organizes the codebase into helper files, creating a modular structure where the main code depends on specialized, independent helper classes or files.&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159014</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159014"/>
		<updated>2024-11-12T03:19:10Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Final Design Document==&lt;br /&gt;
&lt;br /&gt;
===Current Status===&lt;br /&gt;
We have successfully completed the following refactoring and functionality improvements:&lt;br /&gt;
&lt;br /&gt;
1. Update Method: Reviewed and removed unnecessary instance variables in the update method, making it more efficient and streamlined.&lt;br /&gt;
2. Signup Methods: Refined the `signup_as_instructor` and `signup_as_instructor_action` methods by investigating their distinct roles, renaming them for consistency, and adding comprehensive comments to improve readability.&lt;br /&gt;
3. List Method: Simplified and documented the `list` method, breaking down the code into smaller helper functions where possible to enhance readability and maintainability.&lt;br /&gt;
4. Save Topic Deadline Method: Removed unnecessary variables and converted instance variables that were not required to be instance variables into local variables and tested the functionality thoroughly.&lt;br /&gt;
&lt;br /&gt;
These changes have been implemented and tested to ensure they meet the requirements for clarity, functionality, and performance.&lt;br /&gt;
&lt;br /&gt;
===Issues and Plan of Action===&lt;br /&gt;
1. Consistent Naming Conventions&lt;br /&gt;
   Current Issue: Some methods and variables use inconsistent naming conventions for &amp;quot;sign up&amp;quot; and &amp;quot;signup,&amp;quot; leading to potential confusion in understanding their roles.  &lt;br /&gt;
   Plan: We will review the codebase to ensure that &amp;quot;sign up&amp;quot; is consistently used as a verb, while &amp;quot;signup&amp;quot; is used as a noun or adjective. This will include changes to calling methods and any documentation impacted by the renaming.&lt;br /&gt;
&lt;br /&gt;
2. Method Consolidation for Signup Topics&lt;br /&gt;
   Current Issue: The `add_signup_topics_staggered` method duplicates much of the functionality found in `add_signup_topics`, despite being intended for staggered deadlines (e.g., Assignment 1042).  &lt;br /&gt;
   Plan: We will consolidate these functions by ensuring that staggered deadlines are handled within `add_signup_topics_staggered` as a distinct feature, streamlining the code and reducing redundancy.&lt;br /&gt;
&lt;br /&gt;
3. Improving Method Names  &lt;br /&gt;
   Current Issue: Several methods, including `load_add_signup_topics`, `ad_info`, and `list`, could benefit from more descriptive names to clarify their purpose and enhance code readability.  &lt;br /&gt;
   Plan: We will rename these methods to better reflect their functions, making the code more intuitive for future developers and maintainers.&lt;br /&gt;
&lt;br /&gt;
4. Clarifying the `@participants` Variable Usage  &lt;br /&gt;
   Current Issue: The `@participants` variable in `load_add_signup_topics` is used ambiguously. Initially, this variable represented individual students signing up for topics, but now only teams can sign up, making the `@participants` terminology obsolete.  &lt;br /&gt;
   Plan: We will refactor the code to replace `@participants` with a variable name that more accurately reflects its current role. Additionally, we’ll add comments to clarify its function across different views.&lt;br /&gt;
&lt;br /&gt;
5. Improving the Signup Action Method’s If-Else Ladder&lt;br /&gt;
   Current Issue: The `signup_as_instructor_action` method contains an if-else ladder that could be simplified for better readability and maintainability.  &lt;br /&gt;
   Plan: We will refactor the if-else ladder using more elegant conditional logic or helper methods, aiming for a cleaner, more modular approach.&lt;br /&gt;
&lt;br /&gt;
6. DRY Principle for Delete Methods  &lt;br /&gt;
   Current Issue: The `delete_signup` and `delete_signup_as_instructor` methods have significant overlap, violating the DRY (Don’t Repeat Yourself) principle.  &lt;br /&gt;
   Plan: We will extract shared functionality from these methods into a common helper function, making the code more modular and easier to maintain.&lt;br /&gt;
&lt;br /&gt;
7. Code Climate Issues and Method Relocation &lt;br /&gt;
   Current Issue: Some methods could be moved to `sign_up_sheet_helper.rb` to reduce the size of the main file and improve code organization.  &lt;br /&gt;
   Plan: We will review Code Climate issues and move appropriate methods to `sign_up_sheet_helper.rb` as a step towards better code organization and file structure.&lt;br /&gt;
&lt;br /&gt;
By addressing these remaining issues, we will work toward a cleaner, more efficient, and well-documented codebase that adheres to best practices.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159013</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159013"/>
		<updated>2024-11-12T03:16:48Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Modified Files===&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Relevant Links===&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
===Team===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159012</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159012"/>
		<updated>2024-11-12T03:16:06Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
=== Design Plan ===&lt;br /&gt;
==== Proposed Changes ====&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
==== Design Objectives ====&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
==== Plan of Work ====&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
===Solutions===&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===Test 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;
===Manual Testing===&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
===Rspec===&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
===Modified Files===&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Relevant Links===&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
===Team===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159011</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=159011"/>
		<updated>2024-11-12T03:14:55Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2471. E2455. Refactor sign up sheet controller.rb==&lt;br /&gt;
&lt;br /&gt;
This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158271</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158271"/>
		<updated>2024-10-30T02:36:35Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Modified Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158267</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158267"/>
		<updated>2024-10-30T02:35:41Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Design Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications. The delete_signup and delete_signup_as_instructor methods have also been refactored to make sure they only handle their respective functions. All common functionality has been removed to private methods.&lt;br /&gt;
&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158257</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=158257"/>
		<updated>2024-10-30T02:32:10Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E2409_Refactor_sign_up_sheet_controller.rb&amp;diff=158244</id>
		<title>E2409 Refactor sign up sheet controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E2409_Refactor_sign_up_sheet_controller.rb&amp;diff=158244"/>
		<updated>2024-10-30T02:29:40Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the signup_as_instructor_action method, we reduced the function length and complexity by extracting common functionality into helper functions. By doing so, we minimized repetition, improved readability, and ensured consistency across the codebase.We can reuse the log_message() created in part 3 to write application logs. Delete_signup_common is also introduced to ensure the DRY principle is maintained in the code. &lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
*'''The previous version of the project fixed the naming discrepancy issue. We have validated it and found no other changes.'''&lt;br /&gt;
&lt;br /&gt;
* '''signup_as_instructor and signup_as_instructor_action methods functionalities breakdown '''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor: This function appears to be an empty function that doesn't perform any action. It is not called anywhere in the provided code. Hence, it seems unnecessary and can be removed.&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: This function is used to process the instructor's request to sign up a student for a particular topic for an assignment. It handles the form submission and performs the necessary actions based on the submitted data.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/Harshil47/expertiza/commit/7728e5d0ad85a6f9d4c7ca8cb933deb9e4fc9016 Commit]'''&lt;br /&gt;
By centralizing the shared functionality, delete_signup_common, a new method, lessens redundancy and enhances maintainability. A single function can handle both scenarios thanks to the refactored code, which uses the who_user parameter to identify the type of user doing the delete operation.&lt;br /&gt;
&lt;br /&gt;
The error handling logic has been enhanced to provide more descriptive error messages and to log errors appropriately using the ExpertizaLogger.&lt;br /&gt;
Logging has been improved to include more detailed information about the errors and actions being performed.&lt;br /&gt;
Comments have been added to describe each section of the code and explain the purpose of the methods and conditional blocks.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup_common(who_user, participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  # This method centralizes the shared functionality, reducing redundancy and improving maintainability&lt;br /&gt;
  #this function is used to delete a previous signup&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    # Handle case where participant has already submitted work&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;
    # Handle case where drop topic deadline has passed&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;
    # No errors, proceed with dropping topic&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic.'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + topic_id.to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, 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: ' + topic_id.to_s)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:''' https://drive.google.com/file/d/1MTfX_cHa6zy34WQRNgXOybQXDya4J1R2/view?usp=drive_link&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157574</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157574"/>
		<updated>2024-10-29T19:53:02Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Rspec */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Rspec-test.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Rspec-test.jpeg&amp;diff=157573</id>
		<title>File:Rspec-test.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Rspec-test.jpeg&amp;diff=157573"/>
		<updated>2024-10-29T19:50:56Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: image of successful rspec test&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
image of successful rspec test&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157391</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157391"/>
		<updated>2024-10-29T04:56:07Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Team */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:Devansh Shah - dshah8@ncsu.edu&amp;lt;/b&amp;gt; &lt;br /&gt;
* Bhushan Patil - bpatil@ncsu.edu&lt;br /&gt;
* Mragisha Jain - mjain22@ncsu.edu&lt;br /&gt;
* Ashwin Satpute - aasatput@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157389</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157389"/>
		<updated>2024-10-29T04:53:11Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/DarthAsh/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2868&lt;br /&gt;
* '''Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157387</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157387"/>
		<updated>2024-10-29T04:43:59Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Plan of Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
*Refactor save_topic_deadlines to remove variables that are not necessary.&lt;br /&gt;
*Refactor the save_topic_deadlines method by converting any instance variables that are not essential for maintaining the state of the instance into local variables..&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
TBD based on review of Project 3&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157383</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157383"/>
		<updated>2024-10-29T04:39:04Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Design Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
*Refactor the delete_signup and delete_signup_as_instructor to remove common functionality to private methods and simplify readability.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157382</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157382"/>
		<updated>2024-10-29T04:37:18Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Design Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in signup_as_instructor_action method to reduce complexity, simplify program flow and make it readable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157381</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157381"/>
		<updated>2024-10-29T04:34:41Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable. Also by converting the unnecessary instance variable to local in save_topic_deadlines method increased the maintainability as now the scope of those variables will be confined to the methods itself.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def signup_as_instructor_action&lt;br /&gt;
  user = User.find_by(name: params[:username])&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not found&lt;br /&gt;
  if user.nil?&lt;br /&gt;
    flash[:error] = 'That student does not exist!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', 'Student does not exist')&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Early return if user is not registered for the assignment&lt;br /&gt;
  unless AssignmentParticipant.exists?(user_id: user.id, parent_id: params[:assignment_id])&lt;br /&gt;
    flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', &amp;quot;Student is not registered for the assignment: #{user.id}&amp;quot;)&lt;br /&gt;
    return redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # Check if signup is successful or not&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, '', &amp;quot;Instructor signed up student for topic: #{params[: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;
&lt;br /&gt;
  redirect_to controller: 'assignments', action: 'edit', id: params[:assignment_id]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method [https://github.com/DarthAsh/expertiza/commit/5735b5bb180ac4c9c4d5329ab11c7b4775d1cfda Commit]'''&lt;br /&gt;
In our refactor of the save_topic_deadlines method we identified several variables that had been previously declared as instance variables but were not necessary for maintaining the instance's state. These variables were subsequently converted into local variables, thereby enhancing the clarity of the method and effectively encapsulating its operational context. Furthermore, we have included detailed comments throughout the code. These annotations serve to elucidate the purpose of the method, outline its logic, and document the specific changes made during the refactoring process.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
 def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    &lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        topic_submission_due_date = due_dates[&amp;quot;#{topic.id}_submission_#{i}_due_date&amp;quot;]&lt;br /&gt;
        topic_review_due_date = due_dates[&amp;quot;#{topic.id}_review_#{i}_due_date&amp;quot;]&lt;br /&gt;
        assignment_submission_due_date = assignment_submission_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        assignment_review_due_date = assignment_review_due_dates[i - 1].due_at.strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
  &lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if topic_submission_due_date == assignment_submission_due_date &amp;amp;&amp;amp; deadline_type == 'submission'&lt;br /&gt;
          next if topic_review_due_date == assignment_review_due_date &amp;amp;&amp;amp; deadline_type == 'review'&lt;br /&gt;
  &lt;br /&gt;
          topic_due_date = TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
  &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            TopicDueDate.create(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              round: i,&lt;br /&gt;
              flag: assignment_review_due_dates[i - 1].flag,&lt;br /&gt;
              threshold: assignment_review_due_dates[i - 1].threshold,&lt;br /&gt;
              delayed_job_id: assignment_review_due_dates[i - 1].delayed_job_id,&lt;br /&gt;
              deadline_name: assignment_review_due_dates[i - 1].deadline_name,&lt;br /&gt;
              description_url: assignment_review_due_dates[i - 1].description_url,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
          else # update an existing record&lt;br /&gt;
            topic_due_date.update_attributes(&lt;br /&gt;
              due_at: deadline_type == 'submission' ? topic_submission_due_date : topic_review_due_date,&lt;br /&gt;
              submission_allowed_id: assignment_submission_due_dates[i - 1].submission_allowed_id,&lt;br /&gt;
              review_allowed_id: assignment_review_due_dates[i - 1].review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: assignment_review_due_dates[i - 1].review_of_review_allowed_id,&lt;br /&gt;
              quiz_allowed_id: assignment_review_due_dates[i - 1].quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: assignment_review_due_dates[i - 1].teammate_review_allowed_id&lt;br /&gt;
            )&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157372</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157372"/>
		<updated>2024-10-29T04:02:20Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
The `SignUpSheet` controller has been refactored to improve adherence to the Single Responsibility Principle (SRP). The `list` method’s logic has been distributed to helper classes for better modularity and readability. Object creation responsibilities for `SignUpTopic` and `TopicDueDate` are now handled by a dedicated Builder class, isolating this responsibility from the controller. Additionally, the `delete_signup_common` method has been refactored to use a new `DeleteSignupAction` class with methods like `raise_flash_if_work_submitted`, `raise_flash_if_deadline_passed`, and `raise_flash_after_topic_dropped`. This base class is extended by `InstructorDeleteSignUpAction` and `ParticipantDeleteSignupAction`, which contain specific flash message logic for each role. This restructuring keeps each class focused on a single responsibility and allows for easier future modifications.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing code readability and maintainability by using clear, descriptive variable names like `assignment_id` and `topic_id`, which improve understanding at a glance. Detailed comments were added to explain each code section, clarifying the purpose of methods and conditional blocks for easier comprehension of the overall functionality. In the `signup_as_instructor_action` method, we streamlined the logic by introducing early returns, reducing nested structures, and simplifying flow. Additionally, the `list` method was improved with thorough comments, making this complex section more understandable and readable.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactored the List method [https://github.com/DarthAsh/expertiza/commit/da7e6bb31a64de3fb946e7c415465c3e1b1e485b Commit]'''&lt;br /&gt;
&lt;br /&gt;
To address the issue of the `list` method being overly long and sparsely commented, we added clear, descriptive comments to improve readability and understanding. Additionally, we split the method into smaller, focused helper methods, moving code to more appropriate locations. This restructuring made the `list` method more concise, easier to maintain, and enhanced its overall clarity.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
   def list&lt;br /&gt;
    #fetch the participant and related assignment&lt;br /&gt;
    @participant = AssignmentParticipant.find(params[:id].to_i)&lt;br /&gt;
    assignment_details = fetch_assignment_details(@participant)&lt;br /&gt;
    @assignment = assignment_details[:assignment]&lt;br /&gt;
&lt;br /&gt;
    #retrieve slot information&lt;br /&gt;
    @slots_filled = assignment_details[:slots_filled]&lt;br /&gt;
    @slots_waitlisted = assignment_details[:slots_waitlisted]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    @show_actions = true&lt;br /&gt;
    @priority = 0&lt;br /&gt;
    @sign_up_topics = assignment_details[:sign_up_topics]&lt;br /&gt;
    @max_team_size = assignment_details[:max_team_size]&lt;br /&gt;
    team_id = @participant.team.try(:id)&lt;br /&gt;
    @use_bookmark = assignment_details[:use_bookmark]&lt;br /&gt;
&lt;br /&gt;
    #If the assignment is intelligent, get topics based on biding&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;
      #Collect all sign up topics based on bids&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;
      #Filter and update signup topic list&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;
&lt;br /&gt;
    #Calculating the size of sign up topic list&lt;br /&gt;
    @num_of_topics = @sign_up_topics.size&lt;br /&gt;
&lt;br /&gt;
    #Storing deadline information&lt;br /&gt;
    deadlines = fetch_deadlines(@assignment)&lt;br /&gt;
    @signup_topic_deadline = deadlines[:signup_topic_deadline]&lt;br /&gt;
    @drop_topic_deadline = deadlines[:drop_topic_deadline]&lt;br /&gt;
&lt;br /&gt;
    @student_bids = team_id.nil? ? [] : Bid.where(team_id: team_id)&lt;br /&gt;
&lt;br /&gt;
    #Handle topic sign up restrictions based on dealines&lt;br /&gt;
    @show_actions = false if set_action_display_status(@assignment)&lt;br /&gt;
&lt;br /&gt;
    @selected_topics = user_sign_up_status(@assignment, session[:user].id)&lt;br /&gt;
    &lt;br /&gt;
    render('sign_up_sheet/intelligent_topic_selection') &amp;amp;&amp;amp; return if @assignment.is_intelligent&lt;br /&gt;
    &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Added Helper Methods'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
def fetch_assignment_details(participant)&lt;br /&gt;
    @assignment = participant.assignment&lt;br /&gt;
&lt;br /&gt;
      assignment: @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;
      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;
      use_bookmark: @assignment.use_bookmark&lt;br /&gt;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def fetch_deadlines(assignment)&lt;br /&gt;
    {&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;
    }&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_action_display_status(assignment)&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;
    signup_deadline = assignment.due_dates.find_by(deadline_type_id: 1)&lt;br /&gt;
    return true if signup_deadline.nil?&lt;br /&gt;
    !assignment.staggered_deadline? &amp;amp;&amp;amp; (signup_deadline.due_at &amp;lt; Time.now)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def user_sign_up_status(assignment, user_id)&lt;br /&gt;
    users_team = Team.find_team_users(assignment.id, user_id)&lt;br /&gt;
    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;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157359</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157359"/>
		<updated>2024-10-29T02:16:40Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality. We also simplified the if else ladder in the signup_as_instructor_action method by adding some early returns, eliminating nested logic and simplifying the method flow.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/DarthAsh/expertiza/commit/fadabe082255255f8177fe9744107be55413a15d Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157358</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157358"/>
		<updated>2024-10-29T02:15:17Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Design Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions.&lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality. We also simplified the if else ladder in the signup_as_instructor_action method by adding some early returns, eliminating nested logic and simplifying the method flow.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/Harshil47/expertiza/commit/7728e5d0ad85a6f9d4c7ca8cb933deb9e4fc9016 Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157357</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157357"/>
		<updated>2024-10-29T02:08:35Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions. By doing so, we minimized repetition, improved readability, and ensured consistency across the codebase.We can reuse the log_message() created in part 3 to write application logs. &lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality. We also simplified the if else ladder in the signup_as_instructor_action method by adding some early returns, eliminating nested logic and simplifying the method flow.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/Harshil47/expertiza/commit/7728e5d0ad85a6f9d4c7ca8cb933deb9e4fc9016 Commit]'''&lt;br /&gt;
We have introduced three private methods to implement common functionality between the methods delete_signup and delete_signup_as_instructor.&lt;br /&gt;
These methods support delete_signup and delete_signup_as_instructor.&lt;br /&gt;
    *fetch_participant_and_assignment: to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
    *fetch_participant_by_team_and_assignment: to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
    *can_drop_topic?: to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup&lt;br /&gt;
&lt;br /&gt;
    participant, assignment, drop_topic_deadline = fetch_participant_and_assignment(params[:id])&lt;br /&gt;
    submission_error = 'You have already submitted your work, so you are not allowed to drop your topic.'&lt;br /&gt;
    deadline_error = 'You cannot drop your topic after the drop topic deadline!'&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      users_team = Team.find_team_users(assignment.id, session[:user].id)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], users_team[0].t_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;
&lt;br /&gt;
    redirect_to action: 'list', id: params[:id]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  def delete_signup_as_instructor&lt;br /&gt;
&lt;br /&gt;
    team = Team.find(params[:id])&lt;br /&gt;
    assignment, participant, drop_topic_deadline = fetch_participant_by_team_and_assignment(team)&lt;br /&gt;
    submission_error = 'The student has already submitted their work, so you are not allowed to remove them.'&lt;br /&gt;
    deadline_error = 'You cannot drop a student after the drop topic deadline!'&lt;br /&gt;
&lt;br /&gt;
    if can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
      delete_signup_for_topic(params[:topic_id], team.id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic!'&lt;br /&gt;
      ExpertizaLogger.info 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;
&lt;br /&gt;
    redirect_to controller: 'assignments', action: 'edit', id: assignment.id&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  private&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch participant, assignment, and drop topic deadline&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_and_assignment(participant_id)&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;
    [participant, assignment, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to fetch assignment, participant, and drop topic deadline by team&lt;br /&gt;
&lt;br /&gt;
  def fetch_participant_by_team_and_assignment(team)&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;
    [assignment, participant, drop_topic_deadline]&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  # Method to check if the topic can be dropped based on submission and deadline&lt;br /&gt;
&lt;br /&gt;
  def can_drop_topic?(participant, drop_topic_deadline, submission_error, deadline_error)&lt;br /&gt;
    if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
      flash[:error] = submission_error&lt;br /&gt;
      ExpertizaLogger.error LoggerMessage.new(controller_name, session[:user].id, 'Dropping topic for already submitted work: ' + params[:topic_id].to_s)&lt;br /&gt;
      false&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] = deadline_error&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;
      false&lt;br /&gt;
    else&lt;br /&gt;
      true&lt;br /&gt;
   end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157352</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157352"/>
		<updated>2024-10-29T01:47:50Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Solutions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions. By doing so, we minimized repetition, improved readability, and ensured consistency across the codebase.We can reuse the log_message() created in part 3 to write application logs. &lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality. We also simplified the if else ladder in the signup_as_instructor_action method by adding some early returns, eliminating nested logic and simplifying the method flow.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
&lt;br /&gt;
* '''Refactored signup_as_instructor_action method for if else ladder simplification [https://github.com/DarthAsh/expertiza/commit/2d970f96b5bc7c29ce146eb0917e091614e58993 Commit]'''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: Now, whenever a condition fails, it immediately returns and stops further execution. There are no nested if-else blocks anymore, making the logic flow cleaner. The code processes each validation step independently, returning early for error cases. Only if all validations pass does it proceed to signing up the student.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/Harshil47/expertiza/commit/7728e5d0ad85a6f9d4c7ca8cb933deb9e4fc9016 Commit]'''&lt;br /&gt;
By centralizing the shared functionality, delete_signup_common, a new method, lessens redundancy and enhances maintainability. A single function can handle both scenarios thanks to the refactored code, which uses the who_user parameter to identify the type of user doing the delete operation.&lt;br /&gt;
&lt;br /&gt;
The error handling logic has been enhanced to provide more descriptive error messages and to log errors appropriately using the ExpertizaLogger.&lt;br /&gt;
Logging has been improved to include more detailed information about the errors and actions being performed.&lt;br /&gt;
Comments have been added to describe each section of the code and explain the purpose of the methods and conditional blocks.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup_common(who_user, participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  # This method centralizes the shared functionality, reducing redundancy and improving maintainability&lt;br /&gt;
  #this function is used to delete a previous signup&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    # Handle case where participant has already submitted work&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;
    # Handle case where drop topic deadline has passed&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;
    # No errors, proceed with dropping topic&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic.'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + topic_id.to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, 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: ' + topic_id.to_s)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157346</id>
		<title>CSC/ECE 517 Fall 2024 - E2455. 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_2024_-_E2455._Refactor_sign_up_sheet_controller.rb&amp;diff=157346"/>
		<updated>2024-10-29T01:23:41Z</updated>

		<summary type="html">&lt;p&gt;Aasatput: /* Design Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the information regarding the changes made for the E2409 OSS assignment for Spring 2024, 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 comprises all functions related to the management of the signup sheet for an assignment.&lt;br /&gt;
&lt;br /&gt;
*Instructors can add and remove topics from assignments, as well as alter their attributes.&lt;br /&gt;
*Allows an instructor to assign and remove students to subjects. &lt;br /&gt;
*Allows a student to view a list of available subjects on which they can bid for an OSS assignment. &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 [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 do not make sense.&lt;br /&gt;
*Signup_as_instructor_action has an 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;
== Design Plan ==&lt;br /&gt;
=== Proposed Changes ===&lt;br /&gt;
*Update the list method. The list method is too big and can be splitted to make use of helper functions. The if and unless checks can be handled by separate functions to reduce the cognitive complexity of it.&lt;br /&gt;
*Reduce the if-else ladder in delete_signup_common to improve the readability of the code and solve the SRP issue pointed out in Program 3 review. Reuse the log_message() function created in part-3 to log application messages and enure DRY principle is followed&lt;br /&gt;
*Rename methods and variables - delete_signup(delete_signup_as_student), load_add_signup_topics(function does not add anything as such hence shall be renamed)&lt;br /&gt;
*Reduce the if-else ladder in switch_original_topic_to_approved_suggested_topic method into separate functions to improve readability, testability and understandability of the code.&lt;br /&gt;
*Implement Builder method for SignUpTopic and TopicDueDate objects to reduce multiple assignment operations &lt;br /&gt;
*Fix code climate issues&lt;br /&gt;
*Update test specs to ensure the test build passes.&lt;br /&gt;
&lt;br /&gt;
=== Design Objectives ===&lt;br /&gt;
In refactoring the sign_up_sheet_controller.rb, we focused on improving the overall design of the codebase by adhering to several fundamental design principles.&lt;br /&gt;
*'''Single Responsibility Principle (SRP):'''&lt;br /&gt;
&lt;br /&gt;
Responsibility for Object creation for SignUpTopic and TopicDueDate can be delegated to Builder class. We will be addressing the issue of the delete_signup_common method not adhering to SRP. In order to solve the issue we will be creating a class DeleteSignupAction which will have methods like raise_flash_if_work_submitted, raise_flash_if_deadline_passed and raise_flash_after_topic_dropped. We will have two classes InstructorDeleteSignUpAction and ParticipantDeleteSignupAction extending the above class having respective flash generation code.&lt;br /&gt;
*'''Don't Repeat Yourself (DRY):'''&lt;br /&gt;
&lt;br /&gt;
Throughout the refactor, we emphasized reducing redundancy and promoting code reuse. For instance, in the delete_signup_as_instructor and delete_signup methods, we reduced the function length and complexity by extracting common functionality into helper functions. By doing so, we minimized repetition, improved readability, and ensured consistency across the codebase.We can reuse the log_message() created in part 3 to write application logs. &lt;br /&gt;
&lt;br /&gt;
*'''Readability and Maintainability:'''&lt;br /&gt;
&lt;br /&gt;
We prioritized enhancing the readability and maintainability of the codebase by introducing meaningful variable names, refactoring conditional blocks, and adding descriptive comments. Clear and descriptive variable names such as assignment_id and topic_id were used to improve code readability and understanding. Additionally, detailed comments were added to describe each section of the code and explain the purpose of methods and conditional blocks, making it easier for developers to understand the logic and functionality. We also simplified the if else ladder in the signup_as_instructor_action method by adding some early returns, eliminating nested logic and simplifying the method flow.&lt;br /&gt;
&lt;br /&gt;
=== Plan of Work ===&lt;br /&gt;
Based on the feedback given in the OSS project we will change some method names, such as 'delete_signup_common' renamed for better clarity , adding comments for longer methods to explain the flow of method. Additionally add the test cases to the existing framework to accommodate the changes made.&lt;br /&gt;
&lt;br /&gt;
==Solutions==&lt;br /&gt;
*'''The previous version of the project fixed the naming discrepancy issue. We have validated it and found no other changes.'''&lt;br /&gt;
&lt;br /&gt;
* '''signup_as_instructor and signup_as_instructor_action methods functionalities breakdown '''&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor: This function appears to be an empty function that doesn't perform any action. It is not called anywhere in the provided code. Hence, it seems unnecessary and can be removed.&lt;br /&gt;
&lt;br /&gt;
signup_as_instructor_action: This function is used to process the instructor's request to sign up a student for a particular topic for an assignment. It handles the form submission and performs the necessary actions based on the submitted data.&lt;br /&gt;
&lt;br /&gt;
* '''Refactored delete_signup and delete_signup_as_instructor [https://github.com/Harshil47/expertiza/commit/7728e5d0ad85a6f9d4c7ca8cb933deb9e4fc9016 Commit]'''&lt;br /&gt;
By centralizing the shared functionality, delete_signup_common, a new method, lessens redundancy and enhances maintainability. A single function can handle both scenarios thanks to the refactored code, which uses the who_user parameter to identify the type of user doing the delete operation.&lt;br /&gt;
&lt;br /&gt;
The error handling logic has been enhanced to provide more descriptive error messages and to log errors appropriately using the ExpertizaLogger.&lt;br /&gt;
Logging has been improved to include more detailed information about the errors and actions being performed.&lt;br /&gt;
Comments have been added to describe each section of the code and explain the purpose of the methods and conditional blocks.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  def delete_signup_common(who_user, participant, assignment, drop_topic_deadline, topic_id)&lt;br /&gt;
  # This method centralizes the shared functionality, reducing redundancy and improving maintainability&lt;br /&gt;
  #this function is used to delete a previous signup&lt;br /&gt;
  if !participant.team.submitted_files.empty? || !participant.team.hyperlinks.empty?&lt;br /&gt;
    # Handle case where participant has already submitted work&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;
    # Handle case where drop topic deadline has passed&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;
    # No errors, proceed with dropping topic&lt;br /&gt;
    if who_user == &amp;quot;instructor&amp;quot;&lt;br /&gt;
      delete_signup_for_topic(assignment.id, topic_id, participant.user_id)&lt;br /&gt;
      flash[:success] = 'You have successfully dropped the student from the topic.'&lt;br /&gt;
      ExpertizaLogger.info LoggerMessage.new(controller_name, session[:user].id, 'Student has been dropped from the topic: ' + topic_id.to_s)&lt;br /&gt;
    else&lt;br /&gt;
      delete_signup_for_topic(assignment.id, 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: ' + topic_id.to_s)&lt;br /&gt;
    end&lt;br /&gt;
   end&lt;br /&gt;
  end&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;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Refactoring the Update method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&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.&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], topic_name: params[:topic][:topic_name], micropayment: params[:topic][:micropayment], description: params[:topic][:description],link:params[:topic][:link] )&lt;br /&gt;
      flash[:success] = 'The topic has been successfully updated.'&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;
*'''Refactoring the signup_as_instructor_action method [https://github.com/Harshil47/expertiza/commit/eb1e4417552f1067f4085ff5920addfaaaab5494 Commit]'''&lt;br /&gt;
&lt;br /&gt;
The refactored version is more concise and readable. We have reduced the function length which was raised in the Code Climate issue. Also added multiple helper function to reduce the if-else ladder complexity. We added a new user_registered_for_assignment, process_signup_as_instructor_request helper functions as well as log_message function to make sure DRY principle is followed while logging messages. 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'''&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;
      assignment_id = params[:assignment_id]&lt;br /&gt;
      topic_id = params[:topic_id]    &lt;br /&gt;
      if user_registered_for_assignment?(user, assignment_id)&lt;br /&gt;
        process_signup_as_instructor_request(assignment_id,user,topic_id)&lt;br /&gt;
      else&lt;br /&gt;
        log_message(&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;
  def user_registered_for_assignment?(user, assignment_id) # to check if user has registered for the assignment or not.&lt;br /&gt;
    if AssignmentParticipant.exists?(user_id: user.id, parent_id: assignment_id)&lt;br /&gt;
      true&lt;br /&gt;
    else&lt;br /&gt;
      flash[:error] = 'The student is not registered for the assignment!'&lt;br /&gt;
      false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def log_message(message) # function to log the message&lt;br /&gt;
    ExpertizaLogger.info LoggerMessage.new(controller_name, '', message)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def process_signup_as_instructor_request(assignment_id,user,topic_id) # function to add user for a given assignment and given topic&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;
      log_message(&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;
      log_message('Instructor is signing up a student who already has a topic')&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*'''Refactoring the save_topic_deadlines method Part-1 [https://github.com/Harshil47/expertiza/commit/877fe32a2dc0d0d742837ab59455a02b01c34b4d Commit]'''&lt;br /&gt;
As part 1 of refactoring save_topic_deadlines we will be reducing the number of lines of code for this function as it exceeds the limit which was raised in code climate. For this we gave create separate create and update methods of creating and saving TopicDueDate object. Additionally instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1] and instance_variable_get('@topic_' + deadline_type + '_due_date') were used multiple number of times. Hence by applying DRY principle we created variables for the same only one time and used the varaible at different locations of the method.&lt;br /&gt;
&lt;br /&gt;
'''After refactoring'''&lt;br /&gt;
def save_topic_deadlines&lt;br /&gt;
    assignment = Assignment.find(params[:assignment_id])&lt;br /&gt;
    @assignment_submission_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 1 }&lt;br /&gt;
    @assignment_review_due_dates = assignment.due_dates.select { |due_date| due_date.deadline_type_id == 2 }&lt;br /&gt;
    due_dates = params[:due_date]&lt;br /&gt;
    topics = SignUpTopic.where(assignment_id: params[:assignment_id])&lt;br /&gt;
    review_rounds = assignment.num_review_rounds&lt;br /&gt;
    topics.each_with_index do |topic, index|&lt;br /&gt;
      (1..review_rounds).each do |i|&lt;br /&gt;
        @topic_submission_due_date = due_dates[topics[index].id.to_s + '_submission_' + i.to_s + '_due_date']&lt;br /&gt;
        @topic_review_due_date = due_dates[topics[index].id.to_s + '_review_' + i.to_s + '_due_date']&lt;br /&gt;
        @assignment_submission_due_date = DateTime.parse(@assignment_submission_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        @assignment_review_due_date = DateTime.parse(@assignment_review_due_dates[i - 1].due_at.to_s).strftime('%Y-%m-%d %H:%M')&lt;br /&gt;
        %w[submission review].each do |deadline_type|&lt;br /&gt;
          deadline_type_id = DeadlineType.find_by_name(deadline_type).id&lt;br /&gt;
          next if instance_variable_get('@topic_' + deadline_type + '_due_date') == instance_variable_get('@assignment_' + deadline_type + '_due_date')&lt;br /&gt;
&lt;br /&gt;
          topic_due_date = begin&lt;br /&gt;
                             TopicDueDate.where(parent_id: topic.id, deadline_type_id: deadline_type_id, round: i).first&lt;br /&gt;
                           rescue StandardError&lt;br /&gt;
                             nil&lt;br /&gt;
                           end&lt;br /&gt;
          due_date_obj=instance_variable_get('@assignment_' + deadline_type + '_due_dates')[i - 1]  #applying DRY principle and removing multiple instance_variable_get calls&lt;br /&gt;
          due_at=instance_variable_get('@topic_' + deadline_type + '_due_date')                 &lt;br /&gt;
          if topic_due_date.nil? # create a new record&lt;br /&gt;
            create_topic_due_date(i,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
          else # update an existed record &lt;br /&gt;
            topic_due_date.update_attributes(due_at: due_at,submission_allowed_id: due_date_obj.submission_allowed_id,review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
            review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,quiz_allowed_id: due_date_obj.quiz_allowed_id,teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to_assignment_edit(params[:assignment_id])&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  def create_topic_due_date(index,topic,deadline_type_id,due_date_obj,due_at)&lt;br /&gt;
    TopicDueDate.create(&lt;br /&gt;
              due_at: due_at,&lt;br /&gt;
              deadline_type_id: deadline_type_id,&lt;br /&gt;
              parent_id: topic.id,&lt;br /&gt;
              submission_allowed_id: due_date_obj.submission_allowed_id,&lt;br /&gt;
              review_allowed_id: due_date_obj.review_allowed_id,&lt;br /&gt;
              review_of_review_allowed_id: due_date_obj.review_of_review_allowed_id,&lt;br /&gt;
              round: index,&lt;br /&gt;
              flag: due_date_obj.flag,&lt;br /&gt;
              threshold: due_date_obj.threshold,&lt;br /&gt;
              delayed_job_id: due_date_obj.delayed_job_id,&lt;br /&gt;
              deadline_name: due_date_obj.deadline_name,&lt;br /&gt;
              description_url: due_date_obj.description_url,&lt;br /&gt;
              quiz_allowed_id: due_date_obj.quiz_allowed_id,&lt;br /&gt;
              teammate_review_allowed_id: due_date_obj.teammate_review_allowed_id,&lt;br /&gt;
              type: 'TopicDueDate'&lt;br /&gt;
            )&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Test 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;
==Manual Testing==&lt;br /&gt;
Follow these instructions to manually test the below functionalities:&lt;br /&gt;
&lt;br /&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;
*'''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;
*'''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;
==Rspec==&lt;br /&gt;
The RSpec test cases for 'signup_sheet_controller.rb' are intended to fully examine the functionality of handling sign-up topics for assignments. These test cases cover a variety of scenarios, such as adding new topics, modifying topic properties, deleting topics, switching from original to suggested subjects, and more. They ensure that the controller correctly manages activities taken by students and teachers, including meeting deadlines and maintaining submission status. Furthermore, the test cases confirm that activities such as topic priority setting and topic deadline saving function properly.&lt;br /&gt;
&lt;br /&gt;
All of these tests are designed to ensure that the controller's actions respond effectively to user input and that the underlying logic, database interactions, and authorization checks work as expected. With these tests, developers can be certain that the 'SignUpSheetController' is functional and provides a solid basis for managing sign-up topics in an educational setting.&lt;br /&gt;
&lt;br /&gt;
[[File:Test_cases_2409.jpeg|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Modified Files==&lt;br /&gt;
* sign_up_sheet_controller.rb&lt;br /&gt;
* sign_up_sheet_helper.rb&lt;br /&gt;
* sign_up_sheet_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Relevant Links==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Harshil47/expertiza&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/expertiza/pull/2777&lt;br /&gt;
* '''Video Link:''' https://www.youtube.com/watch?v=v7D6gEbuq5g&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Mentor:&amp;lt;/b&amp;gt; Anvitha Reddy Gutha - agutha@ncsu.edu&lt;br /&gt;
* Mitul Patel - mpatel27@ncsu.edu&lt;br /&gt;
* Harshil Sanghavi - hsangha@ncsu.edu&lt;br /&gt;
* Sagar Dama - sudama2@ncsu.edu&lt;/div&gt;</summary>
		<author><name>Aasatput</name></author>
	</entry>
</feed>