CSC/ECE 517 Spring 2022 - E2240. Re-write waitlist functionality: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(42 intermediate revisions by 3 users not shown)
Line 1: Line 1:


== Problem Statement==
== Problem Statement==
Waitlist feature is utilized during subject assignment in an assignment. For example, during the topic allocation of the Final Project (and design doc), each team had the opportunity to sign up for a topic in which they were interested or to add to a waitlist of a topic in which they were not interested. When a team is added to the queue, many circumstances emerge. The waitlist feature currently does not adhere to the open-closed design paradigm. As a result, our task in this project is to resolve these issues by rewriting the waitlist functionality.
Whenever a team requests for a topic, there are two things that can happen.  
Whenever a team requests for a topic, there are two things that can happen.  


Line 7: Line 10:
* '''The topic is unavailable''': In this case, the team is waitlisted for the topic. When any other team drops this topic, a waitlisted team will be assigned for this topic.  
* '''The topic is unavailable''': In this case, the team is waitlisted for the topic. When any other team drops this topic, a waitlisted team will be assigned for this topic.  


Our task is to simplify the way we are handling the second case. For each topic, we will have to have a waitlist object associated with it. If a team has requested for a topic that is not available, the team would just be queued on to the waitlist for this topic. In the waitlist object, we will have to maintain the team_id and the topic id for which this team will be waitlisted. In the current implementation, the waitlisting functionality is scattered across multiple files. All this has to be consolidated and placed in fewer number of places ( model file and helper class ).
We simplified the way we are handling the second case. For each topic, we have a waitlist object associated with it. If a team has requested for a topic that is not available, the team is queued on to the waitlist for this topic. In the waitlist table, we maintain the team id and the topic id for which this team is waitlisted. In the previous implementation, the waitlisting functionality is scattered across multiple files. All this is consolidated and placed in one model file ( waitlists.rb )
=== Issues with previous functionality ===
The previous implementation had multiple models and controllers ( sign_up_topic.rb, waitlist.rb, invitation.rb, lottery_controller.rb, suggestion_controller.rb and signed_up_team.rb etc ) perform actions that indirectly affect the waitlist ( adding or removing teams from waitlist ). As a result, modifying the waitlist is being performed by multiple models and controllers. So, there is a lot of redundancy associated with basic waitlist operations in multiple files.


=== Issues with existing functionality ===
== Solution ==
The current implementation has multiple models and controllers ( sign_up_topic.rb, waitlist.rb, invitation.rb, lottery_controller.rb, suggestion_controller.rb and signed_up_team.rb etc ) perform actions that indirectly affect the waitlist ( adding or removing teams from waitlist ). As a result, modifying the waitlist is being performed by multiple models and controllers. So, there is a lot of redundancy associated with basic waitlist operations in multiple files.


=== Overview of Major Changes ===
To simplify waitlist functionality, to reduce code redundancy and to fix the Single-responsibility principle that is being violated, we have rewritten the methods in multiple controllers and model files that manipulate waitlists of a topic. All these classes now just invoke methods of waitlist_teams.rb. The following files contains the waitlist functionality which we have modified to refer to the new model file.
To simplify waitlist functionality and to reduce code redundancy, we will be moving all the functions present in multiple controllers and model files that manipulate waitlists to waitlist.rb. All these classes will now just invoke methods of waitlist.rb. The list of files and methods which will be modified are


1) signed_up_team.rb
1) ''signed_up_team.rb''


2) waitlist.rb
2) ''waitlist.rb''


3) sign_up_sheet_controller.rb
3) ''sign_up_sheet_controller.rb''


4) sign_up_sheet.rb
4) ''sign_up_sheet.rb''


5) sign_up_topic.rb
5) ''sign_up_topic.rb''


6) suggestion_controller.rb
6) ''suggestion_controller.rb''


7) invitation.rb
7) ''invitation.rb''


== Proposed design and Plan of action ==
== Design ==


=== General Design Goals ===
=== Achieved Design Goals ===
Since our goal is to fix existing functionalities we will not be updating the existing design patterns being employed in the code. Yet, we would like to discuss what makes these refactoring important. Refactoring is a systematic process of improving code without creating new functionality. Thus, a key to the success of our project is ensuring everything that was working before our changes work even after our changes have been added. To ensure this, we will continue to test the system after each issue has been fixed. This will allow us to ensure two things:
Since our goal is to fix existing functionalities we did not update the existing design patterns being employed in the code. Yet, we would like to discuss what makes these refactoring important. Refactoring is a systematic process of improving code without creating new functionality. Thus, a key to the success of our project is ensuring everything that was working before our changes work even after our changes have been added. <br> We have eliminated the waitlist.rb file and moved all the references to this class to the new waitlist_teams.rb model file. We tested the existing features and ensured that we are not breaking what was working before we deployed our fix.
We can say that we achieved our goal of making experiza system more reliable and have code that is consistent with the standards of object-oriented design.


