diff options
| author | mo khan <mo@mokhan.ca> | 2021-12-21 09:53:49 -0700 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2021-12-21 09:53:49 -0700 |
| commit | 752ec386ab387a76f60b2571d43c42faf71e2e29 (patch) | |
| tree | 979c097bb7c20cc2e3eeae925cb46d0db7ccee61 | |
| parent | 846d7e7e2090d18eeef97ef9320a0857c58e8ab8 (diff) | |
refactor: provide points as dependency
| -rw-r--r-- | github_score.rb | 100 |
1 files changed, 49 insertions, 51 deletions
diff --git a/github_score.rb b/github_score.rb index c7e8ff5..23e8238 100644 --- a/github_score.rb +++ b/github_score.rb @@ -4,87 +4,85 @@ require 'net/http' require 'uri' require 'json' require 'rspec/autorun' +require 'webmock/rspec' + +class UserNotFound < ArgumentError +end class GithubScore - def initialize(handle) + DEFAULT_POINTS = { + "IssuesEvent" => 1, + "IssueCommentEvent" => 2, + "PushEvent" => 3, + "PullRequestReviewCommentEvent" => 4, + "WatchEvent" => 5, + "CreateEvent" => 6 + }.freeze + + def initialize(handle, points: DEFAULT_POINTS) @handle = handle + @points = points end def score - events = get_events - get_score(events) + calculate_score_for(events) end + private + + attr_reader :points, :handle + def build_url - "https://api.github.com/users/#{@handle}/events/public" + "https://api.github.com/users/#{handle}/events/public" end - def get_events - begin - response = get_user_events - response_body = JSON.parse(response.body) - if response_body.is_a? Array - return response_body - elsif response_body.key?("message") - raise Exception.new response_body["message"] - else - raise Exception.new "Unknown error" - end - rescue Exception => e - puts "Request failed with #{e.message}" - rescue Timeout::Error => e - puts "Request timed out" - end + def events + response = Net::HTTP.get_response(URI.parse(build_url)) + raise UserNotFound.new(handle) if response.code == "404" + + JSON.parse(response.body) end - def get_score(events) - grouped = events.group_by{|h| h["type"]}.values + def calculate_score_for(events) + grouped = events.group_by { |h| h["type"] }.values score = grouped.map { |g| event_type = g.first["type"].strip - event_score = scoring_params[event_type] || 1 + event_score = points[event_type] || 1 event_score * g.count }.sum score end - - def get_user_events - uri = URI.parse(build_url) - response = Net::HTTP.get_response(uri) - response - end - - def scoring_params - scoring_params = { - "IssuesEvent" => 1, - "IssueCommentEvent" => 2, - "PushEvent" => 3, - "PullRequestReviewCommentEvent" => 4, - "WatchEvent" => 5, - "CreateEvent" => 6 - } - end end RSpec.describe GithubScore do describe "#score" do - context "when ?" do - subject(:github_score) { GithubScore.new("tenderlove") } + subject(:github_score) { GithubScore.new(handle) } + let(:handle) { "tenderlove" } + + context "when calculating the score for a known user" do + let(:events) { [{type: 'PushEvent'}, {type: 'IssuesEvent'}] } before do - response = Net::HTTPResponse.new(1, 2, 3) - response.instance_variable_set(:@read, true) - response.body = [ - {type: 'PushEvent'}, - {type: 'IssuesEvent'}, - ].to_json + stub_request(:get, "https://api.github.com/users/#{handle}/events/public") + .to_return(status: 200, body: events.to_json) end - it 'computes a score' do - allow(github_score).to receive(:get_user_events).and_return(response) + it { expect(github_score.score).to eq(4) } + end - expect(github_score.score).to eq(13) + context "when attempting to retrive the score for an unknown user" do + before do + stub_request(:get, "https://api.github.com/users/#{handle}/events/public") + .to_return(status: 404, body: { + "message": "Not Found", + "documentation_url": "https://docs.github.com/rest/reference/activity#list-public-events-for-a-user" + }.to_json) end + + it { expect { github_score.score }.to raise_error(UserNotFound) } end + + # it times out end end |
