CSC/ECE 517 Spring 2022 - E2201: Testing for assignment questionnaire controller.rb: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
(Created page with "== About Expertiza == [http://expertiza.ncsu.edu/ Expertiza] is the software benefits for both instructors and students by supporting various types of submissions and providi...")
 
No edit summary
Line 27: Line 27:


<pre>
<pre>
  context '#set_anonymized_view' do
context 'when no assignment is associated with the id' do
    it 'admin list_pending_requested' do
      it 'refuses certain action' do
      params = { action: 'list_pending_requested' }
        allow(Assignment).to receive(:find).and_return(nil)
      allow(controller).to receive(:params).and_return(params)
        expect(controller.send(:action_allowed?)).to be_falsey
      expect(controller.action_allowed?).to be false
       end
      stub_current_user(student7, student7.role.name, student7.role)
      allow(controller).to receive(:params).and_return(params)
      expect(controller.action_allowed?).to be false
      stub_current_user(instructor, instructor.role.name, instructor.role)
      allow(controller).to receive(:params).and_return(params)
      expect(controller.action_allowed?).to be false
      stub_current_user(admin, admin.role.name, admin.role)
      allow(controller).to receive(:params).and_return(params)
       expect(controller.action_allowed?).to be true
     end
     end
  end
</pre>


=== auto_complete_for_user_name ===
    context 'instructor is the parent of the assignment found' do
For auto_complete_for_user_name method there is another method auto_complete_result being called in the controller. This method does not exist, and thus when auto_complete_for_user_name method is called, it raises ActionView::Template::Error. In the first test case, it is being checked if the correct error is being thrown. While, in the second test case the method is being called with a GET request and is expected to redirect us to the home page.  
      it 'allows a certain action' do
<pre>
        stub_current_user(instructor1, instructor1.role.name, instructor1.role)
  context '#auto_complete_for_user_name' do
        allow(Assignment).to receive(:find).and_return(assignment)
    it 'checks if auto_complete returns actionview error' do
        allow_any_instance_of(Assignment).to receive(:instructor).and_return(instructor1)
      stub_current_user(student1, student1.role.name, student1.role)
        expect(controller.send(:action_allowed?)).to be_falsey
      session = { user: student1 }
      end
      @params = {user: student1}
    end
      allow(controller).to receive(:params).and_return(@params)
   
      expect{controller.auto_complete_for_user_name}.to raise_error(ActionView::Template::Error)
    context 'user is the ancestor of the assignment found' do
      ##Assert if the user, who is the ancestor of the instructor who created the course, is allowed to perform the action.  
      it 'allows a certain action' do
        stub_current_user(super_admin, super_admin.role.name, super_admin.role)
        allow(Assignment).to receive(:find).and_return(assignment3)
        allow_any_instance_of(Assignment).to receive(:instructor).and_return(instructor1)
        expect(controller.send(:action_allowed?)).to be_truthy
      end
     end
     end


     it 'checks if get auto_complete redirects to test host' do
     context 'course ta is allowed to perform actions on the assignment found' do
       stub_current_user(student1, student1.role.name, student1.role)
       ##Created an assignment for a course
      session = { user: student1 }
      ##Assigned a ta to that course
      @params = {user: student1}
      ##Assert if this assignment's course's ta is the same guy who signed in.
      allow(controller).to receive(:params).and_return(@params)
      it 'allows a certain action' do
      get :auto_complete_for_user_name, @params, session
        ta1 = create(:teaching_assistant, id: 25)
      expect(response).to redirect_to("http://test.host/")
        ta2 = create(:teaching_assistant, id:40, name: 'test_ta_2')
    end
        course1 = create(:course)
  end
        assignment4 = create(:assignment, course_id: course1.id, instructor_id: instructor1)
        TaMapping.create(ta_id: ta1.id, course_id: course1.id)
       
        stub_current_user(ta2, ta2.role.name, ta2.role)
        allow(Assignment).to receive(:find).and_return(assignment4)
        expect(controller.send(:action_allowed?)).to be false
      end
 
    end
</pre>
</pre>


Line 110: Line 114:
       post :destroy
       post :destroy
       expect(response).to redirect_to :action=> :list
       expect(response).to redirect_to :action=> :list
    end
  end
</pre>
=== role ===
This method is private and returns the role of the user as per their role_id. In case role_id is nil a new role with name '(none)' is created and returned. We test if this function is successfully called through the edit action even when the user's role_id is nil, or, the template is successfully rendered for edit and no error is raised.
<pre>
  context '#edit' do 
    it 'checks if role renders through edit' do
      new_student = User.new
      new_student = student1
      new_student.role_id = nil 
      allow(User).to receive(:find).with(any_args).and_return(new_student)
      get :edit
      expect(response).to render_template(:edit)
    end
    it 'checks if role fails through edit' do
      new_student = User.new
      new_student = student1
      new_student.role_id = nil 
      allow(User).to receive(:find).with(any_args).and_return(new_student)
      expect{controller.edit}.not_to raise_error
     end
     end
   end
   end

Revision as of 02:27, 22 March 2022

About Expertiza

Expertiza is the software benefits for both instructors and students by supporting various types of submissions and providing reusable objects for peer review. It is an open-source project based on Ruby on Rails framework. It allows the instructors not only to create and customize new or existing assignments but also to create a list of topics the students can sign up for. Students can form teams to work on various projects and assignments. Expertiza also lets students peer-review other students' submissions, enabling them to work together to improve others' learning experiences.

Current Project Description

This Expertiza OSS project "E2201: Testing for assignment_questionnaire_controller" is focused on adding unit tests for assignment_questionnaire_controller.rb.