* We are only changing what we set out to change when fixing a particular issue.
=== UML Diagram ===
* We are not breaking what was working before we deployed our fix.
 
We believe at the end our changes will increase the quality of Expertiza and improve the experience for users an developers alike.


=== UML Diagram ===
In this Unified Modeling Language (UML), we summarize the details of the system's users and their interactions with the system. <br>
We have two users to the system '''Student''' and '''Instructor'''. The interactions these users have with the system are stated below.


In this Unified Modeling Language (UML), we summarize the details of the system's users such as instructors and students and their interactions with the system. <br>


'''Student Interactions''' <br>
'''Student Interactions''' <br>
Line 59: Line 60:
=== Class Diagram ===
=== Class Diagram ===


Tables associated with '''waitlist_teams''' table:<br>
Tables associated with '''waitlist_teams''' table are<br>
1. teams<br>
1. teams<br>
2. signed_up_teams<br>
2. signed_up_teams<br>
Line 65: Line 66:
waitlist_teams table is referred by the signed_up_teams and teams table as Foreign Key Relationship.
waitlist_teams table is referred by the signed_up_teams and teams table as Foreign Key Relationship.


'''team_id''' : foreign key in waitlists_team table referenced by teams table <br>
'''team_id''' : foreign key in waitlists_team table which is a reference to the teams table <br>
'''topic_id''' : foreign key in waitlists_team table reference by signed_up_teams table <br>
'''topic_id''' : foreign key in waitlists_team table which is a reference to the signed_up_teams table <br>
<br>
These relationships along with the attributes of the classes are depicted in the class diagram below.
<br>
<br>
<br>
<br>
[[File:Waitlists_class_diagram.png|600px|]]


[[File:Waitlists_class_diagram.png|600px|]]
== Actions performed ==
 
Following are the sections of changes that we have done in this project : <br>
1. Updated the SIGNED_UP_TEAMS table. <br>
2. Refactored files that contains waitlist functionality <br>
3. Added new WAITLIST_TEAMS table using scaffold. <br>
4. Migrated the data to WAITLIST_TEAMS table from SIGNED_UP_TEAMS table. <br>
5. Added the business logic to ''waitlist_teams.rb'' file<br>


=== Changes to the signed_up_teams Table ===
=== 1.Changes done to the signed_up_teams Table ===
signed_up_teams table consists of a mapping of team_id, topic_id, is_waitlisted. This table was being used for multiple purposes, one to store the signed up teams and also the waitlisted teams for a topic.
signed_up_teams table consists of a mapping of team_id, topic_id, is_waitlisted. This table was being used for multiple purposes, one to store the signed up teams and also the waitlisted teams for a topic.
<br/>
<br/>
We plan on retiring/removing the waitlist flag from the signed_up_teams table and separating this functionality.  
We have eliminated the use of is_waitlisted column of this table. Instead, we have used a separate table <b>waitlist_teams</b> for waitlisting entries. With this, the signed_up_teams table consists of only signed up teams and waitlist_teams consists of only waitlisted up teams.
<br/>
<br/>
All existing references to the is_waitlisted flag will be rewritten to make use of the new table.
All existing references to the is_waitlisted flag has been rewritten to make use of the new table.
 


=== Files and methods to be refactored ===
=== 2. Files and methods refactored ===


