<NME> github_mock_helpers.rb
<BEF> # {"forks_count"=>0,
#  "language"=>"JavaScript",
#  "homepage"=>"http://www.kesiev.com/akihabara",
#  "git_url"=>"git://github.com/jasonm/akihabara.git",
#  "mirror_url"=>nil,
#  "owner"=>
#   {"login"=>"jasonm",
#    "avatar_url"=>
#     "https://secure.gravatar.com/avatar/8478f9ebe099ad853f022deeb2c1defe?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
#    "id"=>1031,
#    "url"=>"https://api.github.com/users/jasonm",
#    "gravatar_id"=>"8478f9ebe099ad853f022deeb2c1defe"},
#  "has_downloads"=>true,
#  "watchers_count"=>1,
#  "description"=>"Akihabara framework",
#  "open_issues_count"=>0,
#  "html_url"=>"https://github.com/jasonm/akihabara",
#  "created_at"=>"2012-03-18T10:11:00Z",
#  "has_wiki"=>true,
#  "has_issues"=>false,
#  "svn_url"=>"https://github.com/jasonm/akihabara",
#  "size"=>108,
#  "fork"=>true,
#  "pushed_at"=>"2012-03-18T10:11:27Z",
#  "forks"=>0,
#  "clone_url"=>"https://github.com/jasonm/akihabara.git",
#  "name"=>"akihabara",
#  "permissions"=>{"pull"=>true, "push"=>true, "admin"=>true},
#  "open_issues"=>0,
#  "watchers"=>1,
#  "ssh_url"=>"git@github.com:jasonm/akihabara.git",
#  "private"=>false,
#  "updated_at"=>"2012-03-18T10:11:28Z",
#  "full_name"=>"jasonm/akihabara",
#  "id"=>3754140,
#  "url"=>"https://api.github.com/repos/jasonm/akihabara"}

module GithubMockHelpers
  def mock_github_oauth(options={})
    options[:uid] ||= '12345'
  def set_default_github_oauth_options(options)
    options[:uid] ||= '12345'
    options[:info] ||= {}
    options[:info][:email] ||= 'jason.p.morrison@gmail.com'
    options[:info][:name] ||= 'Jason Morrison'
    options[:info][:nickname] ||= 'jasonm'
    options[:credentials] ||= {}
    options[:credentials][:token] ||= 'token-abcdef123456'
    OmniAuth.config.test_mode = true
  end

  def mock_user_repos(repo_hashes)
    Github::Repos.any_instance.stub(:list).and_return(repo_hashes)
  end
    # mock_user_repos([
    #   { "name" => "akihabara", "id" => 3754140, }
    # ])
end
    OmniAuth.config.test_mode = true
  end

  def mock_github_oauth_failure(failure_message = :access_denied)
    OmniAuth.config.mock_auth[:github] = failure_message
    OmniAuth.config.test_mode = true
  end

  def mock_github_user_repos(options={})
    assert_options(options, :oauth_token, :repos)

    json_response = options[:repos].to_json
    stub_request(:get, "https://api.github.com/user/repos?access_token=#{options[:oauth_token]}&per_page=100").to_return(status: 200, body: json_response)
  end

  def mock_github_repo_hook(options={})
    assert_options(options, :oauth_token, :user_name, :repo_name, :resulting_hook_id)

    json_response = { url: 'http://something', id: options[:resulting_hook_id] }.to_json
    stub_request(:post, "https://api.github.com/repos/#{options[:user_name]}/#{options[:repo_name]}/hooks?access_token=#{options[:oauth_token]}").
      to_return(status: 201, body: json_response)
  end

  def mock_github_set_commit_status(options={})
    assert_options(options, :user_name, :repo_name, :sha)
    options[:oauth_token] ||= oauth_token_for(options[:user_name])

    json_response = options[:json_response] || { whatever: 'yeah' }.to_json
    url = "https://api.github.com/repos/#{options[:user_name]}/#{options[:repo_name]}/statuses/#{options[:sha]}?access_token=#{options[:oauth_token]}"
    stub_request(:post, url).to_return(status: 201, body: json_response)
  end

  # TODO refactor other mocks and default oauth_token based on owner/user_name where appropriate
  def mock_github_open_pulls(options = {})
    assert_options(options, :owner, :repo, :pull_ids)
    options[:oauth_token] ||= oauth_token_for(options[:owner])

    attributes_for_open_pulls = options[:pull_ids].map { |id|
      { "number" => id }
    }

    json_response = attributes_for_open_pulls.to_json
    url = "https://api.github.com/repos/#{options[:owner]}/#{options[:repo]}/pulls?access_token=#{options[:oauth_token]}"
    stub_request(:get, url).to_return(status: 200, body: json_response)
  end

  # options[:commits] is an array of hashes,
  # each hash can contain keys :committer, :author, :sha, :url, :commit{}
  def mock_github_pull_commits(options = {})
    assert_options(options, :owner, :repo, :pull_id, :commits)
    assert_options_array(options[:commits], :author, :sha)
    options[:oauth_token] ||= oauth_token_for(options[:owner])

    json_response = options[:commits].to_json
    url = "https://api.github.com/repos/#{options[:owner]}/#{options[:repo]}/pulls/#{options[:pull_id]}/commits?access_token=#{options[:oauth_token]}"
    stub_request(:get, url).to_return(status: 200, body: json_response)
  end

  def mock_github_user_orgs(options = {})
    assert_options(options, :oauth_token, :orgs)
    assert_options_array(options[:orgs], :login)

    json_response = options[:orgs].to_json
    url = "https://api.github.com/user/orgs?access_token=#{options[:oauth_token]}"
    stub_request(:get, url).to_return(status: 200, body: json_response)
  end

  def mock_github_org_repos(options = {})
    assert_options(options, :oauth_token, :org, :repos)
    assert_options_array(options[:repos], :name, :permissions)

    json_response = options[:repos].to_json
    url = "https://api.github.com/orgs/#{options[:org]}/repos?access_token=#{options[:oauth_token]}&per_page=100"
    stub_request(:get, url).to_return(status: 200, body: json_response)
  end

  def github_uid_for_nickname(nickname)
    # consistent and unique-enough string-to-4-byte-integer mapping
    User.find_by_nickname(nickname).try(:uid) || nickname.hash.abs.to_s[0..8].to_i
  end

  def oauth_token_for(nickname)
    User.find_by_nickname(nickname).try(:oauth_token) || Digest::MD5.hexdigest(nickname)
  end

  private

  def assert_options(options, *required_keys)
    required_keys.each do |key|
      raise "must include :#{key}" unless options[key]
    end
  end

  def assert_options_array(options_array, *required_keys)
    raise "options must include array but did not" unless options_array.is_a?(Array)
    options_array.each do |options|
      assert_options(options, *required_keys)
    end
  end
