bitbucket_rest_api2 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +7 -0
  3. data/README.md +169 -0
  4. data/lib/bitbucket_rest_api.rb +90 -0
  5. data/lib/bitbucket_rest_api/api.rb +106 -0
  6. data/lib/bitbucket_rest_api/api/actions.rb +35 -0
  7. data/lib/bitbucket_rest_api/api_factory.rb +30 -0
  8. data/lib/bitbucket_rest_api/authorization.rb +34 -0
  9. data/lib/bitbucket_rest_api/client.rb +56 -0
  10. data/lib/bitbucket_rest_api/configuration.rb +106 -0
  11. data/lib/bitbucket_rest_api/connection.rb +98 -0
  12. data/lib/bitbucket_rest_api/constants.rb +58 -0
  13. data/lib/bitbucket_rest_api/core_ext/array.rb +7 -0
  14. data/lib/bitbucket_rest_api/core_ext/hash.rb +46 -0
  15. data/lib/bitbucket_rest_api/deprecation.rb +39 -0
  16. data/lib/bitbucket_rest_api/error.rb +38 -0
  17. data/lib/bitbucket_rest_api/error/bad_events.rb +9 -0
  18. data/lib/bitbucket_rest_api/error/bad_request.rb +12 -0
  19. data/lib/bitbucket_rest_api/error/blank_value.rb +9 -0
  20. data/lib/bitbucket_rest_api/error/client_error.rb +20 -0
  21. data/lib/bitbucket_rest_api/error/forbidden.rb +12 -0
  22. data/lib/bitbucket_rest_api/error/internal_server_error.rb +12 -0
  23. data/lib/bitbucket_rest_api/error/invalid_options.rb +18 -0
  24. data/lib/bitbucket_rest_api/error/no_events.rb +9 -0
  25. data/lib/bitbucket_rest_api/error/not_found.rb +12 -0
  26. data/lib/bitbucket_rest_api/error/required_params.rb +18 -0
  27. data/lib/bitbucket_rest_api/error/service_error.rb +19 -0
  28. data/lib/bitbucket_rest_api/error/service_unavailable.rb +12 -0
  29. data/lib/bitbucket_rest_api/error/unauthorized.rb +12 -0
  30. data/lib/bitbucket_rest_api/error/unknown_value.rb +18 -0
  31. data/lib/bitbucket_rest_api/error/unprocessable_entity.rb +12 -0
  32. data/lib/bitbucket_rest_api/error/validations.rb +18 -0
  33. data/lib/bitbucket_rest_api/invitations.rb +15 -0
  34. data/lib/bitbucket_rest_api/issues.rb +230 -0
  35. data/lib/bitbucket_rest_api/issues/comments.rb +118 -0
  36. data/lib/bitbucket_rest_api/issues/components.rb +106 -0
  37. data/lib/bitbucket_rest_api/issues/milestones.rb +107 -0
  38. data/lib/bitbucket_rest_api/normalizer.rb +27 -0
  39. data/lib/bitbucket_rest_api/parameter_filter.rb +32 -0
  40. data/lib/bitbucket_rest_api/repos.rb +264 -0
  41. data/lib/bitbucket_rest_api/repos/changesets.rb +54 -0
  42. data/lib/bitbucket_rest_api/repos/commits.rb +40 -0
  43. data/lib/bitbucket_rest_api/repos/default_reviewers.rb +59 -0
  44. data/lib/bitbucket_rest_api/repos/download.rb +21 -0
  45. data/lib/bitbucket_rest_api/repos/following.rb +39 -0
  46. data/lib/bitbucket_rest_api/repos/forks.rb +69 -0
  47. data/lib/bitbucket_rest_api/repos/keys.rb +87 -0
  48. data/lib/bitbucket_rest_api/repos/pull_request.rb +160 -0
  49. data/lib/bitbucket_rest_api/repos/services.rb +103 -0
  50. data/lib/bitbucket_rest_api/repos/sources.rb +39 -0
  51. data/lib/bitbucket_rest_api/repos/webhooks.rb +96 -0
  52. data/lib/bitbucket_rest_api/request.rb +76 -0
  53. data/lib/bitbucket_rest_api/request/basic_auth.rb +31 -0
  54. data/lib/bitbucket_rest_api/request/jsonize.rb +46 -0
  55. data/lib/bitbucket_rest_api/request/oauth.rb +53 -0
  56. data/lib/bitbucket_rest_api/response.rb +28 -0
  57. data/lib/bitbucket_rest_api/response/helpers.rb +21 -0
  58. data/lib/bitbucket_rest_api/response/jsonize.rb +30 -0
  59. data/lib/bitbucket_rest_api/response/mashify.rb +24 -0
  60. data/lib/bitbucket_rest_api/response/raise_error.rb +31 -0
  61. data/lib/bitbucket_rest_api/response/xmlize.rb +26 -0
  62. data/lib/bitbucket_rest_api/result.rb +140 -0
  63. data/lib/bitbucket_rest_api/user.rb +101 -0
  64. data/lib/bitbucket_rest_api/users.rb +24 -0
  65. data/lib/bitbucket_rest_api/users/account.rb +53 -0
  66. data/lib/bitbucket_rest_api/utils/url.rb +56 -0
  67. data/lib/bitbucket_rest_api/validations.rb +25 -0
  68. data/lib/bitbucket_rest_api/validations/format.rb +24 -0
  69. data/lib/bitbucket_rest_api/validations/presence.rb +25 -0
  70. data/lib/bitbucket_rest_api/validations/required.rb +44 -0
  71. data/lib/bitbucket_rest_api/validations/token.rb +43 -0
  72. data/lib/bitbucket_rest_api/version.rb +11 -0
  73. data/spec/bitbucket_rest_api/api/actions_spec.rb +17 -0
  74. data/spec/bitbucket_rest_api/api_factory_spec.rb +30 -0
  75. data/spec/bitbucket_rest_api/api_spec.rb +86 -0
  76. data/spec/bitbucket_rest_api/authorization_spec.rb +72 -0
  77. data/spec/bitbucket_rest_api/client_spec.rb +15 -0
  78. data/spec/bitbucket_rest_api/core_ext/array_spec.rb +12 -0
  79. data/spec/bitbucket_rest_api/core_ext/hash_spec.rb +49 -0
  80. data/spec/bitbucket_rest_api/deprecation_spec.rb +30 -0
  81. data/spec/bitbucket_rest_api/error/bad_events_spec.rb +10 -0
  82. data/spec/bitbucket_rest_api/error/blank_value_spec.rb +13 -0
  83. data/spec/bitbucket_rest_api/error/no_events_spec.rb +10 -0
  84. data/spec/bitbucket_rest_api/invitations_spec.rb +21 -0
  85. data/spec/bitbucket_rest_api/issues/comments_spec.rb +89 -0
  86. data/spec/bitbucket_rest_api/issues/components_spec.rb +88 -0
  87. data/spec/bitbucket_rest_api/issues/milestones_spec.rb +88 -0
  88. data/spec/bitbucket_rest_api/issues_spec.rb +90 -0
  89. data/spec/bitbucket_rest_api/normalizer_spec.rb +30 -0
  90. data/spec/bitbucket_rest_api/parameter_filter_spec.rb +41 -0
  91. data/spec/bitbucket_rest_api/repos/changesets_spec.rb +43 -0
  92. data/spec/bitbucket_rest_api/repos/commits_spec.rb +20 -0
  93. data/spec/bitbucket_rest_api/repos/default_reviewers_spec.rb +64 -0
  94. data/spec/bitbucket_rest_api/repos/download_spec.rb +9 -0
  95. data/spec/bitbucket_rest_api/repos/following_spec.rb +52 -0
  96. data/spec/bitbucket_rest_api/repos/forks_spec.rb +45 -0
  97. data/spec/bitbucket_rest_api/repos/keys_spec.rb +72 -0
  98. data/spec/bitbucket_rest_api/repos/pull_request_spec.rb +288 -0
  99. data/spec/bitbucket_rest_api/repos/sources_spec.rb +77 -0
  100. data/spec/bitbucket_rest_api/repos/webhooks_spec.rb +245 -0
  101. data/spec/bitbucket_rest_api/repos_spec.rb +157 -0
  102. data/spec/bitbucket_rest_api/request/jsonize_spec.rb +18 -0
  103. data/spec/bitbucket_rest_api/request/oauth_spec.rb +27 -0
  104. data/spec/bitbucket_rest_api/request_spec.rb +81 -0
  105. data/spec/bitbucket_rest_api/response/jsonize_spec.rb +12 -0
  106. data/spec/bitbucket_rest_api/response/mashify_spec.rb +32 -0
  107. data/spec/bitbucket_rest_api/response/raise_error_spec.rb +41 -0
  108. data/spec/bitbucket_rest_api/user_spec.rb +77 -0
  109. data/spec/bitbucket_rest_api/utils/url_spec.rb +33 -0
  110. data/spec/bitbucket_rest_api/validations/format_spec.rb +29 -0
  111. data/spec/bitbucket_rest_api/validations/presence_spec.rb +12 -0
  112. data/spec/bitbucket_rest_api/validations/required_spec.rb +43 -0
  113. data/spec/bitbucket_rest_api/validations/token_spec.rb +16 -0
  114. data/spec/bitbucket_rest_api_spec.rb +17 -0
  115. data/spec/spec_helper.rb +24 -0
  116. metadata +373 -0
