CSC/ECE 517 Fall 2017/E1796. Unify Create Assignment and Edit Assignment pages

From Expertiza_Wiki
Jump to navigation Jump to search

E1796. Unify Create Assignment and Edit Assignment pages


Introduction

Expertiza is an open source project based on Ruby on Rails framework. It is a web application where students can submit and peer-review learning objects (articles, code, web sites, etc). It is used in select courses at NC State and by professors at several other colleges and universities. It also supports team projects, and the submission of almost any document type, including URLs and wiki pages. Expertiza enables the instructor to create new and customize existing assignments. It also enables the instructor to create a list of topics the students can sign up for as part of a project. Students can form teams in Expertiza to work on various projects and assignments. Expertiza supports submission across various document types, including the URLs and wiki pages.

Problem Statement:

In the Expertiza portal presently when an instructor wants to create a new assignment then as he selects a new assignment option only a few metrics are asked for while for mentioning the other metrics the professor needs to edit assignment and then under that he is shown the options to edit all the other metrics. Also, when we press the save button while creating or editing an assignment it goes to HTML form request, instead it should be changed to AJAX request so that the page does not need to get refreshed every time user saves the changes. Few other minor issues are validating the user entries and fixing tooltips so that they are supported across all the browsers.( Chrome, Safari, Firefox etc.)

Understanding the Problem Statement:

Issue1: Here we will be unifying the edit assignment view and new assignment view and for that we had to understand how the page requests are being sent on the background on the edit assignment page and accordingly change and implement the changes on the new assignment view. In edit assignment when we switch between the tabs a update request with all the parameters are sent on the background but the user doesn't know that. So incase of new assignment page we have to avoid doing that since we wont be having an assignment id yet to update the values.

Issue2: For validating user entries we had to check what all are the entries which are not being validated before saving and then accordingly update the models of the respective fields with regular expressions according to the field limitations and restrictions.

Issue 3: We need to create a ajax request instead of a form HTML submission request which is being sent when we save changes on edit assignment page and making sure prompt messages are not affected since ajax handling will again need the prompt messages to be shown since the user needs to know whether it is being saved or not.

Issue 4: For this we decided to check the functionalities of tool tips across all the browsers and see whether hovering over the tooltips display the message which is intended to so that the user understand what the tooltip will do upon clicking.


Scope of this Project:

Specific Improvements to assignment creation by navigating the user for creating a new assignment to edit assignment page(view/assignment/edit_assignment).
Making sure the edit assignment has blank fields in case of new assignment and saved fields in case of editing.
When an Instructor creates a new assignment, he should be able to see a table to set DueDates, Review Strategy options and Rubrics associated with the assignments. These options are currently available to the instructor while editing an assignment. We will be adding options to be set during creation of new assignment. Fields to add suggested topics will be excluded for new assignment creation.
Validating the user entries which is submission directory. It states that it is mandatory field and there should be no spaces but does it actually validate.
Fixes to tooltips so that it is supported across all the browsers
Change the save button to AJAX request instead of HTML form submission so that the page doesn’t need to get refreshed every time the user save the changes.

Use Case Diagram:

Current Flow:

This page is displayed in the present system when a professor wants to create a new assignment as we can see there are only very few metrics on this page which are being displayed.




While under Edit assignment the professor can now mention all the various metrics regarding the assignment on this page.

In the present implementation of the project, under the edit assignment page, even if we change the tab or click a tab a save request is sent in the background and the metrics are being saved. So, in this case when we have to save a view for a assignment page, we cannot actually do that because on every tab or every change of tab it needs an assignment id. But in case of new assignment page, we do not have an assignment id yet and we did not create the assignment.

Implementation

New assignment creation form will render forms to set Due Dates, Review Strategy and Rubrics as a table. Currently application ID is required to edit these options for an application. We will modify application/views and application controller to support adding these options while creation without application ID without breaking existing edit functionality.

In the present implementation the save button is handled by JQuery but only until a point where necessary attribute checks are done. Now, we need to prevent the page from reloading which can be done by mentioning a remote value as true in the form tag for the edit assignment page.