end

<MSG> Show repos after OAuthing

<DFF> @@ -1,40 +1,3 @@
-# {"forks_count"=>0,
-#  "language"=>"JavaScript",
-#  "homepage"=>"http://www.kesiev.com/akihabara",
-#  "git_url"=>"git://github.com/jasonm/akihabara.git",
-#  "mirror_url"=>nil,
-#  "owner"=>
-#   {"login"=>"jasonm",
-#    "avatar_url"=>
-#     "https://secure.gravatar.com/avatar/8478f9ebe099ad853f022deeb2c1defe?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png",
-#    "id"=>1031,
-#    "url"=>"https://api.github.com/users/jasonm",
-#    "gravatar_id"=>"8478f9ebe099ad853f022deeb2c1defe"},
-#  "has_downloads"=>true,
-#  "watchers_count"=>1,
-#  "description"=>"Akihabara framework",
-#  "open_issues_count"=>0,
-#  "html_url"=>"https://github.com/jasonm/akihabara",
-#  "created_at"=>"2012-03-18T10:11:00Z",
-#  "has_wiki"=>true,
-#  "has_issues"=>false,
-#  "svn_url"=>"https://github.com/jasonm/akihabara",
-#  "size"=>108,
-#  "fork"=>true,
-#  "pushed_at"=>"2012-03-18T10:11:27Z",
-#  "forks"=>0,
-#  "clone_url"=>"https://github.com/jasonm/akihabara.git",
-#  "name"=>"akihabara",
-#  "permissions"=>{"pull"=>true, "push"=>true, "admin"=>true},
-#  "open_issues"=>0,
-#  "watchers"=>1,
-#  "ssh_url"=>"git@github.com:jasonm/akihabara.git",
-#  "private"=>false,
-#  "updated_at"=>"2012-03-18T10:11:28Z",
-#  "full_name"=>"jasonm/akihabara",
-#  "id"=>3754140,
-#  "url"=>"https://api.github.com/repos/jasonm/akihabara"}
-
 module GithubMockHelpers
   def mock_github_oauth(options={})
     options[:uid] ||= '12345'
@@ -49,10 +12,11 @@ module GithubMockHelpers
     OmniAuth.config.test_mode = true
   end
 
-  def mock_user_repos(repo_hashes)
-    Github::Repos.any_instance.stub(:list).and_return(repo_hashes)
+  def mock_user_repos(options={})
+    raise "must include :oauth_token" unless options[:oauth_token]
+    raise "must include :repos" unless options[:repos]
+
+    json_response = options[:repos].to_json
+    stub_request(:get, "https://api.github.com/user/repos?access_token=#{options[:oauth_token]}").to_return(status: 200, body: json_response)
   end
-    # mock_user_repos([
-    #   { "name" => "akihabara", "id" => 3754140, }
-    # ])
 end

Show repos after OAuthing