CSC/ECE 517 Fall 2020 - E2054. Auto generate submission directory names based on assignment names

From Expertiza_Wiki
Jump to navigation Jump to search

This wiki page describes the changes made under E2054, in order to auto-generate submission directory names based on assignment names for Fall 2020, CSC/ECE 517.

About Expertiza

Expertiza is an open source project based on Ruby on Rails framework, created and maintained by the joint efforts of students and faculty at North Carolina State University.

It allows the instructors to create new assignments and customize new or existing assignments. Expertiza also allows an instructor to create a list of topics the students can sign up for. Students can form teams on the web application to work on various projects and assignments together. Additionally, students can peer review each other's submissions allowing them to improve upon their work. Expertiza supports submission across various document types, including the URLs and wiki pages.


Need for the current project

Goal

Each assignment should have its own unique auto-generated submission directory, which is named based on the assignment name entered by the teacher.

Issues to be fixed

In the current implementation of Expertiza, there are following issues need to be addressed:
Issue #1: The directory name should be auto-generated from the assignment name.
Issue #2: It should be done by changing spaces in the names to underscores. E.g., the directory for Program 1 is by default "Program_1".
Issue #3: A check should be added to prevent two assignments in the same course from having the same name.
Issue #4: Verify or add if not present - a check to stop two assignments from sharing the same directory.
Issue #5: On changing name of an assignment while creating it, the code shouldn't throw a NoMethodError.

Issues that have been fixed

Fix #1: Submission directory is successfully being generated after the assignment name is typed in. If needed, the submission directory can be changed, however any modifications to the assignment name will just auto-generate it to match.
Fix #2: A check was added to ensure that assignments in the same course do not share the same name. When creating a course, if the assignment name is a duplicate, it will reset the entire form.
Fix #3: A check was added to ensure that assignments in the same course do not share the same submission directory. When creating a course, if the submission directory is a duplicate, it will reset the entire form.
Fix #4: These checks were also put in place when modifying an existent assignment.


Project implementation

Submitted work and demonstration of project

Files involved

The controller, helper and spec were modified for this project:
1. Assignments Controller - assignments_controller.rb
2. Assignments View - _general.html.erb
3. Assignemnts Controller Spec - assignments_controller_spec.rb
4. Assignments Model - assignment.rb

Assignments Controller

This is a controller that helps instructors create, modify, copy new assignments. Each assignment can be associated with specific Rubrics, Review Strategy and Due dates.

Assignments View

This the view for creating the new assignments and editing the existing assignments. This view also handles specifications of Rubrics, Review Strategy and Dates.

Assignemnts Controller Spec

Tests and bug fixes pertaining to assignments controller.

Assignments Model

The ruby code which defines how the assignment model functions.

Description of current project

The project primarily deals with the AssignmentsController and AssignmentsView, and changes made are as follows:

The directory name is auto-generated from the assignment name typed in by the instructor.

This is achieved by replacing all spaces in the names with underscores, and removing all special characters like '/','\','$', etc from the auto-generated submission directory name.

If any two assignments of the same name under the same course are attempted to be created, it is prevented and an error message is displayed to the user stating the the submission directory name already exists.

The odd case of a teacher editing the name of an already existing assignment to one that already exists is also handled. Expertiza will display a similar error message stating that the assignment couldn't be saved.

Changes made to code

Most changes were made in the assignments_controller.rb file. Checks were added to ensure that an existing assignment name or submission directory did not exist when creating a new assignment. If the assignment was not created due to an error, the code would render new which would cause the assignment to be created even though it did not pass all of the checks. Instead of using render new, redirect_to "/assignments/new?private=1" was used to ensure the form would be reset upon any errors.