#signed_up_team.rb
#signed_up_team.rb
##All references to is_waitlisted should be removed and waitlists must be determined by using the new waitlist_team table.
##All references to the is_waitlisted boolean flag are removed and waitlists are determined by using the new waitlist_team table.  
#waitlist.rb
#waitlist.rb
##This class must be scrapped away and we will use a separate helper class to add all the logic of waitlisting which will be called by other methods.  
##We have completely eliminated this class. We have used <b>WaitlistTeam</b> in place of this class and this contains all business logic for managing waitlisted teams for topics. <br> Refer to this [https://github.com/akhilkumarmengani/expertiza/pull/1/commits/f1520041e759518e87109be1fa6adf539d7deb0a commit] to view the changes.
#sign_up_sheet_controller.rb
#sign_up_sheet_controller.rb
##switch_original_topic_to_approved_suggested_topic
##set_values_for_new_topic
###Change usage of is_waitlisted attribute in the signed_up_teams table to use the new table
###Added code to get waitlisted entries from new table instead of having all the entries from signed_up_teams table. <br> Refer to this [https://github.com/akhilkumarmengani/expertiza/pull/15/commits/44a0f06761dfc681d6ed8e6d9ecd3017a816848d commit] to view the changes.
###Add additional checks and transactions to make sure perform operations in an atomic way in case of failures.
#sign_up_sheet.rb
#sign_up_sheet.rb
##cancel_all_wailists (typo in code) - This method currently does 2 things, it cancels waitlist and also updates the signed_up_team topic which needs to be split
##cancel_all_wailists
###This method previously has done 2 things, it cancelled waitlist and also updated the signed_up_team topic which needs to be split to comply with single responsibility principle. We ensured that is happening in the current implementation. <br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-f7b8fbeb82e3d7d5481ba3ed065d55838a21a82ebd055ac076ea36f222f88556 commit] to view the changes.
##create_SignUpTeam
##create_SignUpTeam
###It checks if topic has slots if yes it adds to signed up team, else creates a signup as waitlist
### This method in the previous implementation checked if topic has slots. If yes, it added to signed up team, else created a signup as waitlist. <br> We modified this in order to use the new table and call the functions of waitlist_teams.rb to perform actions on waitlists. <br> Refer to this [https://github.com/akhilkumarmengani/expertiza/pull/12/commits/7194a53ec01e78ea0d95920624436da6fe9933e2 commit] to view the changes.
###This method should use the new table and call the helper functions of waitlist to perform actions on waitlists
#sign_up_topic.rb
#sign_up_topic.rb
##users_on_waiting_list - Move method to fetch all users on waitlist for a topic to waitlist_teams method.
##users_on_waiting_list - Moved this method to fetch all users on waitlist for a topic to waitlist_teams model file.
##assign_to_first_waiting_team - The same functionality is being called in multiple places, it should be made DRY and moved to the waitlist_teams model
##assign_to_first_waiting_team - The same functionality is being called in multiple places. This is modified to comply with DRY and is moved to the waitlist_teams model
##reassign_topic - Use methods that perform actions on waitlist that should be moved to waitlist_helper, also use transactions to make it atomic.
##reassign_topic - Modified this method to use waitlist_teams.rb model file for actions on waitlisted teams.
##update_waitlisted_users - Move method to waitlist_teams model and use the new table
##update_waitlisted_users - Moved this method to waitlist_teams model file.
##find_slots_waitlisted - Move method to waitlist_teams model
##find_slots_waitlisted - Moved this method to waitlist_teams model file.
##find_waitlisted_topics - Move method to waitlist_teams model
##find_waitlisted_topics - Moved this method to waitlist_teams model file. <br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-e0df714a791bc6d36e6b27b82af71be36e8eac2cd21af5ea28a8bc5303953f5b diff] to view the changes.
#suggestion_controller.rb
#suggestion_controller.rb
##notification
##notification - Clean waitlist functionality is moved to a method in waitlist_teams model. team id is passed as a parameter to delete the waitlist for that team. <br> Refer to this [https://github.com/akhilkumarmengani/expertiza/pull/14/files PR] to view the changes.
##Clean waitlist functionality should be moved to a method in waitlist_teams model. team id should be passed as a parameter to delete the waitlist for that team.
#invitation.rb
#invitation.rb
##remove_waitlists_for_team
##remove_waitlists_for_team - Removed this method as we dont need it in this file. <br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-c899291de1875b0c2483c0f132ed4503e6c33be63148d6e5d1f4235bfeb1c331 diff] to view the changes.
###Removing from waitlist and adding to team to sign up should be as a single transaction
###There should be additional checks to make sure that there is enough space left before adding team to signed_up_sheet
###All functionality should be moved to waitlist_helper and implemented in a robust and dry manner


===Adding new waitlist_teams Table ===
===3. Added new waitlist_teams Table ===
We plan to add a new table ''waitlist_teams''
We added a new table ''waitlist_teams''
<br/>
<br/>
The attributes for the table are team_id(refers to the ''teams'' table), topic_id (refers to the ''sign_up_topics'' table)
The attributes for the table are team_id(refers to the ''teams'' table), topic_id (refers to the ''sign_up_topics'' table)
Line 118: Line 123:
This table only stores the waitlisted teams for each topic.
This table only stores the waitlisted teams for each topic.
<br/>
<br/>
The default timestamp in the table will be used to check the first team waitlisted instead of using queues to implement the functionality.
The default timestamp in the table is used to check the first team waitlisted instead of using queues to implement the functionality.
<br/>
<br/>
Having separated tables for signups and waitlists will help in managing entries and enforcing constraints and make it easier to implement and extend functionality if required.
Having separated tables for signups and waitlists helps us in managing entries and enforcing constraints and makes it easier to implement and extend functionality if required.
<br/><br/>
<br/><br/>
The waitlist_helper class will perform the following operations  
The waitlist_teams.rb model class performs the following operations  
#Delete all waitlists for team
#Delete all waitlists for team
#Purge all waitlists for topic  
#Purge all waitlists for topic  
Line 132: Line 137:
#Check waitlist empty for topic
#Check waitlist empty for topic
#Check if team has any waitlists  
#Check if team has any waitlists  
#Get the number of waitlisted teams for all topics in an assignment
#Get the number of waitlisted teams for all topics in an assignment.<br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-0b3fc155270b76c5cdbf311acb356fbcd90873d2704bf87c44ee1d5ce111b9ca file] to view the waitlist_teams model.


