CSC/ECE 517 Fall 2021 - E2163. Refactor waitlist functionality

From Expertiza_Wiki
Jump to navigation Jump to search

About Expertiza

The Expertiza platform employs a divide-and-conquer strategy for creating reusable learning objects via active-learning exercises built entirely on Ruby on Rails framework. Students get to choose from a list of tasks to complete either individually or in teams. It also allows the instructor to create a list of topics the students can sign up for. They then prepare their work and submit it to a peer-review mechanism. On submission, other students can assess their peers work and provide feedback. Expertiza encourages students to collaborate in order to improve the learning experiences from one another. It aids their learning by making them translate what is taught in the lectures and apply those concepts to a real-world issue.

Problem Statement

When a team requests a topic which is not available, the team is waitlisted for the topic, given that bidding is not in use for the assignment. When another team drops a topic, then a waitlisted team will be assigned the topic, if there are any teams waitlisted for it. Implement a waitlist object associated with each topic, and a team that requested it when it was not available would just be queued on the waitlist. The waitlist would just enqueue ordered pairs〈team_id, topic_id〉 Currently, the functionality relevant to waitlisting is scattered across the multiple files. These functions need to be consolidated and placed in a single class.

Control Flow

In the current implementation, multiple models and controllers perform actions that indirectly affect the teams in the waitlist and require to be added or removed from the waitlist. Due to this the same redundant operations of modifying the waitlist is being performed by multiple models and controllers. In order to improve the functionality all the redundant operations being performed on the waitlist need to be moved to the 'waitlist.rb' file and all the other controllers and models will be utilising these methods to manipulate the waitlists.

Planned implementation: The Context object in our case the waitlist object delegates an algorithm to different Strategy objects to execute waitlist functions as shown below. The Context calls algorithm() on a Strategy1 object, which performs the algorithm and returns the result to Context.

Existing Control Flow

Modified Control Flow

Solution Approach

Refactoring

Goal of the project is to simplify waitlist functionality by moving all the functions manipulating waitlists to waitlist.rb, along with a WaitingTeam class that would consist of a 〈team_id, topic_id〉pair to store information regarding teams on waitlist for a particular topic. Classes should just invoke methods of waitlist.rb for the following functionality:

  1. Add themselves to waitlists
  2. Add another team to a waitlist
  3. Take a team off a waitlist
  4. Purge all waitlists of a specific team
  5. Clear a specific waitlist of all waiting teams

Introduce a waitlist object associated with each topic so that any team that requested it when it was not available would just be queued on the waitlist. The waitlist would just enqueue ordered pairs〈team_id, topic_id〉

Design Pattern

As we are decoupling the functionality manipulating waitlists that is scattered across various files and putting it all under a single class the design pattern opted for is Strategy Design Pattern. It is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable. The plan is to isolate the code, internal data, and dependencies of various algorithms related to waitlist from the rest of the code. Various clients now get a simple class to execute the algorithms and switch them at runtime.

Tentative list of files to be modified

  1. sign_up_topic.rb
  2. invitation.rb
  3. waitlist.rb
  4. lottery_controller.rb
  5. suggestion_controller.rb
  6. signed_up_team.rb
  7. student_teams_controller.rb

UI Test Steps

  • Step 1: Signup as an instructor and click on Manage Assignments

  • Step 2: Create an assignment with the required configurations and click on create.

  • Step 3: Post assignment creation, go to manage assignments, and edit the newly created assignment

  • Step 4: Selected the 'has topics' options and create new topics for the students to sign up using the topics tab.

  • Step 5: Add participants to the assignment using the participant tab and then assign the participants to teams using the teams tab and save the changes.

  • Step 6: Impersonate one student that you had added to one team in the previous step.

  • Step 7: In the assignment tabs, choose the assignment that you had created in the previous step and click on sign-up sheet to sign up for a topic.

  • Step 8: Sign up for any topic of your choice. If it is available then you will be assigned the slot and the number of available slots will be updated.

  • Step 9: Impersonate as another student from another team that you had created for the same assignment in the previous steps and follow the same steps as mentioned above to sign up for a topic. Sign up for the same topic as the previously impersonated student.

  • Step 10: You will now notice that since there was only one available slot and the previous team already signed up for it, the current team will be added to the waitlist for that topic.

  • Step 11: You can also check the student currently assigned to a topic and the waitlisted students in the manage assignments tab on logging in as an instructor (as done in the previous steps)

  • Step 12: Following the above mentioned steps various scenarios can be tested via the UI like:
  1. Adding more topics
  2. Multiple teams signing up for the same topic
  3. Teams dropping topics etc.