The following function was added to app/views/assignments/edit/_general.html.erb, to generate submission directory names with underscores replacing spaces:

  // E2054 Javascript function to generate the submission directory
  $(function() {
      $("#assignment_form_assignment_name").change(function() {
          filename = $( "#assignment_form_assignment_name" ).val().replace(/ /g,"_").replace(/[/\\?%*:|"<>/$&!#%^@]/g, '');;
          $('#assignment_form_assignment_directory_path').val(filename);
      });
  });

Changes were made to the create function in assignments_controller.rb, such that it only creates the assignment directory if the one with the same name doesn't already exist:

Before

  def create
    @assignment_form = AssignmentForm.new(assignment_form_params)
    if params[:button]
      if @assignment_form.save
        @assignment_form.create_assignment_node
        exist_assignment = Assignment.find_by(id: @assignment_form.assignment.id)
        assignment_form_params[:assignment][:id] = exist_assignment.id.to_s
        if assignment_form_params[:assignment][:directory_path].blank?
          assignment_form_params[:assignment][:directory_path] = "assignment_#{assignment_form_params[:assignment][:id]}"
        end
        ques_array = assignment_form_params[:assignment_questionnaire]
        due_array = assignment_form_params[:due_date]
        ques_array.each do |cur_questionnaire|
          cur_questionnaire[:assignment_id] = exist_assignment.id.to_s
        end
        due_array.each do |cur_due|
          cur_due[:parent_id] = exist_assignment.id.to_s
        end
        assignment_form_params[:assignment_questionnaire] = ques_array
        assignment_form_params[:due_date] = due_array
        @assignment_form.update(assignment_form_params, current_user)
        aid = Assignment.find_by(id: @assignment_form.assignment.id).id
        ExpertizaLogger.info "Assignment created: #{@assignment_form.as_json}"
        redirect_to edit_assignment_path aid
        undo_link("Assignment \"#{@assignment_form.assignment.name}\" has been created successfully. ")
        return
      else
        flash.now[:error] = "Failed to create assignment"
        render 'new'
      end
    else
      render 'new'
      undo_link("Assignment \"#{@assignment_form.assignment.name}\" has been created successfully. ")
    end
  end

After

  def create
    @assignment_form = AssignmentForm.new(assignment_form_params)
    if params[:button]
      # E2054 Query for existing directory name and assignment name
      find_existing_assignment = Assignment.find_by(name: @assignment_form.assignment.name, course_id: @assignment_form.assignment.course_id)
      dir_path = assignment_form_params[:assignment][:directory_path]
      find_existing_directory = Assignment.find_by(directory_path: dir_path, course_id: @assignment_form.assignment.course_id)
      if !find_existing_assignment and !find_existing_directory and @assignment_form.save #No existing names/directories 
        @assignment_form.create_assignment_node
        current_assignment = Assignment.find_by(name: @assignment_form.assignment.name, course_id: @assignment_form.assignment.course_id)
        assignment_form_params[:assignment][:id] = current_assignment.id.to_s 
        ques_array = assignment_form_params[:assignment_questionnaire]
        due_array = assignment_form_params[:due_date]
        ques_array.each do |cur_questionnaire|
          cur_questionnaire[:assignment_id] = current_assignment.id.to_s 
        end
        due_array.each do |cur_due|
          cur_due[:parent_id] = current_assignment.id.to_s 
        end
        assignment_form_params[:assignment_questionnaire] = ques_array
        assignment_form_params[:due_date] = due_array
        @assignment_form.update(assignment_form_params, current_user)
        aid = Assignment.find_by(name: @assignment_form.assignment.name, course_id: @assignment_form.assignment.course_id).id 
        ExpertizaLogger.info "Assignment created: #{@assignment_form.as_json}"
        redirect_to edit_assignment_path aid
        undo_link("Assignment \"#{@assignment_form.assignment.name}\" has been created successfully. ")
        return
      else # E2054 Existing Directory or Assignment Name was Found
        if find_existing_assignment
          flash[:error] = @assignment_form.assignment.name + " already exists as an assignment name"
        end
        if find_existing_directory
          flash[:error] = dir_path + " already exists as a submission directory name"
        end
        redirect_to "/assignments/new?private=1"
        # E2054 Rendering to this page instead of render new, this prevents it from creating a new assignment upon error 
      end
    else
      render 'new'
      undo_link("Assignment \"#{@assignment_form.assignment.name}\" has been created successfully. ")
    end
  end

Changes were made to the update_feedback_assignment_form_attributes function in the same file to flash an error if an edited file has the same name:

Before

  def update_feedback_assignment_form_attributes
    if params[:set_pressed][:bool] == 'false'
      flash[:error] = "There has been some submissions for the rounds of reviews that you're trying to reduce. You can only increase the round of review."
    else
      if @assignment_form.update_attributes(assignment_form_params, current_user)
        flash[:note] = 'The assignment was successfully saved....'
      else
        flash[:error] = "Failed to save the assignment: #{@assignment_form.errors.get(:message)}"
      end
    end
    ExpertizaLogger.info LoggerMessage.new("", session[:user].name, "The assignment was saved: #{@assignment_form.as_json}", request)
  end

After

  def update_feedback_assignment_form_attributes
    if params[:set_pressed][:bool] == 'false'
      flash[:error] = "There has been some submissions for the rounds of reviews that you're trying to reduce. You can only increase the round of review."
    else
      if @assignment_form.update_attributes(assignment_form_params, current_user)
        flash[:note] = 'The assignment was successfully saved....'
      else
        flash[:error] = "Failed to save the assignment: #{@assignment_form.assignment.name}" 
      end
    end
    ExpertizaLogger.info LoggerMessage.new("", session[:user].name, "The assignment was saved: #{@assignment_form.as_json}", request)
  end

The following validations were added to app/models/assignment.rb, without these validations the user was allowed to change the assignment name or submission directory to one that already exists.

  validates :directory_path, presence: true # E2054 Needs Validation for unique submission directory
  validates :directory_path, uniqueness: {scope: :course_id}  # E2054 Needs Validation for unique submission directory

Test Plan

Manual UI Testing

The following steps must be performed to test the project UI:

Step 1: Log in as an Instructor, with Username - instructor6, Password - password




Step 2: Create a new assignment. In this case our assignment is called "E2054 Test Assignment", under course CSC 216 Fall 2009




Step 3: To save the assignment, the Review and Author Feedback rubrics need to be filled in




Step 4: On completion, the assignment will be saved




Step 5: If another assignment of the same name under the same course is created, the following error is displayed




Step 6: On editing an already made assignment to match the same details as "E2054 Test Assignment"



We get the following error:




RSpec Testing

The following RSpec tests were added to the assignments_contoller_spec.rb file

    # E2054 Ensure Assignment Names Cannot Match
    context 'when assignment_form is not saved successfully due to same assignment name already existing' do
      it 'raises validation error' do
        assignment1 = create(:assignment, name: 'Assignment 1', course_id: 1, directory_path: 'Assignment1')
        expect {create(:assignment, name: 'Assignment 1', course_id: 1,
                       directory_path: 'Assignment2')}.to raise_error(ActiveRecord::RecordInvalid)
      end
    end

    # E2054 Ensure Submission Directory Cannot Match
    context 'when assignment_form is not saved successfully due to same submission directory already existing' do
      it 'raises validation error' do
        assignment1 = create(:assignment, name: 'Assignment 1', course_id: 1, directory_path: 'Assignment1')
        expect {create(:assignment, name: 'Assignment 2', course_id: 1,
                       directory_path: 'Assignment1')}.to raise_error(ActiveRecord::RecordInvalid)
      end
    end

Manual Rspec Testing Video Link

Team Information

1) Nicholas Viado (ndviado)

2) Akshay Podila (apodila)

Mentor: Sanket Pai (sgpai2)