CSC/ECE 517 Fall 2021 - E2146. Introduce a Student View for instructors: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
(→‎Expertiza: Added feature demo section)
Line 175: Line 175:


Much of the syntactic structure of this spec file was based off the impersonate_user_controller_spec.rb file, since that method and feature is rather similar to this one.
Much of the syntactic structure of this spec file was based off the impersonate_user_controller_spec.rb file, since that method and feature is rather similar to this one.
==Feature Demo==
[[Media:https://drive.google.com/file/d/1tArc7o5_mSfy8R4Yt3J9wMBDdcHUQtN_/view]]


==Conclusions and Future Work==
==Conclusions and Future Work==

Revision as of 03:29, 24 October 2021

Problem Statement

Currently, Expertiza is designed such that an instructor can view all the pages a student can, and is given access to a view very similar to that of a student. However, the difference between the navigational bar shown to an instructor and that which is shown to a student means that an instructor cannot perfectly emulate the view that a student has of Expertiza.

This makes activities such as demonstrating how to navigate around the website and access certain parts of assignments more difficult. While an instructor can choose to impersonate a student, this is cumbersome if they simply wish to view things as a student would from within their instructor account.

Additionally, certain features of the navigational bar are redundant. The main feature in question is the Assignments navigational link, which navigates to the same location as Manage... -> Assignments. Having such redundancy is confusing.

To summarize the problem, there is no easy way for an instructor to have the same view as a student at a moment's notice due to a difference between an instructor's and a student's navigational bars.

Goal of this Topic

The goal of this topic has two primary components:

  • Remove the redundant "Assignments" link in the current navigational bar
  • Add a new "Student View" link to the navigational bar. When clicked, the navigational bar changes to that of a student for the remainder of the session, with the addition of an "Instructor View" link. When that link is clicked, the navigational bar changes back to that of an instructor.

By making these changes, the unnecessary redundancy in the navigational bar is removed, and an instructor has an easy ability to demonstrate or visualize expertiza from the perspective of a student.

Specific Statement of Intent

The following is a precise, mechanical description of the intended changes.

When an instructor logs in, they should see a navigational bar with the following components: Home | Manage... | Survey Deployments | Course Evaluation | Profile | Contact Us | Student View

These are the same navigational components that an instructor can currently view, with the removal of Assignments and the addition of Student View.

If an instructor clicks on Student View, they are redirected to the home page and their navigational bar changes to the following:

Home | Assignments | Pending Surveys | Profile | Contact Us | Anonymized view | Instructor View

These are the same navigational links that a student can view, with the addition of Instructor View.

This navigational bar change should persist throughout the session, until the instructor chooses to change their view.

Implementation

To implement these changes, our theoretical framework was as follows: 1. Add a link to the navigational bar which directs to a new controller and its controller method. 2. Write a controller method which flips the value of a session flag. This session flag determines which navigational bar you see at any time. 3. Whenever the navigational bar is loaded, this flag is checked. If in the "student view" state, it renders the student view version of the instructor's navigational bar. if not, it renders the instructor's normal navigational bar (both with the addition of the link to switch to the other state).

To make this change, the following files were affected:

  • controllers/student_view_controller.rb: a controller with a single unique method, "flip_view", which flips the [:flip_user] session variable when called.
  • views/shared/_navigation.html.erb: the view which handles rendering the navigation bar. Has been edited to check the status of [:flip_user] and render a view accordingly.
  • config/role_instructor.yml: determines various aspects about those assigned the role of instructor. Only change made is the addition of the student_view and instructor_view Menu::Node objects, which are rendered in the navigation bar.
  • config/routes.rb: the routes for expertiza. Modified to allow a route to the newly made "flip_view" method.
  • spec/controllers/student_view_controller_spec.rb: A series of unit tests for the student view controller, ensuring proper functionality and permissions.

Each major change and/or will now be explained in detail.

student_view_controller.rb

This controller contains only two methods, flip_view and _action_allowed? The later is a method common to all controllers, which determines who has access to the method. This is defined for the student_view_controller such that only those with instructor privileges may use it.

The flip_view function is shown below.

  def flip_view
    if(session[:flip_user] == nil || session[:flip_user] == false) then
      session[:flip_user] = true
      redirect_to '/'
    elsif(session[:flip_user] == true) then
      session[:flip_user] = false
      redirect_to '/'
    end
  end

This relatively simple method's purpose is to flip the parity of a session variable named :flip_user between true and false, before then redirecting back to the home page. It also sets this variable to true if uninitialized, as would be the case at the beginning of a session. The route to this method is specified in the routes file as "student_view/flip_view".

_navigation.html.erb

The purpose of this variable becomes clear when we investigate _navigation.html.erb. This file is the first step in rendering the navigation menu at the top. While this process does involve other files, the determination of which menu items to render is handled here, which is the point at which student view interacts. The relevant portion of code is given below:

 ...
 <% if session[:menu] %>
   <% if !session[:flip_user] || session[:flip_user] == nil  %>
     <%= render :partial => 'menu_items/suckerfish',
            :locals => { items: session[:menu].get_menu(0) - [26, 59], level: 0 } %>
   <% elsif session[:user].role.name == 'Instructor' %>
     <% session[:menu] = Role.student.cache[:menu] %>
       <%= render :partial => 'menu_items/suckerfish',
                        :locals => { items: session[:menu].get_menu(0), level: 0 } %>
       <% session[:menu] = Role.instructor.cache[:menu] %>
       <%= render :partial => 'menu_items/suckerfish',
                        :locals => { items: session[:menu].get_menu(0) & [59], level: 0 } %>
   ...

The second line is where the [:flip_user] session variable becomes relevant. If this variable is either false or nil (set to false or uninitialized), then the standard instructor view is rendered (the 26 and 59 subtracted from "items" are removing menu items exclusive to the Student View, Assignments and Instructor View, respectively). If this condition fails (and the user is an instructor), it implies the instructor has set that variable to true. In that case, the student view menu items are found (the cache for the student menu items is pulled from Role.student.cache[:menu]) and then rendered, with the addition of the "Instructor View" button (indicated by the & [59]).

Thus, by clicking the view button, the re-rendered page gains a newly updated navigation bar, depending on the state of session[:flip_user], which will continue to persist for the entire expertiza session.

_role_instructor.yml

It is typically said that one should not edit config files lightly, and so we made sure to be careful with our changes to role_instructor.yml. However, changes were necessary, as this file is what supplies the data called in _navigation.html.erb by Role.instructor.cache[:menu]. It took a while to determine this, but the navigation menu items displayed at the top of the Expertiza view are defined under the :menu: items of this file. Each listed Menu::Node item is rendered within the navigational menu, with associated label, name, and url.

Because there was no way to know what other files or controllers may rely on this file, the only change we made was the addition of two new menu nodes: student_view and instructor_view, both with a url leading to the route for student_view_controller's flip_user method. Each was added to all three databases (development, testing, and deployment), and each was assigned a corresponding id (58 for student_view, and 59 for instructor_view). The added code can be seen below:

   ...
     58: &58 !ruby/object:Menu::Node
       content_page_id:
       controller_action_id: 58
       id: 58
       label: Student View
       name: student_view
       parent:
       parent_id:
       site_controller_id: 58
       url: "/student_view/flip_view"
     59: &59 !ruby/object:Menu::Node
       content_page_id:
       controller_action_id: 59
       id: 59
       label: Instructor View
       name: instructor_view
       parent:
       parent_id:
       site_controller_id: 59
       url: "/student_view/flip_view"
   ...

Thus, these two nodes are now loaded when the navigational bar is loaded, allowing them to appear. However, 59 is removed from the normal instructor view, and is added back in with the student view.

It's worthy to note that, currently, the Assignments menu item is manually removed from the navigation bar in _navigation.html.erb (the subtracted 26 when rendering the instructor view). While it would presumably be more clean to remove the menu node object all together, due to an abundance of caution, we decided it best not to remove any data from this config file, as again, its contents may be used by other controllers and methods we are not aware of. Future development may be able to determine if this caution is unnecessary, and make this change.

This concludes all major changes and additions. All other modifications were minor changes already referenced, and so will not be discussed in detail.

student_view_controller_spec.rb

The final noteworthy final is the unit testing spec file created for the student view controller. This spec file specifically seeks to ensure that:

  • only instructors are able to switch between student and instructor view
  • the flip user flag is worked as expected
  • navigation is occurring as expected

The code below largely matches these testing goals:

describe StudentViewController do
 let(:instructor) { build(:instructor, id: 2) }
 let(:student1) { build(:student, id: 30, name: :Amanda)}
 # student view is only accessible to instructors, so we will make one
 before(:each) do
   stub_current_user(instructor, instructor.role.name, instructor.role)
 end
 describe "check access" do
   it "instructor should be able to call flip user" do
     expect(controller.action_allowed?).to be true
   end
   it "student should not be able to call flip user" do
     stub_current_user(student1, student1.role.name, student1.role)
     expect(controller.action_allowed?).to be false
   end
 end
 describe "the student view flag working as expected" do
   it 'flag should not be initialized by default' do
     expect(session[:flip_user]).to eq nil
   end
   it 'flag should be set to true after selecting student view' do
     post :flip_view
     expect(session[:flip_user]).to eq true
   end
   it 'flag should become false after using student view twice' do
     post :flip_view
     post :flip_view
     expect(session[:flip_user]).to eq false
   end
 end
 describe "navigation should work as intended" do
   it 'should be redirected to homepage after entering student view' do
     post :flip_view
     expect(response).to redirect_to("/")
   end
   it 'should be redirected to homepage after exiting student view' do
     post :flip_view
     post :flip_view
     expect(response).to redirect_to("/")
   end
 end
end

Much of the syntactic structure of this spec file was based off the impersonate_user_controller_spec.rb file, since that method and feature is rather similar to this one.

Feature Demo

Media:https://drive.google.com/file/d/1tArc7o5_mSfy8R4Yt3J9wMBDdcHUQtN_/view

Conclusions and Future Work

We believe this feature to be working in its entirety and hope it will be a helpful tool to improve the teaching options of instructors.

If future changes were to be made to this feature, the following suggestions may be applicable:

  • A means of performing feature tests. Due to an unknown error in capybara's simplified testing view, any tests specifically looking for the Instructor View button seemed to fail. This error has not occurred on any fully rendered version of the application, nor on the Heroku-hosted server. It would be benefitial to implement tests to ensure the link appears correctly for users, but it's not clear how to do so with this issue. Finding a way to feature test would be preferrable.
  • As previously noted, if the Menu::Node objects listed in role_instructor.yml are exclusively used for rendering the navigational bar, the Assignments node object should be removed entirely, and the code where 26 is removed from the items rendered in _navigation.html.erb changed to reflect this removal.

Github

The Github corresponding to this task is publicly available here: https://github.com/Aeront39/expertiza