===Migrating existing waitlists to use new table===
=== 4. Migrated existing waitlists to use new table===
Since the signed_up_teams table will no longer be used to store the waitlists we will move all the entries for waitlisted teams to the new table so that all the existing waitlists don't get affected.
Since the signed_up_teams table will no longer be used to store the waitlists, we moved all the entries for waitlisted teams to the new table so that all the existing waitlists don't get affected.
<br/>  
<br/>  
We plan on writing a migration script to move the waitlists from signed_up_teams table to waitlist_teams table.
We have written a migration script to move the waitlists from signed_up_teams table to waitlist_teams table.
<br/>
<br/>
This will ensure minimal regression breakages and retain existing functionalities.
This ensures minimal regression breakages and that all existing functionalities are retained. <br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-327e3874b03ef13dc2d75451388a63d2d28dd775df41e2d48389eb701667f5cb file] to view the migration script.
=== Specific Tasks Completed ===
''will be added for the final submission''


== Implementation ==
== Implementation ==
''will be added for the final submission''
'''1. Waitlist Teams Table, Validations and Model file:''' <br>
https://github.com/akhilkumarmengani/expertiza/pull/1/files (Adding waitlist_teams table) <br>
https://github.com/akhilkumarmengani/expertiza/pull/2/files (Migration script changes to add unique constraint on waitlist_teams table and remove id column) <br>
https://github.com/akhilkumarmengani/expertiza/pull/4/files (Schema changes) <br>
https://github.com/akhilkumarmengani/expertiza/pull/3/files (Validations)<br>
<br>
'''2. Migration Scripts''' <br>
https://github.com/akhilkumarmengani/expertiza/pull/10/files (Migrate existing data in signed_up_teams to waitlist_teams) <br>
<br>
'''3. Business Logic Changes''' <br>
Adding new methods for add, delete, signup of waitlist teams in WaitlistTeam.rb.<br>
Changes to existing method calls in model files<br>
<br>
https://github.com/akhilkumarmengani/expertiza/pull/5/files (WaitlistTeam model methods like CRUD etc) <br>
https://github.com/akhilkumarmengani/expertiza/pull/11/files (Methods to handle deletion cases) <br>
https://github.com/akhilkumarmengani/expertiza/pull/12 (Check if team is waitlisted before a topic signup) <br>
https://github.com/akhilkumarmengani/expertiza/pull/13 (Release waitlist and signup when a user joins another team and there are no other users in the old team) <br>
https://github.com/akhilkumarmengani/expertiza/pull/14/files (Synchronize waitlist features in other files) <br>
<br>
'''4. RSpec''' <br>
https://github.com/akhilkumarmengani/expertiza/pull/13 (RSpec changes to test model methods) <br>


== Testing ==
== Testing ==
=== Video Demonstration ===
=== Video Demonstration ===
''will be added for the final submission''
Please watch this [https://www.youtube.com/watch?v=L6NntAvnzUo Video Demonstration] where we explain the bugs we rectified in this project.
 
=== Testing Goals and Test Objects ===
=== Testing Goals and Test Objects ===


Line 166: Line 190:


=== RSpec Unit Tests ===
=== RSpec Unit Tests ===
'''''Test cases provided here, will add RSpec code blocks for the final submission'''''
*Student Waitlist
*Student Waitlist
**Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-0e90ff1a02697a3552966c713b541746d6b1226088147dcfe333f9605ebeb576 diff] to view the RSpec unit tests for waitlist_teams.rb model file. Few of them are
<pre>
Scenario: Getting enrolled in a topic
Given: Logged in as a Student
  When: The topic for an assignment has available slots
  And: Student tries to signup for a topic
  Then: The team that the student is a part of should be enrolled for the topic.
</pre>
<pre>
<pre>
Scenario: Getting added to the waitlist for a topic  
Scenario: Getting added to the waitlist for a topic  
Line 176: Line 207:
</pre>
</pre>
<pre>
<pre>
Scenario: Getting enrolled in a topic  
Scenario: Drop team from the waitlist for a topic
Given: Logged in as a Student
  When: The student is waitlisted for a topic
  And: Student drops from the waitlist of this topic
  Then: The team that the student is a part of should be dropped from the waitlist for the topic.
</pre>
<pre>
Scenario: Getting enrolled in a topic
  Given: Logged in as a Student
  Given: Logged in as a Student
   When: The topic for an assignment has available slots
   When: The enrolled team for a topic drops
  And: Student tries to signup for a topic
   Then: The team that was waitlisted earlier for the topics must be enrolled.
   Then: The team that the student is a part of should be enrolled for the topic.
