CSC/ECE 517 Fall 2021 - E2149. Finish Github metrics integration - Reputations: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 42: Line 42:


1. We edited expertiza\app\views\assignments\edit\_general.html.erb and added a checkbox. The codes are as follow.
1. We edited expertiza\app\views\assignments\edit\_general.html.erb and added a checkbox. The codes are as follow.
If the id of the assignment exists, there will be a checkbox for the user to use github metrics.
If the id of the assignment exists, there will be a checkbox for the user to use github metrics. The UseGithubMetricsController.exist use the self function in the controller.  


   <!--Github-->
   <!--Github-->
Line 67: Line 67:
   <% end %>
   <% end %>
  <% end %>
  <% end %>
3.
jQuery(document).ready(function () {
        // This function determines whether the 'Topics' tab must be displayed when the page is re-loaded
        var checkbox = jQuery('#assignment_has_topics');
        if (checkbox.is(':checked')) {
            // If this checkbox is checked, show the 'Topics' tab
            jQuery("#topics_tab_header").show();
        } else {
            // Otherwise, hide topics tab
            jQuery("#topics_tab_header").hide();
        }
        $('#use_github').change(function () {
            if (jQuery('#use_github').is(':checked')) {
                jQuery.ajax({
                    url: '/use_github_metrics/' + <%= @assignment.id %>,
                    method: 'POST',
                    xhrFields: {
                        withCredentials: true
                    },
                    dataType: 'json'
                })
            } else{
                jQuery.ajax({
                    url: '/use_github_metrics/' + <%= @assignment.id %>,
                    method: 'DELETE',
                    xhrFields: {
                        withCredentials: true
                    },
                    dataType: 'json'
                })
            }
        })
    });


==== Controller Modification ====
==== Controller Modification ====

Revision as of 22:43, 30 November 2021

Abstract

Expertiza provides teammate reviews to measure how much each team member contributed. It also augments this data with Github data of each group’s submitted repo link to help differentiate the performance of team members for grading purposes and predict which projects are likely to be merged. Instructors would like to compile this Github repository statistics on a per-project, per-team basis, and integrate the display of these data within Expertiza. The project team will troubleshoot existing code and add new features.

Problem Statement

The functionality of the showing GitHub metrics cannot be turned off, meaning that an instructor who uses Expertiza for writing assignments in an English course would get a Github metrics report. There needs to be a way to turn the report off for a particular assignment. The project doesn't report lines added and deleted because of the lack of support from the current API. It adds quite a lot of lines of code for a single project and some codes could be refactored. The test plans of the current project are not described thoroughly enough. We will modify the existing RSpec test code and add some new tests.

Methodology

The team has synced the revised 2021 Spring project E2111 code with the current status of the Expertiza/beta branch and has begun analyzing the existing code. Prior customer feedback has advised the team to address inextensibility/coupling issues, documentation issues, and synchronization issues. We are performing our own end-to-end analysis of the code in addition to this feedback, and have found numerous action items so far. We have separated these action items into Primary and Secondary objectives: Primary objectives are "must-haves" that need to be addressed before the existing code is mergeable. Secondary objectives are "nice-to-haves" or features that are either left out of the original project or will make the integration display more integrated.

Team Action Items

Adding turn on and turn down option

The functionality of the current project cannot be turned off. We will provide an option for instructors not to query Github metrics data before they post the assignment, which is the way we turn the GitHub report off for a particular assignment.

Database Modification

In order to determine whether the GitHub report of the assignment is turned on or turned off, we need to create a new table named "use_github_metric" to save the id of the assignment whose GitHub metric is turned on. We also have an alternative solution to add a boolean field in the assignment table, but due to security concerns, we give it up. We think we should not change the data of the assignment.

Table: use_github_metric

id(PK) Assignment_id(FK)
1 1
2 15


Simplify the Codes

Extract the repeating part of codes and then construct an independent method based on them. Finally, we could use this method.