In the improved view of New Assignment instructor will be able to specify details under four tabs as shown in the below screenshots

In the General tab the instructor is now able to see all the options from the old view.


In the improved view, in addition to supporting the General tab, now there are new tabs like "Rubrics". This tab allows the instructor to select the various rubrics for the new assignment. This page also allows the setting of different rubrics for each round of the assignment.



In the improved view, there will be an additional new tab titled "Review Strategy". This tab allows the instructor to set the various policies for review of the new assignment. This page also allows assigning manual review strategies.


The new view also renders tab a titled "Due Dates" where the instructor can select the deadlines for various rounds of the selected rubrics. This tab also allows the instructor to select the late penalty policy The instructor can also choose to make a new late policy instead of selecting an existing policy created by the same instructor.

Code Changes

In the assignments_controller.rb controller, under the function create, we created a condition or blocking it from saving and then updating all the tabs with the assignment id it needs.

   if params[:button]
       if @assignment_form.save
          @assignment_form.create_assignment_node
          existAssignment = Assignment.find_by_name(@assignment_form.assignment.name)
          assignment_form_params[:assignment][:id] = existAssignment.id.to_s
          quesparams = assignment_form_params
          questArray = quesparams[:assignment_questionnaire]
          dueArray = quesparams[:due_date]
          questArray.each do |curquestionnaire|
          curquestionnaire[:assignment_id] = existAssignment.id.to_s
         end
             dueArray.each do |curDue|
               curDue[:parent_id] = existAssignment.id.to_s
             end
             quesparams[:assignment_questionnaire] = questArray
             quesparams[:due_date] = dueArray
             @assignment_form.update(quesparams,current_user)
              aid = Assignment.find_by_name(@assignment_form.assignment.name).id
              redirect_to edit_assignment_path aid
               return
               undo_link("Assignment \"#{@assignment_form.assignment.name}\" has been created successfully. ")
               else
                 flash.now[:error] = "Failed to create assignment"
                 render 'new'
                 end
         end


In the general.html.erb for ajax view if there is an error or if the saved changes are updated then it shows a flash message.

$("#flash").html('<%= j render partial: "shared/notice_banner" %>');
       <% if notice.present? %>
       <%= render partial: "shared/notice_banner" %>
       <% end %>

In the edit.html.erb following code changes were made. Setting the remote to true ensures that the following is an ajax request and not and html request.

<%= form_for @assignment_form.assignment, html: { id: 'assignment_form', :remote=>true } do %>
   <%= render "layouts/flash_notices" %>


The following code was added in the assignment.rb for validation of our page. The below implementation ensures that there are no special characters in the submission directory field, course_id is unique and name is always present.

 validates :name, presence: true
 validates :name, uniqueness: {scope: :course_id}
 validate :valid_num_review
 validates :directory_path, format: {with: /\A[a-zA-Z0-9]+\Z/ , message: "Please  follow the guidelines" }, presence:true

In general.html.erb for ajax view, the following code is rendered for displaying the flash messages.

$("#flash").html('<%= j render partial: "shared/notice_banner" %>');
       <% if notice.present? %>
       <%= render partial: "shared/notice_banner" %>
       <% end %>


Tooltips Functionality

The Tooltips functionalities are throughly checked in various browsers and the following screenshots show that they are supported across various browsers. The images show in Firefox and Internet Explorer browsers.

Files Modified