</pre>
</pre>
<pre>
<pre>
Line 194: Line 231:
   Then: All the waitlisted teams for that particular topic must be dropped.
   Then: All the waitlisted teams for that particular topic must be dropped.
</pre>
</pre>
<pre>
 
Scenario: Getting enrolled in a topic
=== Regression Testing ===
Given: Logged in as a Student
In order to ensure complete coverage, testing of the changes done between the end of last semester and this project is done to ensure that old test cases still pass. <br> Refer to this [https://github.com/expertiza/expertiza/pull/2384/files#diff-41ff53070546cf68377a8592d16001af4558d9aa280bb65a21cf74cc2af33ceb PR] to view the changes to old test cases.
  When: The enrolled team for a topic drops
  Then: The team that was waitlisted earlier for the topics must be enrolled.
</pre>


=== Manual Testing ===
=== Manual Testing ===


Student sees the following page during the topic signup. <br>
'''Student's View'''
 
[[File:Student_waitlist_page.png|900px|]]
 
 
----
 
 
'''Instructor's View'''
 
[[File:Instructor_signup_page.png|900px|]]
 
 
----
'''Instructor's View With Waitlists'''
 
[[File:Waitlist.png|900px|]]
 
 
----
 


[[File:Student_waitlist_page.png|600px|]]


'''Test 1:''' <br>
'''Test 1:''' <br>
Line 212: Line 265:
'''Test 2:'''<br>
'''Test 2:'''<br>
Student should be able to drop the team from the waitlist by clicking on '''Delete''' icon (see the image above) if they are no longer interested in it.<br>
Student should be able to drop the team from the waitlist by clicking on '''Delete''' icon (see the image above) if they are no longer interested in it.<br>
Instructor sees the following page during the topic signup<br>
[[File:Instructor_signup_page.png|600px|]]


'''Test 3:'''<br>
'''Test 3:'''<br>
Line 223: Line 272:
Instructor should be able to delete a student to the topic by clicking on '''Delete''' (see the image above) icon. <br>
Instructor should be able to delete a student to the topic by clicking on '''Delete''' (see the image above) icon. <br>


=== Regression Testing ===
''' Test 5:''' <br>
''In order to ensure complete coverage, testing of the changes done between the end of last semester and this project will be done to ensure that ''
Instructor should be able to view all the students signup for a topic in the page displayed. <br>
''old test cases still pass.''
 
''' Test 6:''' <br>
Instructor should be able to view all the topics available
 
''' Test 7:''' <br>
Instructor should be able to view waitlisted and signed up teams for all the topics in the assignment


# Make sure all existing waitlist functionality still passes
''' Test 8:''' <br>
Instructor should be able to drop waitlisted team for a topics in the assignment.


== Conclusions and Future Work ==
== Conclusions and Future Work ==
=== Comprehensive Testing and Scope ===
'''Conclusion:''' <br>
* ''will be added for final submission''
Following is the summary of what we have done in this project so far:<br>
1. Adding new table waitlist_teams to store waitlist teams for a topic and migration script for transferring the waitlist data from signed_up_teams.<br>
2. Changed the existing functionality to store the new waitlists data in this new table<br>
3. Existing waitlist business logic implementation is not in waitlist model class so we created a new model file and rewritten the code for waitlist functionality.<br>
4. There are number of methods in other model classes which are referencing waitlist functionality. We have changed all those references to the new methods that we have implemented.<br>
<br>
'''Future Work:'''<br>
1. We created a new table that will store the team in waitlist for a topic. Earlier there was only table (signed_up_teams) to keep track of signed up teams and waitlist teams. This table has is_waitlist column to figure out if the entry is for a sign up or waitlist. With the Introduction of new table for waitlist_teams this column now seems unreasonable and it will not impact the functionality. Though we have script to migrate the existing waitlist data to new table, the column is_waitlist is not removed yet. Teams working on it further can work on it and remove all the references of is_waitlist column. <br>
2. Teams can work on writing more test cases for waitlist functionality because there are various flows in which this functionality is touched Examples: Accept Invitation, Leaving team etc.<br>


=== Conclusion ===
== Useful Links ==
''will be added for final submission''


== Useful Links ==
[https://github.com/expertiza/expertiza/pull/2384/view Pull request] <br/>
Pull request


Deployed application with changes
[https://go.ncsu.edu/fab_four_deployed_application Deployed application with changes] <br/>


Forked repository
[https://github.com/akhilkumarmengani/expertiza/view Forked repository] <br/>


== Contributors ==
== Contributors ==

Latest revision as of 15:04, 3 May 2022

Problem Statement

Waitlist feature is utilized during subject assignment in an assignment. For example, during the topic allocation of the Final Project (and design doc), each team had the opportunity to sign up for a topic in which they were interested or to add to a waitlist of a topic in which they were not interested. When a team is added to the queue, many circumstances emerge. The waitlist feature currently does not adhere to the open-closed design paradigm. As a result, our task in this project is to resolve these issues by rewriting the waitlist functionality.

Whenever a team requests for a topic, there are two things that can happen.

  • The topic is available: In this case, the team will be assigned this topic ( Assuming that there is no bidding for the assignment ). This is pretty straightforward.
  • The topic is unavailable: In this case, the team is waitlisted for the topic. When any other team drops this topic, a waitlisted team will be assigned for this topic.

We simplified the way we are handling the second case. For each topic, we have a waitlist object associated with it. If a team has requested for a topic that is not available, the team is queued on to the waitlist for this topic. In the waitlist table, we maintain the team id and the topic id for which this team is waitlisted. In the previous implementation, the waitlisting functionality is scattered across multiple files. All this is consolidated and placed in one model file ( waitlists.rb )

Issues with previous functionality

The previous implementation had multiple models and controllers ( sign_up_topic.rb, waitlist.rb, invitation.rb, lottery_controller.rb, suggestion_controller.rb and signed_up_team.rb etc ) perform actions that indirectly affect the waitlist ( adding or removing teams from waitlist ). As a result, modifying the waitlist is being performed by multiple models and controllers. So, there is a lot of redundancy associated with basic waitlist operations in multiple files.

Solution

To simplify waitlist functionality, to reduce code redundancy and to fix the Single-responsibility principle that is being violated, we have rewritten the methods in multiple controllers and model files that manipulate waitlists of a topic. All these classes now just invoke methods of waitlist_teams.rb. The following files contains the waitlist functionality which we have modified to refer to the new model file.

1) signed_up_team.rb

2) waitlist.rb

3) sign_up_sheet_controller.rb

4) sign_up_sheet.rb