The last edition uses the lots of Google API to help generate the chart, we can use the method from helper to generate charts instead.

Frontend Modification

If a user chooses not to include the GitHub metric in the assignment (the functionality is turned off), the icon named "Login to Query of Github data" should not be displayed on the frontend page.

1. We edited expertiza\app\views\assignments\edit\_general.html.erb and added a checkbox. The codes are as follow. If the id of the assignment exists, there will be a checkbox for the user to use github metrics. The UseGithubMetricsController.exist use the self function in the controller.

     <input type="checkbox" name = "use_github" id="use_github" <%= "checked" 
            if UseGithubMetricsController.exist(@assignment_form.assignment.id) %>></input>
     <%= label_tag('use_github', 'Use github metrics?') %>

2. The expertiza\app\views\assignments\list_submissions.html.erb is edited too. If the id of the assignment exists and github_access_token is null (it means that the user hasn't logged in), then the page will show 'Login to Query Github data' button. If github_access_token is not null, it would show 'Refresh Github data' button because the user has logged in. <%if UseGithubMetricsController.exist(@assignment.id) %> <% if session["github_access_token"].nil? %> <% topic_identifier, topic_name, users_for_curr_team, participants = get_data_for_list_submissions(@teams.first) %> <%= link_to 'Login to Query Github data', { controller: 'metrics', action: 'show', id: participants.first.id } %> <% else %> <%= link_to 'Refresh Github data', { controller: 'metrics', action: 'query_assignment_statistics', id: @assignment.id}, :onclick => "showLoadIcon()"%> <img id="load_icon" src="<%= image_url('ajax-loader.gif') %>" style="display:none"> <% end %> <% end %> 3. jQuery(document).ready(function () { // This function determines whether the 'Topics' tab must be displayed when the page is re-loaded var checkbox = jQuery('#assignment_has_topics'); if (checkbox.is(':checked')) { // If this checkbox is checked, show the 'Topics' tab jQuery("#topics_tab_header").show(); } else { // Otherwise, hide topics tab jQuery("#topics_tab_header").hide(); } $('#use_github').change(function () { if (jQuery('#use_github').is(':checked')) { jQuery.ajax({ url: '/use_github_metrics/' + <%= @assignment.id %>, method: 'POST', xhrFields: { withCredentials: true }, dataType: 'json' }) } else{ jQuery.ajax({ url: '/use_github_metrics/' + <%= @assignment.id %>, method: 'DELETE', xhrFields: { withCredentials: true }, dataType: 'json' }) } }) });

Controller Modification

We added a function in expertiza\app\controllers\use_github_metrics_controller.rb as follwowing.

Self Functions

1. Check if assignment_id exists in the table use_github_metrics. If so, return TRUE.

#check if assignment_id exists in the table use_github_metrics
 def self.exist(assignment_id)
   use_github = UseGithubMetric.find_by(assignment_id: assignment_id)
   !use_github.nil?
 end

2. If assignment_id does not exist in the table use_github_metrics, save it.

 #if assignment_id does not exist in the table use_github_metrics, save it
 def self.save(assignment_id)
   unless exist(assignment_id)
     use_github = UseGithubMetric.new(assignment_id)
     use_github.assignment_id = assignment_id
     use_github.save
   end
 end

3. If assignment_id exists in the table use_github_metrics, delete it

 #if assignment_id exists in the table use_github_metrics, delete it
 def self.delete(assignment_id)
   if exist(assignment_id)
     use_github = UseGithubMetric.find_by(assignment_id: assignment_id)
     use_github.destroy
   end
 end
Not Self Functions

1. Return TRUE if the assignment id exists.

 #check if assignment_id exists in the table use_github_metrics
 def exist
   assignment_id = params[:assignment_id]
   UseGithubMetricsController.exist(assignment_id)
 end

2. Save assignment is if it doesn't exist. This function is for the frontend page to select the checkbox.

 #if assignment_id does not exist in the table use_github_metrics, save it
 def save
   assignment_id = params[:assignment_id]
   UseGithubMetricsController.save(assignment_id)
   respond_to do |format|
     format.json { render json: assignment_id }
   end
 end

3. Delete assignment id if it exists. This function is for the frontend page to cancel the checkbox.

 #if assignment_id exists in the table use_github_metrics, delete it
 def delete
   assignment_id = params[:assignment_id]
   UseGithubMetricsController.delete(assignment_id)
   respond_to do |format|
     format.json { render json: assignment_id }
   end
 end

Testing

See the details in Test Plan.

Functionality Walk Through

Assignment edit page view

An instructor can customize an assignment in this view. We will provide an option for instructors to decide whether they need Github metrics in the assignment or not.

Before we modified this part, this page is as follows:

After modifying it, this page is:

List Submissions View: with Github metrics option

This is how a user will view List Submissions when they choose Github metrics in the previous assignment edit page and is not authenticated to Github yet. The Login link redirects to an omniauth login page, which redirects back to this page.


List Submissions View: without Github metrics option

This is how a user will view List Submissions when they did not choose Github metrics in the previous assignment edit page. The Login link for querying Github data would not be provided to the instructors if they don't choose the "use GitHub metric" option.

Final Design UML

This UML shows the new classes and models we created and implemented in our final project. Besides these, we also modified some of the existing classes and methods, we will give more detailed information later.

OminiAuth Github API update

GitHub no longer supports authentication through query parameters. Thus, we move the authentication to the header. From September 8, 2021, using access_token as a query parameter to access the API (as a user or as a GitHub App) and using client_id/client_secret to make OAuth app unauthenticated are disabled.



GitHub's OAuth implementation


 #Use Oauth protocols to attempt to authorize user for either google or github
 def oauth_login
   case params[:provider]
   when "github"
     github_login
   when "google_oauth2"
     google_login
   when "github2021" # due to github 0
     custom_github_login
   else
     ExpertizaLogger.error LoggerMessage.new(controller_name, user.name, "Invalid OAuth Provider", "")
   end
 end


After requesting the user's GitHub identity, the user will be redirected back to Expertiza by GitHub. If the user accepts the request, GitHub redirects back to expertiza with a temporary code in a code parameter and the state provided in the previous step in a state parameter. The client_id and client_secret are required as they received from GitHub for Expertiza. The code is also required as it would be a response to the request. Then the access token allows Expertiza to make requests to the API on a behalf of a user.

 #Login functionality for Github to get access_token
 def custom_github_login
   session_code = request.env['rack.request.query_hash']['code']
   result = RestClient.post('https://github.com/login/oauth/access_token',
                              {:client_id => GITHUB_CONFIG['client_key'],
                               :client_secret => GITHUB_CONFIG['client_secret'],
                               :code => session_code},
                               :accept => :json)
   access_token = JSON.parse(result)['access_token']
   session["github_access_token"] = access_token
   redirect_to controller: 'assignments', action: 'list_submissions', id: session["assignment_id"]
 end

Test Plan

UI Testing

Our UI tests aim to capture the following core pieces of functionality:

Turn on and turn down functionality button:

In order to test the functionality manually, we follow the following steps:

1. Log in to Expertiza as an instructor
2. Navigate to assignments through Manage
3. Show a turn on/turn down option for Github metric on the page
4. Process the page without choosing Github metrics report for a particular assignment
5. The page should not display "Login to Query of Github data" options.


Rspec

Detailed of Github Testing

After changing the way of calling the GitHub API, we need to test whether we can get the data from the GitHub API correctly.

describe '#gets data from GitHub api v4(graphql)' do
end
describe '#get_github_repository_details' do
end
describe '#get_statuses_for_pull_request' do
end

Resources

Key Links

Github API Documentation

Deprecating API authentication through query parameters

Previous Project References

Original E1858 Documentation

E1983 Revision Documentation

E2111 Project Refactoring