@@ -0,0 +1,56 @@
1
+ require 'cgi'
2
+
3
+ module BitBucket
4
+ module Utils
5
+ module Url
6
+ extend self
7
+
8
+ DEFAULT_QUERY_SEP = /[&;] */n
9
+
10
+ KEY_VALUE_SEP = '='.freeze
11
+
12
+ def escape(s) CGI.escape s.to_s end
13
+
14
+ def unescape(s) CGI.unescape s.to_s end
15
+
16
+ def build_query(params)
17
+ params.map { |k, v|
18
+ if v.class == Array
19
+ build_query(v.map { |x| [k, x] })
20
+ else
21
+ v.nil? ? escape(k) : "#{escape(k)}=#{escape(v)}"
22
+ end
23
+ }.join("&")
24
+ end
25
+
26
+ def parse_query(query_string)
27
+ return '' if query_string.nil? || query_string.empty?
28
+ params = {}
29
+
30
+ query_string.split(DEFAULT_QUERY_SEP).each do |part|
31
+ k, v = part.split(KEY_VALUE_SEP, 2).map { |el| unescape(el) }
32
+
33
+ if cur = params[k]
34
+ if cur.class == Array
35
+ params[k] << v
36
+ else
37
+ params[k] = [cur, v]
38
+ end
39
+ else
40
+ params[k] = v
41
+ end
42
+ end
43
+ params
44
+ end
45
+
46
+ def parse_query_for_param(query_string, name)
47
+ parse_query(query_string).each do |key, val|
48
+ return val.first if (name == key) && val.is_a?(Array)
49
+ return val if (name == key)
50
+ end
51
+ return nil
52
+ end
53
+
54
+ end # Url
55
+ end # Utils
56
+ end # BitBucket
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Validations
5
+ extend AutoloadHelper
6
+
7
+ autoload_all 'bitbucket_rest_api/validations',
8
+ :Presence => 'presence',
9
+ :Token => 'token',
10
+ :Format => 'format',
11
+ :Required => 'required'
12
+
13
+ include Presence
14
+ include Format
15
+ include Token
16
+ include Required
17
+
18
+ VALID_API_KEYS = [
19
+ 'page',
20
+ 'per_page',
21
+ 'jsonp_callback'
22
+ ]
23
+
24
+ end # Validation
25
+ end # BitBucket
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Validations
5
+ module Format
6
+
7
+ # Ensures that value for a given key is of the correct form whether
8
+ # matching regular expression or set of predefined values.
9
+ #
10
+ def assert_valid_values(permitted, params)
11
+ params.each do |k, v|
12
+ next unless permitted.keys.include?(k)
13
+ if permitted[k].is_a?(Array) && !permitted[k].include?(params[k])
14
+ raise BitBucket::Error::UnknownValue.new(k,v, permitted[k].join(', '))
15
+
16
+ elsif permitted[k].is_a?(Regexp) && !(permitted[k] =~ params[k])
17
+ raise BitBucket::Error::UnknownValue.new(k,v, permitted[k])
18
+ end
19
+ end
20
+ end
21
+
22
+ end # Format
23
+ end # Validations
24
+ end # BitBucket
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Validations
5
+ module Presence
6
+
7
+ # Ensures that essential arguments are present before request is made
8
+ #
9
+ def _validate_presence_of(*params)
10
+ params.each do |param|
11
+ raise ArgumentError, "parameter cannot be nil" if param.nil?
12
+ end
13
+ end
14
+
15
+
16
+ # Check if user or repository parameters are passed
17
+ #
18
+ def _validate_user_repo_params(user_name, repo_name)
19
+ raise ArgumentError, "[user] parameter cannot be nil" if user_name.nil?
20
+ raise ArgumentError, "[repo] parameter cannot be nil" if repo_name.nil?
21
+ end
22
+
23
+ end # Presence
24
+ end # Validations
25
+ end # BitBucket
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module Validations
5
+ module Required
6
+
7
+ # Validate all keys present in a provided hash against required set,
8
+ # on mismatch raise BitBucket::Error::RequiredParams
9
+ # Note that keys need to be in the same format i.e. symbols or strings,
10
+ # otherwise the comparison will fail.
11
+ #
12
+ def assert_required_keys(required, provided)
13
+ result = required.all? do |key|
14
+ provided.has_deep_key? key
15
+ end
16
+ if !result
17
+ raise BitBucket::Error::RequiredParams.new(provided, required)
18
+ end
19
+ result
20
+ end
21
+
22
+ # Validate that required values are not blank
23
+ # the *required are colon separated strings
24
+ # e.g. 'source:branch:name' tests value of params[:source][:branch][:name]
25
+ #
26
+ def assert_required_values_present(params, *required)
27
+ required.each do |encoded_string|
28
+ keys = parse_values(encoded_string)
29
+ value = keys.inject(params) { |params, key| params[key] }
30
+ if value.is_a?(String)
31
+ if value.empty?
32
+ raise BitBucket::Error::BlankValue.new(encoded_string)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def parse_values(string)
39
+ string.split(':')
40
+ end
41
+
42
+ end # Required
43
+ end # Validations
44
+ end # BitBucket
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ # TODO: Set token required calls
4
+
5
+ module BitBucket
6
+ module Validations
7
+ module Token
8
+
9
+ TOKEN_REQUIRED = [
10
+ 'get /user',
11
+ 'get /user/emails',
12
+ 'get /user/followers',
13
+ 'get /user/following',
14
+ 'get /user/keys',
15
+ 'get /user/repos',
16
+ 'patch /user',
17
+ 'post /user/emails',
18
+ 'post /user/keys',
19
+ 'post /user/repos'
20
+ ]
21
+
22
+ TOKEN_REQUIRED_REGEXP = [
23
+ /repos\/.*\/.*\/comments/,
24
+ ]
25
+
26
+ # Ensures that required authentication token is present before
27
+ # request is sent.
28
+ #
29
+ def validates_token_for(method, path)
30
+ return true unless TOKEN_REQUIRED.grep("#{method} #{path}").empty?
31
+
32
+ token_required = false
33
+ TOKEN_REQUIRED_REGEXP.each do |regex|
34
+ if "#{method} #{path}" =~ regex
35
+ token_required = true
36
+ end
37
+ end
38
+ return token_required
39
+ end
40
+
41
+ end # Token
42
+ end # Validations
43
+ end # BitBucket
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module BitBucket
4
+ module VERSION
5
+ MAJOR = 0
6
+ MINOR = 2
7
+ PATCH = 0
8
+
9
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
10
+ end
11
+ end # BitBucket
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe BitBucket::API, '#actions' do
4
+ let(:api) { BitBucket::Repos::Keys }
5
+
6
+ context 'when class' do
7
+ it "lists all available actions for an api" do
8
+ expect(api.actions).to match_array([:actions, :all, :create, :delete, :edit, :list])
9
+ end
10
+ end
11
+
12
+ context 'when instance' do
13
+ it "lists all available actions for an api" do
14
+ expect(api.new.actions).to match_array([:actions, :all, :create, :delete, :edit, :list])
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe BitBucket::ApiFactory do
6
+
7
+ subject(:factory) { described_class }
8
+
9
+ context '#new' do
10
+ it 'throws error if klass type is ommitted' do
11
+ expect { factory.new nil }.to raise_error(ArgumentError)
12
+ end
13
+
14
+ it 'instantiates a new object' do
15
+ expect(factory.new('Issues')).to be_a BitBucket::Issues
16
+ end
17
+ end
18
+
19
+ context '#create_instance' do
20
+ it 'creates class instance' do
21
+ expect(factory.create_instance('User', {})).to be_kind_of(BitBucket::User)
22
+ end
23
+ end
24
+
25
+ context '#convert_to_constant' do
26
+ it 'knows how to convert nested classes' do
27
+ expect(factory.convert_to_constant('Repos::Changesets')).to eql(BitBucket::Repos::Changesets)
28
+ end
29
+ end
30
+ end # BitBucket::ApiFactory
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe BitBucket::API do
4
+ let(:setup_options) { { user: 'test_user' } }
5
+ let(:bitbucket_api) { described_class.new(setup_options) }
6
+ after do
7
+ [:user, :login, :password].each do |key|
8
+ bitbucket_api.send "clear_#{key}".to_sym
9
+ end
10
+ end
11
+
12
+ describe '#new' do
13
+ it 'passes options to bitbucket' do
14
+ described_class.new(setup_options)
15
+
16
+ expect(bitbucket_api.user).to eq(setup_options[:user])
17
+ end
18
+
19
+ context 'valid options' do
20
+ it 'sets valid options' do
21
+ setup_options = {
22
+ login: 'johnwick',
23
+ password: 'password'
24
+ }
25
+ bitbucket_api = described_class.new(setup_options)
26
+
27
+ expect(bitbucket_api.login).to eq('johnwick')
28
+ expect(bitbucket_api.password).to eq('password')
29
+ end
30
+
31
+ it 'ignores invalid options' do
32
+ setup_options = {
33
+ invalid_option: 'invalid option'
34
+ }
35
+
36
+ bitbucket_api = described_class.new(setup_options)
37
+
38
+ expect{ bitbucket_api.invalid_option }.to raise_error(NoMethodError)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '#method_missing' do
44
+ let(:setup_options) { { user: 'test_user' } }
45
+
46
+ it 'responds to attribute query' do
47
+ expect(bitbucket_api.user?).to eq(true)
48
+ end
49
+
50
+ it 'clears the attributes' do
51
+ bitbucket_api.clear_user
52
+
53
+ expect(bitbucket_api.user).to be_nil
54
+ end
55
+ end
56
+
57
+ describe '#_update_user_repo_params' do
58
+ it 'sets the username and repo_name' do
59
+ bitbucket_api._update_user_repo_params('test_user1', 'test_repo')
60
+
61
+ expect(bitbucket_api.user).to eq('test_user1')
62
+ expect(bitbucket_api.repo).to eq('test_repo')
63
+ end
64
+ end
65
+
66
+ describe '#_merge_user_into_params!' do
67
+ let(:params) { {} }
68
+
69
+ it 'takes a hash and merges user into it' do
70
+ bitbucket_api._merge_user_into_params!(params)
71
+
72
+ expect(params).to include('user')
73
+ end
74
+ end
75
+
76
+ describe '#_merge_user_repo_into_params!' do
77
+ let(:params) { {} }
78
+
79
+ it 'takes a hash and merges user into it' do
80
+ new_params = bitbucket_api._merge_user_repo_into_params!(params)
81
+
82
+ expect(new_params).to include('user')
83
+ expect(new_params).to include('repo')
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe BitBucket::Authorization do
4
+ let(:oauth_api) { BitBucket::API.new(oauth_token: 'example_oauth_token') }
5
+ let(:basic_auth_api) { BitBucket::API.new(basic_auth: 'example_login:example_password') }
6
+ let(:basic_auth_api_hash) do
7
+ BitBucket::API.new(
8
+ basic_auth: { login: 'example_login', password: 'example_password' })
9
+ end
10
+ let(:login_and_password_api) do
11
+ BitBucket::API.new(
12
+ login: 'example_login',
13
+ password: 'example_password',
14
+ basic_auth: nil
15
+ )
16
+ end
17
+
18
+ describe '#authenticated?' do
19
+ context 'oauth authentication' do
20
+ it 'should return true if oauth is used' do
21
+ expect(oauth_api.authenticated?).to eq(true)
22
+ end
23
+ end
24
+
25
+ context 'basic authentication' do
26
+ it 'should return true if basic authentication is used' do
27
+ expect(basic_auth_api.authenticated?).to eq(true)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#basic_authed?' do
33
+ context 'with basic_auth' do
34
+ it 'should return true if basic_auth is set' do
35
+ expect(basic_auth_api.basic_authed?).to eq(true)
36
+ expect(basic_auth_api_hash.basic_authed?).to eq(true)
37
+ end
38
+ end
39
+
40
+ context 'with login and password' do
41
+ it 'should return true if a login and password are set' do
42
+ expect(login_and_password_api.basic_authed?).to eq(true)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#authentication' do
48
+ context 'with basic_auth as a string' do
49
+ it 'should return a hash containing the value for :basic_auth' do
50
+ expectation = { basic_auth: 'example_login:example_password' }
51
+
52
+ expect(basic_auth_api.authentication).to eq(expectation)
53
+ end
54
+ end
55
+
56
+ context 'with basic_auth as a hash' do
57
+ it 'should return a hash containing the value for :basic_auth' do
58
+ expectation = { basic_auth: { login: 'example_login', password: 'example_password'} }
59
+
60
+ expect(basic_auth_api_hash.authentication).to eq(expectation)
61
+ end
62
+ end
63
+
64
+ context 'with login and password' do
65
+ it 'should return a hash containing values for :login and :password' do
66
+ expectation = { login: 'example_login', password: 'example_password' }
67
+
68
+ expect(login_and_password_api.authentication).to eq(expectation)
69
+ end
70
+ end
71
+ end
72
+ end