5) sign_up_topic.rb

6) suggestion_controller.rb

7) invitation.rb

Design

Achieved Design Goals

Since our goal is to fix existing functionalities we did not update the existing design patterns being employed in the code. Yet, we would like to discuss what makes these refactoring important. Refactoring is a systematic process of improving code without creating new functionality. Thus, a key to the success of our project is ensuring everything that was working before our changes work even after our changes have been added.
We have eliminated the waitlist.rb file and moved all the references to this class to the new waitlist_teams.rb model file. We tested the existing features and ensured that we are not breaking what was working before we deployed our fix. We can say that we achieved our goal of making experiza system more reliable and have code that is consistent with the standards of object-oriented design.

UML Diagram

In this Unified Modeling Language (UML), we summarize the details of the system's users and their interactions with the system.
We have two users to the system Student and Instructor. The interactions these users have with the system are stated below.


Student Interactions
1. Student should be able to perform an action to add their own team to the waitlist.
2. Student should be able to drop their own team from the waitlist but not others team.

Instructor Interactions
1. Delete or purge on the waitlist items are those actions that have to be performed by the instructor/admin and student should not be given access to delete action.
2. Instructor should be able to add any team to the waitlist.
3. Instructor should be able to drop any team from the waitlist.
4. Instructor should be able to fetch the details of the teams in a waitlist for a particular topic.
5. Instructor should be able to fetch the details of the topics in which a team is waitlisted.


Class Diagram

Tables associated with waitlist_teams table are
1. teams
2. signed_up_teams

waitlist_teams table is referred by the signed_up_teams and teams table as Foreign Key Relationship.

team_id : foreign key in waitlists_team table which is a reference to the teams table
topic_id : foreign key in waitlists_team table which is a reference to the signed_up_teams table

These relationships along with the attributes of the classes are depicted in the class diagram below.

Actions performed

Following are the sections of changes that we have done in this project :
1. Updated the SIGNED_UP_TEAMS table.
2. Refactored files that contains waitlist functionality
3. Added new WAITLIST_TEAMS table using scaffold.
4. Migrated the data to WAITLIST_TEAMS table from SIGNED_UP_TEAMS table.
5. Added the business logic to waitlist_teams.rb file

1.Changes done to the signed_up_teams Table

signed_up_teams table consists of a mapping of team_id, topic_id, is_waitlisted. This table was being used for multiple purposes, one to store the signed up teams and also the waitlisted teams for a topic.
We have eliminated the use of is_waitlisted column of this table. Instead, we have used a separate table waitlist_teams for waitlisting entries. With this, the signed_up_teams table consists of only signed up teams and waitlist_teams consists of only waitlisted up teams.
All existing references to the is_waitlisted flag has been rewritten to make use of the new table.