view/assignment/edit/.*
views/assignment/new.html.erb
views/assignment/*
controller/assignment_controller.rb
assignment_creation_spec.rb
assignments_controller_spec.rb


Design Pattern

1.MVC – The project is implemented in Ruby on Rails that uses MVC architecture. It separates an application’s data model, user interface, and control logic into three distinct components (model, view and controller, respectively).
2.Dry Principle – We are trying to reuse the existing functionalities in Expertiza, thus avoiding code duplication. Whenever possible, code modification based on the existing classes, controllers, or tables will be done instead of creating the new one.


Test Plan

Manual and automated testing to be done for below cases.
As an Instructor, clicking on Manage->Assignments should display all created assignments with correct directory, creation date, updation date, instructor id, and actions.
As an Instructor, clicking on Manage->Assignments->actions of an assignment should successfully redirect to action page.
As an Instructor, clicking on Manage->Assignments->new public assignment,will redirected to "Create New Public Assignment" Page.
As an Instructor, clicking on Manage->Assignments->new private assignment,will redirected to "Create New Private Assignment" Page.
As an Instructor, clicking on Manage->Assignments->new public/private assignment, "Create New Public/Private Assignment" should render a table with tabs "General", "Rubrics, "Review Strategy", "Due Dates".
As an Instructor, clicking on "Rubrics" tab from "Create New Public/Private Assignment" page, the tab should display table to select Questionnaire, menu type, display style, weight and notification limit.
As an Instructor, select review type, author feedback type, and Teammate review option from the drop down from "Rubrics" tab.
As an Instructor, select Review Strategy from drop down on "Rubrics" tab from "Create New Public/Private Assignment".
As an Instructor, set number of reviews done by each student on "Review Strategy" tab from "Create New Public/Private Assignment".
As an Instructor, Set minimum number of reviews done for each submission on "Review Strategy" tab from "Create New Public/Private Assignment".
As an Instructor, Set both calibrated and uncalibrated artifacts on "Review Strategy" tab.
As an Instructor, select Anonymous Review option on "Review Strategy" tab.
As an Instructor, select allow self review on "Review Strategy" tab.
As an Instructor, set due dates on "Due Date" tab from "Create New Public/Private Assignment".
As an Instructor, set number of submissions allowed on "Due Date" tab from "Create New Public/Private Assignment".
As an Instructor, set number of reviews allowed on "Due Date" tab from "Create New Public/Private Assignment".
As an Instructor, set number of teammate review allowed on "Due Date" tab from "Create New Public/Private Assignment".
As an Instructor, after updating the fields on all tabs and clicking on save should create an assignment form in database.
As an Instructor, after saving the new assignment, redirect to edit page to update Signup topics.
As an instructor, save should not reload the page while creating a new assignment.
Test when instructor creates a empty template for assignment form.
Test when name of the assignment is not unique.
Test when late policy is not created for instructor, and instructor tries to create a new assignment.
All Users should be able to see tooltip of respective actions on all Browsers.
As an instructor, delete an assignment.
Form submission validates the attributes of all associated models.

Below are some of the test cases added

  it "is able show tab review strategy" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     find_link('ReviewStrategy').click
     expect(page).to have_content("Review Strategy")
   end
   it "is able show tab due deadlines" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     find_link('Due date').click
     expect(page).to have_content("Deadline type")
   end
   
   it "set the deadline for an assignment review" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     click_link 'Due date'
     fill_in 'assignment_form_assignment_rounds_of_reviews', with: '1'
     fill_in 'datetimepicker_submission_round_1', with: (Time.now.in_time_zone + 1.day).strftime("%Y/%m/%d %H:%M")
     fill_in 'datetimepicker_review_round_1', with: (Time.now.in_time_zone + 10.days).strftime("%Y/%m/%d %H:%M")
     click_button 'submit_btn'
     submission_type_id = DeadlineType.where(name: 'submission')[0].id
     review_type_id = DeadlineType.where(name: 'review')[0].id
     submission_due_date = DueDate.find(1)
     review_due_date = DueDate.find(2)
     expect(submission_due_date).to have_attributes(
                                        deadline_type_id: submission_type_id,
                                        type: 'AssignmentDueDate'
                                    )
     expect(review_due_date).to have_attributes(
                                    deadline_type_id: review_type_id,
                                    type: 'AssignmentDueDate'
                                )
   end
  it "is able show tab rubrics" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     find_link('Rubrics').click
     expect(page).to have_content("rubric varies by round")
   end
   it "is able show attributes in rubrics" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     find_link('Rubrics').click
     expect(page).to have_content("rubric varies by round")
   end
  it "sets attributes for review strategy auto selects" do
     login_as("instructor6")
     visit '/assignments/new?private=0'
     fill_in 'assignment_form_assignment_name', with: 'public assignment for test'
     select('Course 2', from: 'assignment_form_assignment_course_id')
     fill_in 'assignment_form_assignment_directory_path', with: 'testDirectory'
     find_link('ReviewStrategy').click
     select "Auto-Selected", from: 'assignment_form_assignment_review_assignment_strategy'
     fill_in 'assignment_form_assignment_review_topic_threshold', with: 3
     fill_in 'assignment_form_assignment_max_reviews_per_submission', with: 10
     click_button 'Create'
     assignment = Assignment.where(name: 'public assignment for test').first
     expect(assignment).to have_attributes(
                               review_assignment_strategy: 'Auto-Selected',
                               review_topic_threshold: 3,
                               max_reviews_per_submission: 10
                           )
   end
 end
describe "deadlines", js: true do
   before(:each) do
     @assignment = create(:assignment, name: 'public assignment for test')
     login_as("instructor6")
     visit "/assignments/#{@assignment.id}/edit"
     click_link 'Due date'
   end
   # instructor can set deadline for review and taking quiz
   it "set the deadline for an assignment review" do
     fill_in 'assignment_form_assignment_rounds_of_reviews', with: '1'
     fill_in 'datetimepicker_submission_round_1', with: (Time.now.in_time_zone + 1.day).strftime("%Y/%m/%d %H:%M")
     fill_in 'datetimepicker_review_round_1', with: (Time.now.in_time_zone + 10.days).strftime("%Y/%m/%d %H:%M")
     click_button 'submit_btn'
     submission_type_id = DeadlineType.where(name: 'submission')[0].id
     review_type_id = DeadlineType.where(name: 'review')[0].id
     submission_due_date = DueDate.find(1)
     review_due_date = DueDate.find(2)
     expect(submission_due_date).to have_attributes(
       deadline_type_id: submission_type_id,
       type: 'AssignmentDueDate'
     )
     expect(review_due_date).to have_attributes(
       deadline_type_id: review_type_id,
       type: 'AssignmentDueDate'
     )
   end
 end

Test cases which were modified

  it 'redirets to assignment#edit page' do
         allow(assignment_form).to receive(:assignment).and_return(assignment)
         allow(assignment_form).to receive(:save).and_return(true)
+        allow(assignment_form).to receive(:update).with(any_args).and_return(true)
         allow(assignment_form).to receive(:create_assignment_node).and_return(double('node'))
         allow(assignment).to receive(:id).and_return(1)
         allow(Assignment).to receive(:find_by_name).with('test assignment').and_return(assignment)
        allow_any_instance_of(AssignmentsController).to receive(:undo_link)
          .with('Assignment "test assignment" has been created successfully. ').and_return(true)
        post :create, @params
        expect(response).to redirect_to('/assignments/1/edit')
      end
  context 'when assignment_form is saved successfully' do
      it 'redirets to assignment#edit page' do
         allow(assignment_form).to receive(:assignment).and_return(assignment)
         allow(assignment_form).to receive(:save).and_return(true)
         allow(assignment_form).to receive(:create_assignment_node).and_return(double('node'))
+        allow(existAssignment).to receive(:id).and_return(1)
+        allow(Assignment).to receive(:find_by_name).with('test assignment').and_return([double('Assignment', id: 1)])
         allow_any_instance_of(AssignmentsController).to receive(:undo_link)
           .with('Assignment "test assignment" has been created successfully. ').and_return(true)
         post :create, @params
        expect(response).to redirect_to('/assignments/1/edit')
      end
    end
   context 'when assignment_form is not saved successfully' do
       it 'renders assignment#new page' do
         allow(assignment_form).to receive(:save).and_return(false)
-        post :create, @params
+        params = {button: 1}
+        post :create, params
         expect(response).to render_template(:new)
       end
     end

References

  1. Expertiza on GitHub
  2. The live Expertiza website
  3. Expertiza project documentation wiki
  4. Rspec Documentation