In the current implemention the following issue exists which will be fixed:

Scenario 1: Assigned teams dropping topics

Expected Behavior : After one team signs up for a topic and the second team that signs up for the same topic is added to the waitlist, if the first team drops the topic, ideally the available slots should be updated and the second team should be assigned the topic since it is the first on the waitlist.

Current Issue : The available slot after one team drops the topic does not update due to which the first team in the waitlist is not automatically assigned the topic.

Proposed Solution : Implement a new waitlist object to maintain the list of topics and the teams in the waitlist as ordered pairs: 〈team_id, topic_id〉as soon as the first team drops the topic the team_id field will be updated to the second team since it is the first on the waitlist.

Scenario 2: Instructor intervention when assigned teams drops topics

Expected Behavior : After one team signs up for a topic and the second team that signs up for the same topic is added to the waitlist, if the first team drops the topic, ideally the available slots should be updated and the second team should be assigned the topic since it is the first on the waitlist also we know that the manage topics tab while the instructor edits the assignment also contains the team that is currently assigned the topic and the list of waitlisted teams it should be updated when a change occurs.

Current Issue : The instructor does not see in the manage assignments topics tab that the topic is not assigned to the first team once it chooses to drop it.

Proposed Solution : Since the same functionality of maintaining the waitlist is being done at multiple places, the code does not update for the manage assignments topic tab for the instructor. In order to fix this, implementation of a new waitlist object is done to maintain the list of topics and the teams in the waitlist as ordered pairs: 〈team_id, topic_id〉as soon as the first team drops the topic the team_id field will be updated to the second team since it is the first on the waitlist and the same object will be consumed everywhere. Hence, the manage assignments topic will be updated automatically.

Test Plan

This project entails code refactoring such that all functionality relevant to waitlist is easily available under one class. Focus is on ensuring existing tests work as expected as the newly added code will not impact functionality per se. However, new unit tests will be written for testing waitlist.rb independently. Furthermore, test cases for suggestion_controller.rb & signed_up_team.rb are missing in the current implementation. Hence, we will be adding spec files for the aforementioned files as well. Certain edge cases will also be tested which have not been covered by the current tests.

Test Files

  1. sign_up_topic_spec.rb
  2. invitation_spec.rb
  3. waitlist_spec.rb
  4. lottery_controller_spec.rb
  5. suggestion_controller_spec.rb
  6. signed_up_team_spec.rb
  7. student_teams_controller_spec.rb

Cases To Be Tested

  1. Add team to waitlist if topic isn't available: When a team signs up for a topic already assigned to another team they automatically get added to the waitlist of that topic.
  2. Push the first waitlisted member (if exists) in case a confirmed slot is deleted: When a team drops the topic assigned to them or the instructor deletes the assignment of a topic to a particular team then the first team on the waitlist get assigned the topic for that assignment.
  3. Remove waitlists for team if a topic is confirmed: Once a team on the waitlists of multiple topics gets assigned a topic, the team is removed from the other waitlists.
  4. Clean waitlists & assign topic if the user has a team but not a topic: If a team hasn't signed up for a topic it should get auto-assigned one topic.


Automated Tests

Automated testing can be done using Capybara. Since a major part of the scenario can be tested using the UI, an automated test to create teams and sign up for topics can be created using Capybara with Cucumber. These tests can be written using the TDD approach prior to defining the code.

Code Coverage: Code coverage for the test cases can be obtained using the Code Coverage plugin and SimpleCov gem. The lines in the functions for which test cases are written in the corresponding spec file are highlighted in green and the rest of the lines are highlighted in red.

References

  1. Problem Statement
  2. Forked Repository

Team

  • Ankit Singh (asingh072318)
  • Asrita Kuchibhotla (kAsrita)
  • Neha Kotcherlakota (nehajaideep)
  • Vinit Desai (VinitDesai1998)