2. Files and methods refactored

  1. signed_up_team.rb
    1. All references to the is_waitlisted boolean flag are removed and waitlists are determined by using the new waitlist_team table.
  2. waitlist.rb
    1. We have completely eliminated this class. We have used WaitlistTeam in place of this class and this contains all business logic for managing waitlisted teams for topics.
      Refer to this commit to view the changes.
  3. sign_up_sheet_controller.rb
    1. set_values_for_new_topic
      1. Added code to get waitlisted entries from new table instead of having all the entries from signed_up_teams table.
        Refer to this commit to view the changes.
  4. sign_up_sheet.rb
    1. cancel_all_wailists
      1. This method previously has done 2 things, it cancelled waitlist and also updated the signed_up_team topic which needs to be split to comply with single responsibility principle. We ensured that is happening in the current implementation.
        Refer to this commit to view the changes.
    2. create_SignUpTeam
      1. This method in the previous implementation checked if topic has slots. If yes, it added to signed up team, else created a signup as waitlist.
        We modified this in order to use the new table and call the functions of waitlist_teams.rb to perform actions on waitlists.
        Refer to this commit to view the changes.
  5. sign_up_topic.rb
    1. users_on_waiting_list - Moved this method to fetch all users on waitlist for a topic to waitlist_teams model file.
    2. assign_to_first_waiting_team - The same functionality is being called in multiple places. This is modified to comply with DRY and is moved to the waitlist_teams model
    3. reassign_topic - Modified this method to use waitlist_teams.rb model file for actions on waitlisted teams.
    4. update_waitlisted_users - Moved this method to waitlist_teams model file.
    5. find_slots_waitlisted - Moved this method to waitlist_teams model file.
    6. find_waitlisted_topics - Moved this method to waitlist_teams model file.
      Refer to this diff to view the changes.
  6. suggestion_controller.rb
    1. notification - Clean waitlist functionality is moved to a method in waitlist_teams model. team id is passed as a parameter to delete the waitlist for that team.
      Refer to this PR to view the changes.
  7. invitation.rb
    1. remove_waitlists_for_team - Removed this method as we dont need it in this file.
      Refer to this diff to view the changes.

3. Added new waitlist_teams Table

We added a new table waitlist_teams
The attributes for the table are team_id(refers to the teams table), topic_id (refers to the sign_up_topics table)
This table only stores the waitlisted teams for each topic.
The default timestamp in the table is used to check the first team waitlisted instead of using queues to implement the functionality.
Having separated tables for signups and waitlists helps us in managing entries and enforcing constraints and makes it easier to implement and extend functionality if required.

The waitlist_teams.rb model class performs the following operations

  1. Delete all waitlists for team
  2. Purge all waitlists for topic
  3. Add team to waitlist
  4. Delete specific team from waitlist
  5. Get all waitlisted topics for team
  6. Get all waitlisted teams for topic
  7. Get first team in waitlist for topic
  8. Check waitlist empty for topic
  9. Check if team has any waitlists
  10. Get the number of waitlisted teams for all topics in an assignment.
    Refer to this file to view the waitlist_teams model.

4. Migrated existing waitlists to use new table

Since the signed_up_teams table will no longer be used to store the waitlists, we moved all the entries for waitlisted teams to the new table so that all the existing waitlists don't get affected.
We have written a migration script to move the waitlists from signed_up_teams table to waitlist_teams table.
This ensures minimal regression breakages and that all existing functionalities are retained.
Refer to this file to view the migration script.

Implementation

1. Waitlist Teams Table, Validations and Model file:
https://github.com/akhilkumarmengani/expertiza/pull/1/files (Adding waitlist_teams table)
https://github.com/akhilkumarmengani/expertiza/pull/2/files (Migration script changes to add unique constraint on waitlist_teams table and remove id column)
https://github.com/akhilkumarmengani/expertiza/pull/4/files (Schema changes)
https://github.com/akhilkumarmengani/expertiza/pull/3/files (Validations)

2. Migration Scripts
https://github.com/akhilkumarmengani/expertiza/pull/10/files (Migrate existing data in signed_up_teams to waitlist_teams)

3. Business Logic Changes
Adding new methods for add, delete, signup of waitlist teams in WaitlistTeam.rb.
Changes to existing method calls in model files

https://github.com/akhilkumarmengani/expertiza/pull/5/files (WaitlistTeam model methods like CRUD etc)
https://github.com/akhilkumarmengani/expertiza/pull/11/files (Methods to handle deletion cases)
https://github.com/akhilkumarmengani/expertiza/pull/12 (Check if team is waitlisted before a topic signup)
https://github.com/akhilkumarmengani/expertiza/pull/13 (Release waitlist and signup when a user joins another team and there are no other users in the old team)
https://github.com/akhilkumarmengani/expertiza/pull/14/files (Synchronize waitlist features in other files)

