CSC/ECE 517 Spring 2022 - E2233. 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 look for a person using their name, user ID, or other criteria.
    2. An instructor should be able to look for assignments based on their name, due date, or other criteria.
    3. An instructor should be able to find rubrics (or other questionnaires) by name or by the courses or assignments in which they were utilized.
      1. There should also be a means for instructors to quickly locate rubrics (and other surveys) that have been utilized in a particular course. It should be possible to search or click someplace to bring up a list of questionnaires used in the course, with the list of questionnaires only extending to include those that are pertinent.
      2. One should also be able to search for questionnaires by words used in questions that belong to the questionnaires.
    4. There should be a way to search for specific ratings or text strings across all reviews of a team's work. Filtering reviews by score, text comment length, reviewer, and reviewee should be possible.
    5. An instructor or administrator should be able to search for all the assignments that a user has participated in.
    6. If more than one criterion needs to be specified, there should be an 'Advanced Search' button.

    Expertiza presently supports some of these queries, but the user interface is extremely clumsy. This is especially true on the site of an instructor or administrator, where huge and complicated search boxes push the vital elements of the page to the bottom of the screen. A quick search should be possible by just inputting text into an unobtrusive textbox. If further criteria are needed, there should be an "advanced search" button or link that opens up more textboxes, perhaps in Javascript, that are of an acceptable size and do not overwhelm the rest of the page's content.

    E2153 Previous Implementation

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

    E2233 Current Implementation

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

    Issue With Previous Implementation

    1. The code is not readable and there are some parts of 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.
    5. With compatibility issues, these workers can't be check-in currently.
    6. Format is not aligned between course search/assignment search and user search/rubric search.
    7. 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 with participants.

    Proposed Solution

    The design presented in this iteration of the project is very similar to the high-level design proposed last year in Fall 2021 Design. 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. Clear words stating the modification will be used to indicate changes from the previous design.

    Three main objects in this application are used as the basis for expanding search functionality. These are the user, assignment and questionnaire. Each of these points are 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:

    The Manage Users view in the current system process allows search users by Username, Full Name, and Email. We'll keep these three search criteria the same, but we'll rename "Username" to "User ID" to avoid confusion with "Full name." We'll let you search for fields regardless of the case of the string you're looking for. The user will be able to apply numerous filters at once, with the query's output matching all of them. An empty list will be returned if no results are found.

    Sequence Diagram

    Implementation

    In order to introduce the "Advanced Search" functionality, we will leverage the existing list method and make changes in that method.

    1. Remove the existing simple search in "app/views/users/list.html.erb".
      1. Add a new partial to render the search form.
      2. Style the user list table UI by adding the code as "class="table table-hover"".
    2. So in order to perform the search, we will introduce code to render a form input in file: "app/views/users/_search.html.erb".
      1. We will by styling the "Search" button with "class='btn btn-primary'".
      2. We will be styling the "text blank" using "class:'form-control'".
      3. Now our UI contains two search components to be displayed in the UI.
        1. search_field: This search bar is always displayed as it is in the existing UI.
        2. advance_search_fields: These are only displayed when the "Advanced Search" button is toggled to be ON.
    3. In "users controller.rb," add a form input handler to parse the form, which should just do parsing and provide arguments to the model.
    4. In the method "get_user_list", add code to perform the newly introduced advanced search which is in the User model file: "user.rb"
      1. As a result of this modification, the method "get_user_list" will now have three parameters (user id, full name, e-mail).
      2. To match the search with user fields, we utilize regular expressions, and it should allow for multiple input for comparison.
      3. The result will be returned to the controller in @users, and the list view will render it with paginated users once more.

    Search for Courses:

    In the current system when a user goes on Course page to look up for any course, a search box is present. User can add course name to look up any course. Functionality of Advanced search is also present in which user can search for any course based on start date and end date. User can select a filter whether he wants to search via created date filter or updated date filter. User can also select whether he wants course name which has a quiz present or not.

    But the issue with the current system is that it may lead to some discrepancies if multiple filters are selected and current system of searching a course does not work on DRY approach. Hence, we propose a new system which is quite like current one just with some additional modifications to make course search more effective and use the DRY approach.

    In the proposed system, the user will be able to search a course with the similar advanced search option as previous one, just the back-end code for implementing this functionality will be based on Don’t Repeat Yourself Approach. The part of code which is being reused again and again will be written at just one place and a call will be made to use that functionality. To search for a course by date, the user will have a similar drop-down list to choose whether he want to search by created date or updated date. For the date drop down menu, a calendar prompt will be displayed for date selection.

    To clear out the discrepancies in applying multiple filters, we implemented the DRY approach and tried to remove as much duplicate code as possible. All the courses that match user preferences in search box will be returned when user search using multiple filters. An empty list will be returned if search criteria is not matched.

    UML 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

    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


    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

    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

    Ed Gehringer (efg@ncsu.edu)

    Team Members

    Vishnu Challa (vchalla2@ncsu.edu)

    Sujith Tumma (stumma2@ncsu.edu)

    Indu Chenchala (ichench@ncsu.edu)

    Banpreet Singh Chhabra (bchhabr@ncsu.edu)

    References

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