Files Involved

  • assignment_questionnaire_controller.rb
  • assignment_questionnaire_controller_spec.rb

Running Tests

  rspec ./spec/controllers/assignment_questionnaire_controller_spec.rb

Testing

assignment_questionnaire_controller had 3 methods for which unit tests were missing as seen in this coverall. The RSpec unit tests added for these methods in the spec file 'assignment_questionnaire_controller_spec.rb' are discussed below.

action_allowed?

This method checks if a particular action is allowed when it is called for the current user. The action is passed in the params. In this case we are testing the action list_pending_requested. We stub a student, an instructor and an admin, and we test if only the admin has the right to perform this action.

context 'when no assignment is associated with the id' do
      it 'refuses certain action' do
        allow(Assignment).to receive(:find).and_return(nil)
        expect(controller.send(:action_allowed?)).to be_falsey
      end
    end

    context 'instructor is the parent of the assignment found' do
      it 'allows a certain action' do
        stub_current_user(instructor1, instructor1.role.name, instructor1.role)
        allow(Assignment).to receive(:find).and_return(assignment)
        allow_any_instance_of(Assignment).to receive(:instructor).and_return(instructor1)
        expect(controller.send(:action_allowed?)).to be_falsey
      end
    end
    
    context 'user is the ancestor of the assignment found' do
      ##Assert if the user, who is the ancestor of the instructor who created the course, is allowed to perform the action. 
      it 'allows a certain action' do
        stub_current_user(super_admin, super_admin.role.name, super_admin.role)
        allow(Assignment).to receive(:find).and_return(assignment3)
        allow_any_instance_of(Assignment).to receive(:instructor).and_return(instructor1)
        expect(controller.send(:action_allowed?)).to be_truthy
      end
    end

    context 'course ta is allowed to perform actions on the assignment found' do
      ##Created an assignment for a course
      ##Assigned a ta to that course
      ##Assert if this assignment's course's ta is the same guy who signed in. 
      it 'allows a certain action' do
        ta1 = create(:teaching_assistant, id: 25)
        ta2 = create(:teaching_assistant, id:40, name: 'test_ta_2')
        course1 = create(:course)
        assignment4 = create(:assignment, course_id: course1.id, instructor_id: instructor1)
        TaMapping.create(ta_id: ta1.id, course_id: course1.id)
        
        stub_current_user(ta2, ta2.role.name, ta2.role)
        allow(Assignment).to receive(:find).and_return(assignment4)
        expect(controller.send(:action_allowed?)).to be false
      end

    end

destroy

This action is called in the process of deleting a user. When this action is successfully executed or user is successfully destroyed (when User is passed a valid value 'student1') a note alert is flashed, whereas in case user is not destroyed (when User is passed an invalid value 'nil') an error is flashed. Further, it is being tested that at the end in both cases it redirects to list action.

  context '#destroy' do
    it 'check if user was successfully destroyed' do
      allow(User).to receive(:find).with(any_args).and_return(student1)
      allow(AssignmentParticipant).to receive(:delete).with(any_args).and_return(true)
      allow(TeamsUser).to receive(:delete).with(any_args).and_return(true)
      allow(AssignmentQuestionnaire).to receive(:destroy).with(any_args).and_return(true)
      allow(User).to receive(:destroy).with(any_args).and_return(true)
      post :destroy
      expect(flash[:note]).to be_present
    end

    it 'check if user was not successfully destroyed' do
      allow(User).to receive(:find).with(any_args).and_return(nil)
      allow(AssignmentParticipant).to receive(:delete).with(any_args).and_return(true)
      allow(TeamsUser).to receive(:delete).with(any_args).and_return(true)
      allow(AssignmentQuestionnaire).to receive(:destroy).with(any_args).and_return(true)
      allow(User).to receive(:destroy).with(any_args).and_return(true)
      post :destroy
      expect(flash[:error]).to be_present
    end

    it 'check if successful destroy leads to redirect' do
      allow(User).to receive(:find).with(any_args).and_return(student1)
      allow(AssignmentParticipant).to receive(:delete).with(any_args).and_return(true)
      allow(TeamsUser).to receive(:delete).with(any_args).and_return(true)
      allow(AssignmentQuestionnaire).to receive(:destroy).with(any_args).and_return(true)
      allow(User).to receive(:destroy).with(any_args).and_return(true)
      post :destroy
      expect(response).to redirect_to :action=> :list
    end

    it 'check if error during destroy leads to redirect' do
      allow(User).to receive(:find).with(any_args).and_return(nil)
      allow(AssignmentParticipant).to receive(:delete).with(any_args).and_return(true)
      allow(TeamsUser).to receive(:delete).with(any_args).and_return(true)
      allow(AssignmentQuestionnaire).to receive(:destroy).with(any_args).and_return(true)
      allow(User).to receive(:destroy).with(any_args).and_return(true)
      post :destroy
      expect(response).to redirect_to :action=> :list
    end
  end

paginate_list

This method is also private and needs to be tested through list action. The parameter paginate_options which decides the execution of statement we need to test is predefined in the paginate_list, and thus the required statement cannot be accessed or tested. So, we tested the other statements in the method.

  context '#list' do
    it 'checks that paginate_list does not fail with controller' do
      expect{controller.list}.not_to raise_error
    end

    it 'checks that paginate_list does not fail with post' do
      post :list
      expect(response.status).to eq(200)
    end
  end

Conclusion

The users_controller has been thoroughly tested in its present state. The auto_complete_result method in auto_complete_for_user_name method needs to be defined. Further, the paginate_list method needs to be refactored so that all statements in the method are accessible and may be tested.

Related Links

The main repository can be found here.

The forked git repository for this project can be found here.

A video of all tests running can be seen here.