4. RSpec
https://github.com/akhilkumarmengani/expertiza/pull/13 (RSpec changes to test model methods)

Testing

Video Demonstration

Please watch this Video Demonstration where we explain the bugs we rectified in this project.

Testing Goals and Test Objects

Drawing from the project objectives:

  1. Ways to get added to the waitlist for a topic
    1. Team requests a topic that has no slot available.
    2. When capacity/max choosers for a topic is increased
    3. When a student gets added to a team that already has a signed up topic
  2. Ways to get off a waitlist
    1. team gets the topic they are waiting for ( all other waitlists are dropped for the team)
    2. team drops off the waitlist
    3. instructor drops team from the waitlist
    4. a drop-topic deadline passes
    5. team is deleted
    6. student gets added to a new team, then the old team's waitlist should be dropped


RSpec Unit Tests

  • Student Waitlist
    • Refer to this diff to view the RSpec unit tests for waitlist_teams.rb model file. Few of them are
Scenario: Getting enrolled in a topic 
 Given: Logged in as a Student
  When: The topic for an assignment has available slots
   And: Student tries to signup for a topic
  Then: The team that the student is a part of should be enrolled for the topic.
Scenario: Getting added to the waitlist for a topic 
 Given: Logged in as a Student
  When: The topic for an assignment has no available slots
   And: Student tries to signup for a topic
  Then: The team that the student is a part of should be added to the waitlist for the topic.
Scenario: Drop team from the waitlist for a topic 
 Given: Logged in as a Student
  When: The student is waitlisted for a topic
   And: Student drops from the waitlist of this topic
  Then: The team that the student is a part of should be dropped from the waitlist for the topic.
Scenario: Getting enrolled in a topic
 Given: Logged in as a Student
  When: The enrolled team for a topic drops
  Then: The team that was waitlisted earlier for the topics must be enrolled.
Scenario: All waitlisted topics getting dropped
 Given: Logged in as a Student
  When: Student gets enrolled into a course for which he was waitlisted before.
  Then: The team that the student is a part of should be dropped from the remaining waitlisted topics.
Scenario: All waitlisted teams getting dropped
 Given: Logged in as a Student
  When: The deadline for a topic passes.
  Then: All the waitlisted teams for that particular topic must be dropped.

Regression Testing

In order to ensure complete coverage, testing of the changes done between the end of last semester and this project is done to ensure that old test cases still pass.
Refer to this PR to view the changes to old test cases.

Manual Testing

Student's View




Instructor's View



Instructor's View With Waitlists




Test 1:
Student should be able to add their team to the waitlist by clicking on Check icon (see the image above) if the team has not signed up in any topic.

Test 2:
Student should be able to drop the team from the waitlist by clicking on Delete icon (see the image above) if they are no longer interested in it.

Test 3:
Instructor should be able to add a student to the topic by clicking on Check (see the image above) icon.

Test 4:
Instructor should be able to delete a student to the topic by clicking on Delete (see the image above) icon.

Test 5:
Instructor should be able to view all the students signup for a topic in the page displayed.

Test 6:
Instructor should be able to view all the topics available

Test 7:
Instructor should be able to view waitlisted and signed up teams for all the topics in the assignment

Test 8:
Instructor should be able to drop waitlisted team for a topics in the assignment.

Conclusions and Future Work

Conclusion:
Following is the summary of what we have done in this project so far:
1. Adding new table waitlist_teams to store waitlist teams for a topic and migration script for transferring the waitlist data from signed_up_teams.
2. Changed the existing functionality to store the new waitlists data in this new table
3. Existing waitlist business logic implementation is not in waitlist model class so we created a new model file and rewritten the code for waitlist functionality.
4. There are number of methods in other model classes which are referencing waitlist functionality. We have changed all those references to the new methods that we have implemented.

Future Work:
1. We created a new table that will store the team in waitlist for a topic. Earlier there was only table (signed_up_teams) to keep track of signed up teams and waitlist teams. This table has is_waitlist column to figure out if the entry is for a sign up or waitlist. With the Introduction of new table for waitlist_teams this column now seems unreasonable and it will not impact the functionality. Though we have script to migrate the existing waitlist data to new table, the column is_waitlist is not removed yet. Teams working on it further can work on it and remove all the references of is_waitlist column.
2. Teams can work on writing more test cases for waitlist functionality because there are various flows in which this functionality is touched Examples: Accept Invitation, Leaving team etc.

Useful Links

Pull request

Deployed application with changes

Forked repository

Contributors

Students

  • Krishna Saurabh Vankadaru (kvankad)
  • Samson Reddy Mulkur (smulkur)
  • Akhil Kumar Mengani (amengan)
  • Sai Naga Vamshi Chidara (schidar)

Mentor

  • Naman Shrimali (nshrima)