CSC/ECE 517 Fall 2023 - E2355. Improving Search Facility In Expertiza

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

The Expertiza project makes use of peer review to allow students to learn from one another. It's a Ruby on Rails-based open-source application. It is used by faculty and students for the management of courses and assignments for specific courses. Different screens in the manage content area of the application offer information about users, courses, assignments, questionnaires, and reviews.

The program should have a fully functional search functionality throughout all views, allowing a user to quickly find any sort of data using any number of parameters that meet his needs. Users should be found using one additional parameter, such as their name, full name, email address, and so on. Similarly, assignments should be searched by name, creation date, updated date, and other criteria.

However, the existing application's search functionality is limited to a single parameter for users and assignments. A search feature has not yet been introduced in the management of questionnaires. This project aims to improve Expertiza's search functionality by adding search bars if they aren't already there, creating an advanced search tool that allows users to search using several parameters, and making the search functionality look more appealing.

Test Login Credentials

  • UserId: instructor6
  • Password: password
  • Problem Statement

    1. An instructor or administrator can search for a user by name, user ID, or other characteristics.
    2. An instructor should be able to search for assignments by name, due date (creation date, updated date), or other characteristics.
    3. An instructor should be able to search for rubrics (or other questionnaires) by name, or by the courses or assignments they have been used in.
      1. For the instructor, there also needs to be a way to quickly find rubrics (and other questionnaires) that have been used in a single course. It should be possible to search or click somewhere to bring up a list of questionnaires used in the course, expanding only the applicable questionnaires in the list of questionnaires.
      2. One should also be able to search for questionnaires by words used in items (questions) that belong to the questionnaires.
    4. There should be a way to search all reviews of a particular team’s work for particular scores or text strings. Reviews should be able to be filtered by score, text comment length, reviewer, and reviewee.
    5. An instructor or administrator should be able to search for all the assignments that a particular user has participated in.


    Some of these searches are currently possible in Expertiza, but the user interface is quite cumbersome. This is especially true on an instructor’s or administrator’s homepage, where large and confusing search boxes shift the important parts of the page down to the bottom of the screen. There should be a way to do a simple search by just typing text into an unobtrusive textbox. If more criteria need to be specified, there should be an “advanced search” button or link that opens up additional textboxes, perhaps in Javascript, that are of reasonable size and do not overwhelm other content on the page.

    E2153 Previous Implementations

    1. E2153 Github Repository
    2. E2153 Pull Request
    3. Demo Video
    1. E2233 Github Repository
    2. E2233 Pull Request
    3. Demo Video

    E2233 Current Implementation

    1. E2355 Github Repository
    2. E2355 Pull Request

    Issue With Previous Implementation

    1. The code is not readable and there are some parts of the code that still need to DRYed out.
    2. The test cases "it" clause must be more specific to the test. This is the same for all the test cases as of now which is quite confusing.
    3. All implementations are working on javascript inside tree_display.jsx. There are some changes that are overlapping and confusing to refactor.
    4. All the code changes should follow proper ruby naming conventions and there should be enough comments to explain the functionality. But no unnecessary comments too.
    5. With compatibility issues, these workers can't be checked in currently.
    6. Format is not aligned between course search/assignment search and user search/rubric search.
    7. The questionnaire search is not straightforward and the list is not working.
    8. Searching for users with "name" and "full name" is confusing.
    9. Searching criteria can't be accumulated.
    10. Instructors and administrators can't find assignments that a user participates in.
    11. There is no search option to find reviews of a particular team.

    Proposed Solution

    The design presented in this iteration of the project is very similar to the high-level design proposed last year in Spring 2022 Design. Since this pull request was not merged, we have included the proposed changes that are credible. Below is a comparable explanation of the previously offered remedy, as well as some new design decisions to improve upon the previous iteration of this issue.

    Four main objects in this application are used as the basis for expanding search functionality. These are the user, assignment, questionnaire, and review. Each of these points is searchable by the title of the object or not searchable at all. The remaining sections note the current situation and propose a tentative solution.

    Search for User:

    In the current Manage Users view, users can search by Username, Full Name, and Email. We'll keep these three search options but rename "Username" to "User ID" to eliminate confusion with "Full Name." Users will be able to search regardless of the case of the string. Multiple filters can be applied simultaneously, and the search results will match all of them. If there are no results, an empty list will be returned.

    Sequence Diagram for User Search

    Implementation

    1. To introduce "Advanced Search" functionality:
      1. Modify the existing list method in the controller.
      2. Remove the simple search in "app/views/users/list.html.erb."
      3. Add a new partial for the search form.
      4. Style the user list table with "class="table table-hover."
    1. To perform the search:
      1. Create a form input in "app/views/users/_search.html.erb."
      2. Style the "Search" button with "class='btn btn-primary.'"
      3. Style the "text blank" with "class:'form-control.'"
      4. The UI contains two search components: "search_field" (always displayed) and "advanced_search_fields" (displayed when "Advanced Search" is ON).
    1. In the "users controller.rb":
      1. Add a form input handler to parse the form and provide arguments to the model.
    1. In the "get_user_list" method:
      1. Implement advanced search in the User model.
      2. The method now takes three parameters (user id, full name, e-mail).
      3. Use regular expressions to match user fields and allow multiple inputs for comparison.
      4. Return results to the controller in @users for rendering in the list view with paginated users.

    Search for Courses:

    In the current system, users can search for courses on the Course page using a search box. They have the option to search by course name or use an advanced search with filters for start and end dates, creation and update dates, and the presence of quizzes. However, using multiple filters can lead to inconsistencies, and the system lacks the "Don't Repeat Yourself" (DRY) approach.

    In the proposed system, we maintain a similar user interface for advanced search but implement it with a DRY approach. We centralize the reusable code and call it when needed. To search by date, users can choose between the creation date and the update date from a dropdown menu with a user-friendly calendar prompt.

    By applying the DRY approach, we minimize duplicate code and ensure that courses matching the user's filter preferences are returned, while an empty list is presented if there are no matching criteria.

    Sequence Diagram for Course Search

    Implementation

    Current system has most of the functionalities implemented already, like Advanced search functionality etc. We will use this code of current system and optimize this code by using the DRY approach and removing the duplicate and reused code. Hence our implementation first describes the current implementation of various functionalities as described in wiki page of 2021 and then we provide the refactoring of the code.

    The implementation of this functionality of advanced search and optimal UI is written in "app/assets/javascripts/tree_display.jsx". The functionality of dropdown menu in advanced search has the same format as “User Advanced Search”. The components used for implementing the advanced search functionality are AdditionalSearchDropDown, DatePicker, and HASQUIZ_TOGGLE. The React component FilterableTable is used to implement pop-up advanced search functionality.

    1. Fetching and Displaying all the sub-contents when user clicks on a course
      1. The HTTP POST request is sent by getSubFolderData() from FilterableTable component
      2. The state of FilterableTable component is updated after retrieving the data.
      3. An update to ContentTable component is triggered once the state is updated.
    2. Course Search
      1. ContentTable component handles the search method, which filters out courses' names that match the user's input corresponding to each filter as selected by the user.

    Refactoring of implementation of above desired functionalities is done in this new proposed system and code duplication is removed. DRY approach has been implemented in this system for Course and assignment search functionality along with advanced search.

    Search for Assignments:

    In the current system implementation, searching by assignment name (partial or whole) is supported. After pressing the Advanced Search button in the proposed system, the user will be able to search for an assignment with additional filters. The filters will contain a creation date, an updated date, and a checkbox to indicate if a quiz is included. The user might apply many filters at the same time, and the query's output would match all of them.

    When searching for an assignment by date, the user will have the option of searching by created or modified date from a drop-down menu. Following that, he will be presented with a calendar from which he may choose a date, and any tasks created/updated on or before that date will be displayed.

    The user may apply additional filters by tapping the Advanced Search button adjacent to the Search button; a hidden div will then be shown below, including text fields for all of the columns. The filters will return all assignments that fit the criteria. If the search criteria do not match any entries in the database, an empty list will be provided.

    Sequence Diagram for Assignment Search

    Implementation

    Because this component is only specified in the file "app/assets/javascripts/tree display.jsx," we can only use javascript to implement it. The format of the interactive dropdown advanced search code will be the same as "User Advanced Search." We built a pop up advanced search capability in React component FilterableTable utilizing AdditionalSearchDropDown, DatePicker, and HASQUIZ TOGGLE components.

    The ContentTable component handles the searching mechanism, which filters out course titles that match the user's input.

    Because course and assignment searches are so similar, they share the same code in the FilterableTable component.

    Search for Questionnaires:

    The existing system includes search functionality for the following criteria:

    1. A text field : where you can search for a keyword within name of  Questionnaire
    2. A text field : to search for a keyword or a string In a single question within a questionnaire
    3. A text field:For the Course name
    4. A text field:For the Assignment name

    The user will be able to apply numerous filters at once, and the query's output will match all of them. An empty list will be returned if no results are found..

    As a simple search,There is a default search box for the questionnaire's name and if a user wants to apply several filters, user need to press the "Advanced Search" button which is  adjacent to the "Search" button, Also, a hidden field with text boxes for all the columns are being rendered below. A List is being displayed for the questionnaires which matches the search

    In the current system for searching a Questionnaire does not follow the DRY approach. As a result, we suggest a new system that is quite similar to the current one, but with a few tweaks to make the Questionnaire search more effective and to follow the DRY approach.

    Proposed System:

    The user will be able to search questionnaires in the proposed system using an advanced search option similar to the previous one; however, the back end code for implementing this functionality needs to be refactored by following DRY Approach.In the file: app/assets/javascripts/tree display.jsx  code that is in common for all the searches  needs to be refactored

    Sequence Diagram for Questionnaire Search

    Implementation

    We will use the existing list method and make changes to it in order to present the "Advanced Search" functionality.

    Current Implementation:

    1. Getting sub-contents when a user press on a course
      1. From FilterableTable ,getSubFolderData() method makes an HTTP POST request.
      2. It will update the state of the FilterableTable component after retrieving the data.
      3. When the state is updated, the ContentTable component is updated, and the component is rerendered
    1. Searching for questionnaire
      1. FilterableTable is in charge of the searching method. When the search button is pressed, all sub-contents from each questionnaire category are filtered based on the user's input.
      2. From FilterableTable component, handleQuestionnaireSearchChange() method keeps track of the search input field. When the input field is cleared, it will trigger an update.

    Proposed Implementation

    In the proposed system, we will be using existing list method However, the back end code for implementing this functionality needs to be refactored by following DRY Approach.In the file: app/assets/javascripts/tree display.jsx code that is in common for all the searches needs to be refactored

    Search for Reviews:

    The HTML code in the "app/views/reports/_review_report.html.erb" file is responsible for rendering a review report table. The table is designed to display reviewer information, the number of reviews completed, the teams reviewed, scores awarded, average scores, metrics, and the ability to assign grades and write comments. It also provides the option to export the review scores to a CSV file. There is no existing searching functionality to filter through the rows. We include a search functionality to filter the results in the review report table based on team names. This feature provides users with the ability to narrow down the displayed data, making it easier to find specific teams or reviewers.

    Implementation

    1. Search Input Field: A search input field with the label "Search Team Name" is included in the user interface. Users can enter a team name in this field to specify the filter criteria.

    2. Search Button: A "Search" button is provided next to the search input field. Clicking this button triggers the search functionality.

    3. JavaScript Search Function: A JavaScript function named "searchTeam()" is defined in the code. This function retrieves the user's input, converts it to lowercase for case-insensitive matching, and then iterates through the rows of the table to find matches.

    4. Filtering and Display: When the user initiates a search, the JavaScript function compares the search input with the team names in the table. Rows that match the search criteria are displayed, while non-matching rows are hidden, effectively filtering the results based on the entered team name.

    Lo-fi UI Example

    Flowchart

    Test Plan

    Rspec Unit Tests

    Functionalities to be tested:

    1. Given an unfiltered search result, everything should be included.
    2. The filtered search produces a list of items that include the filtered search item.
    3. When a search is invalid, an empty list is returned.

    Code Snippet Modified

    Here are some improvements on previously implemented test cases:

    1. The "it" clause is going to be more specific with respect to each test.
    2. We will be introducing fixtures in the tests to modularize the common code in each test.
    3. We will try to add more tests if possible to increase the code coverage of the controllers and models.


    # spec/models/user_spec.rb
        context 'when current user is super admin and searches by user name' do
          it 'fetches all users with the given user name' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abc", "", "")).to eq([user1, user2])
          end
        end
    
        context 'when current user is super admin and searches by incorrect user name' do
          it 'fetches an empty users list if user with given user name is not found' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abcd", "", "")).to eq([])
          end
        end
    
        context 'when current user is super admin and searches by user full name' do
          it 'fetches all users with the given full name' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "abc bbc", "")).to eq([user1, user2])
          end
        end
    
        context 'when current user is super admin and searches by incorrect user full name' do
          it 'fetches an empty users list if user with given full name is not found' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "abc bbcd", "")).to eq([])
          end
        end
    
        context 'when current user is super admin and searches by user email' do
          it 'fetches all users with the given email' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "", "abcbbe@gmail.com")).to eq([user2])
          end
        end
    
        context 'when current user is super admin and searches by incorrect user email' do
          it 'fetches an empty users list if user with given email is not found' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "", "abcbbcd@gmail.com")).to eq([])
          end
        end
    
        context 'when current user is super admin and searches by user name and email' do
          it 'fetches all users with given user name and email' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abc", "", "abcbbc@gmail.com")).to eq([user1])
          end
        end
    
        context 'when current user is super admin and searches by incorrect user name and email' do
          it 'fetches an empty users list if user with given user name and email is not found' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abc", "", "abcbdfbc@gmail.com")).to eq([])
          end
        end
    
        context 'when current user is super admin and searches by user full name and email' do
          it 'fetches all users with given full name and email' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "abc bbc", "abcbbe@gmail.com")).to eq([user2])
          end
        end
    
        context 'when current user is super admin and searches by incorrect user full name and email' do
          it 'fetches an empty users list if user with given full name and email is not found' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("", "abcsd bbc", "abcfdbbe@gmail.com")).to eq([])
          end
        end
    
        context 'when current user is super admin and searches by user name and full name' do
          it 'fetches all users with given user name and full name' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abc", " bbc", "")).to eq([user1, user2])
          end
        end
    
        context 'when current user is super admin and search by user name, full name and email' do
          it 'fetches all users with given user name, full name and email' do
            allow(user).to receive_message_chain("role.super_admin?") { true }
            expect(user.get_user_list("abc", " bbc", "abcbbe@gmail.com")).to eq([user2])
          end
        end
      end
    

    Manual UI Testing

    UI tests will be performed to reproduce the behavior previously mentioned. These steps were reproduced from the previously proposed solution for this issue. Please pair with our Demo Video to confirm our testing

    Search for User

    1. Log into expertiza to view the home page
    2. Go to Manage > Users
    3. Type the search string in the search box available on the UI and select the column to search for from the dropdown.
    4. To perform a search based on multiple filters, the user can tap on the Advanced Search button adjacent to the Search button, the view renders a hidden div containing text boxes for all the columns, allowing the user to search based on multiple columns.
    5. All the entries that match the specified criteria will be returned.
    6. An empty list is returned if the search criteria don't match any valid records in the database.

    Search for Courses

    1. Log into expertiza to view the home page
    2. Go to Manage > Courses
    3. Type the search criteria fro the course (name, institution etc) in the available search box and select the appropriate field from the dropdown.
    4. To perform a search based on multiple filters, the user can tap on the Advanced Search button adjacent to the Search button, the view renders a hidden div containing text boxes for all the columns, allowing the user to search based on multiple columns.
    5. All the entries that match the given criteria will be returned.
    6. An empty list is returned if the search criteria don't match any valid records in the database.

    Search for Assignment

    1. Log into expertiza to view the home page
    2. Go to Manage > Assignments
    3. Type the search criteria in the available search criteria and select the appropriate field from the dropdown.
    4. To perform a search based on multiple filters, the user can tap on the Advanced Search button adjacent to the Search button, the view renders a hidden div containing text boxes for all the columns, allowing the user to search based on multiple columns.
    5. All the entries that match the given criteria will be returned.
    6. An empty list is returned if the search criteria don't match any valid records in the database.

    Search for Questionnaire

    1. Log into expertiza to view the home page
    2. Go to Manage > Questionnaires
    3. Type the search criteria in the available search criteria and select the appropriate field from the dropdown.
    4. To perform a search based on multiple filters, the user can tap on the Advanced Search button adjacent to the Search button, the view renders a hidden div containing text boxes for all the columns, allowing the user to search based on multiple columns.
    5. All the entries that match the given criteria will be returned.
    6. An empty list is returned if the search criteria don't match any valid records in the database.

    Resulting Snapshots

    You can watch this demo video for a rough idea of the UI pages. Demo.

    User Search UI

  • Before Change
  • After Change
  • The first image depicts the USER search UI page. The second image depicts the USER page, which allows users to search by userid, name, and e-mail. It's worth noting that not all parameters are required for a successful search. You can search using one, two, or all of the options.

    Course Search UI

  • Before Change
  • After Change
  • The first picture shows the main page of COURSE searching UI. The second picture shows the searching result that search by created date. Note that it doesn't necessarily need all parameters to search. One can search with one or two or all parameters.

    Assignment Search UI

  • Before Change
  • After Change
  • The first picture shows the main page of ASSIGNMENT searching UI. The second picture shows the searching result that search by updated date. Note that it doesn't necessarily need all parameters to search. One can search with one or two or all parameters.

    Questionnaire Search UI

  • Before Change
  • After Change
  • The first picture shows the main page of questionnaire searching UI. The second picture shows the questionnaire searching page with advance search and detail of review questionnaire. Note that it doesn't necessarily need all parameters to search. One can search with one or two or all parameters.

    Project Mentor

    Srilekha Gudipati (sngudipa@ncsu.edu)

    Team Members

    Ananya Mantravadi (amantra@ncsu.edu)

    Anvitha Reddy Gutha (agutha@ncsu.edu)

    Nainisha Bhallamudi (nbhalla@ncsu.edu)

    References

    1. Fall 2021 Design
    2. Fall 2020 Design
    3. Fall 2019 Design
    4. Expertiza on GitHub
    5. RSpec Documentation