headquarters 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -27
  3. data/Rakefile +7 -0
  4. data/headquarters.gemspec +0 -1
  5. data/lib/headquarters.rb +6 -8
  6. data/lib/headquarters/api.rb +51 -0
  7. data/lib/headquarters/api/endpoints.rb +13 -0
  8. data/lib/headquarters/api/factory.rb +17 -0
  9. data/lib/headquarters/api/oauth_authenticator.rb +37 -0
  10. data/lib/headquarters/client.rb +13 -0
  11. data/lib/headquarters/{email.rb → client/email.rb} +8 -8
  12. data/lib/headquarters/client/github.rb +7 -0
  13. data/lib/headquarters/client/members.rb +13 -0
  14. data/lib/headquarters/rails_delivery_method.rb +35 -0
  15. data/lib/headquarters/railtie.rb +3 -4
  16. data/lib/headquarters/request.rb +7 -39
  17. data/lib/headquarters/version.rb +1 -1
  18. data/spec/headquarters/api/factory_spec.rb +19 -0
  19. data/spec/headquarters/api/oauth_authenticator_spec.rb +32 -0
  20. data/spec/headquarters/api_spec.rb +59 -0
  21. data/spec/headquarters/client/email_spec.rb +34 -0
  22. data/spec/headquarters/client/github_spec.rb +30 -0
  23. data/spec/headquarters/client/members_spec.rb +32 -0
  24. data/spec/headquarters/client_spec.rb +14 -0
  25. data/spec/{request_spec.rb → headquarters/request_spec.rb} +0 -19
  26. data/spec/headquarters_spec.rb +11 -0
  27. data/spec/shared_examples/an_http_requester.rb +39 -0
  28. data/spec/spec_helper.rb +1 -0
  29. metadata +31 -29
  30. data/lib/headquarters/email/rails_delivery_method.rb +0 -30
  31. data/lib/headquarters/endpoints.rb +0 -14
  32. data/lib/headquarters/github.rb +0 -7
  33. data/lib/headquarters/member.rb +0 -15
  34. data/spec/email_spec.rb +0 -16
  35. data/spec/github_spec.rb +0 -25
  36. data/spec/member_spec.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49835f5ea6c9c1d08010c6c6de69126d68fefd36
4
- data.tar.gz: aca257c780d85bb4efa0f57fc5e2dd87d00b93da
3
+ metadata.gz: b918932a9bf5a0d18d6b9a2d5e2e85bb4eab2b0d
4
+ data.tar.gz: f68c7ce2029733e9c2b8d3085d564b946433ea9c
5
5
  SHA512:
6
- metadata.gz: 072a81b8ec0db58856d4b88d181a2e23af5c3f90c3c1ad6b1459492e446439ba4b5145df8af9af58a026250f67aca6f0cad55b2cc8b36cfa39b1623e3b2f90b9
7
- data.tar.gz: 1c4b58be9bced8e5c845ebfd37bd1928c9a266537bf8f91d4caa68696f524f6d097d8473e701c2c6834a86bf9b58ce7d53accf5ea64a8644f5e3aefdd9371928
6
+ metadata.gz: fad10448257f1c394466d9ec23e05e3c8ec509d6c943c673b3f427f8e651438bd8365d6e4e63fdc56180f55bc0a1dab32252c07bed295030e5f09ad0a6ffdf6e
7
+ data.tar.gz: 66e149d00d1f07e555742decf3fccb247fd94eb6a83123b1854c1fa1af3aac3f1934a3475a72d809094059ef8484c30e181a234a540b792df4c937fd21b8bd74
data/README.md CHANGED
@@ -47,66 +47,64 @@ Headquarters.logger = Logger.new(STDERR)
47
47
 
48
48
  ## Usage
49
49
 
50
- These are all the available method to interact with the headquarters.
50
+ You must first instantiate a client:
51
51
 
52
- ### Members
52
+ ```ruby
53
+ client = Headquarters.new
54
+ ```
55
+
56
+ You most likely want to authenticate to use protected endpoints (such as sending emails). You can do so by passing the credentials to the constructor:
53
57
 
54
- To retrieve a collection of all members of the team you might use the `all`
55
- operation:
56
58
 
57
59
  ```ruby
58
- Headquarters::Member.all
60
+ client = Headquarters.new(client_id: 'your_client_id', client_secret: 'your_client_secret')
59
61
  ```
60
62
 
61
- Or you can search for a specific email
63
+ The main client contains namespaces that give you access to different features of Headquarters. For example, the email API can be accessed via `client.email`. If your applications needs only to send emails, and doesn't use any other features, you can instantiate an email client directly instead:
62
64
 
63
65
  ```ruby
64
- Headquarters::Member.search('mpalhas@groupbuddies.com')
66
+ email_client = Headquarters::Client::Email.new(client_id: 'your_client_id', client_secret: 'your_client_secret')
65
67
  ```
66
68
 
67
- ### Pull Requests
69
+ ### Members
68
70
 
69
- To get all (paginated) pull requests for groupbuddies, use the
70
- `pull_requests` operation:
71
+ To retrieve a collection of all members of the team you might use the `all`
72
+ operation:
71
73
 
72
74
  ```ruby
73
- Headquarters::Github.pull_requests
75
+ client.members.all
74
76
  ```
75
77
 
76
- You can filter these results using anything that github takes in the `q`
77
- parameters of its [search API](https://developer.github.com/v3/search/). For
78
- instance, if you want to get only the open pull requests, you might do:
78
+ Or you can search for a specific email
79
79
 
80
80
  ```ruby
81
- Headquarters::Github.pull_requests(query: 'is:open')
81
+ client.members.search('mpalhas@groupbuddies.com')
82
82
  ```
83
83
 
84
- ### Internal
84
+ ### Github
85
85
 
86
- There is some extra info protected with basic authentication. In order to get it
87
- you must first add the credentials to you `.env` file:
86
+ Within the `github` namespace, you can use the `pull_requests` method to get a list of all open Pull Requests in the Group Buddies organization:
88
87
 
89
- ```
90
- BASIC_AUTH_USER=some-username
91
- BASIC_AUTH_PASS=some-password
88
+ ```ruby
89
+ client.github.pull_requests
92
90
  ```
93
91
 
94
- #### Members
95
-
96
- Now you may use the `all_internal` operation:
92
+ You can filter these results using anything that github takes in the `q`
93
+ parameters of its [search API](https://developer.github.com/v3/search/). For
94
+ instance, if you want to get only the open pull requests, you might do:
97
95
 
98
96
  ```ruby
99
- Headquarters::Member.all_internal
97
+ client.github.pull_requests(query: 'is:open')
100
98
  ```
101
99
 
102
- #### Emails
100
+ ### Emails
103
101
 
104
102
  You can send emails for Group Buddies addresses (Any non-GB addresses will be filtered out).
105
103
 
106
104
  `app_name` can be set to be appended to the sender. i.e. `from: hq@groupbuddies.com, app_name: test` will become `hq+test@groupbuddies.com`. This is useful for filtering and labeling.
107
105
 
108
106
  ```ruby
109
- Headquarters::Email.send(to: 'mpalhas@groupbuddies.com,zamith@groupbuddies.com', subject: 'custom subject', body: '<b>HTML body</b>', app_name: 'hq')
107
+ client.email.deliver(to: 'mpalhas@groupbuddies.com,zamith@groupbuddies.com', subject: 'custom subject', body: '<b>HTML body</b>', app_name: 'hq')
110
108
  ```
111
109
 
112
110
  When using rails you can use headquarters as the delivery method, and transparently send emails using ActiveMailer as usual:
@@ -114,6 +112,11 @@ Headquarters::Email.send(to: 'mpalhas@groupbuddies.com,zamith@groupbuddies.com',
114
112
  ```ruby
115
113
  # config/initializers/mailer.rb
116
114
  ActionMailer::Base.delivery_method = :headquarters
115
+
116
+ Headquarters::RailsDeliveryMethod.credentials = {
117
+ client_id: 'your_client_id',
118
+ client_secret: 'your_client_secret'
119
+ }
117
120
  ```
118
121
 
119
122
  Using this method, `app_name` is also available as a header or parameter to the `mail` function
data/Rakefile CHANGED
@@ -5,3 +5,10 @@ RuboCop::RakeTask.new
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
7
  task default: [:rubocop, :spec]
8
+
9
+ task :console do
10
+ require 'pry'
11
+ require 'headquarters'
12
+ ARGV.clear
13
+ Pry.start
14
+ end
data/headquarters.gemspec CHANGED
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency 'dotenv'
22
21
  spec.add_dependency 'httparty', '>= 0.13.3'
23
22
 
24
23
  spec.add_development_dependency 'climate_control'
data/lib/headquarters.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  require 'net/https'
2
2
  require 'logger'
3
- require 'dotenv'
4
3
 
5
4
  require 'headquarters/version'
6
- require 'headquarters/endpoints'
5
+ require 'headquarters/client'
7
6
 
8
7
  if defined? ::Rails::Railtie
9
8
  require 'headquarters/railtie'
10
9
  end
11
10
 
12
11
  module Headquarters
13
- API_BASE = 'hq.groupbuddies.com'
12
+ API_BASE = 'https://hq.groupbuddies.com'
14
13
  ROOT_PATH = File.dirname(__FILE__)
15
14
 
16
15
  @api_base = API_BASE
@@ -19,12 +18,11 @@ module Headquarters
19
18
 
20
19
  class << self
21
20
  attr_accessor :api_base, :api_port, :logger
21
+
22
+ def new(*options)
23
+ Client.new(*options)
24
+ end
22
25
  end
23
26
  end
24
27
 
25
28
  require 'headquarters/request'
26
- require 'headquarters/member'
27
- require 'headquarters/github'
28
- require 'headquarters/email'
29
-
30
- Dotenv.load
@@ -0,0 +1,51 @@
1
+ require 'headquarters/api/factory'
2
+ require 'headquarters/api/oauth_authenticator'
3
+
4
+ module Headquarters
5
+ class API
6
+ def initialize(**options)
7
+ @authenticator = options[:authenticator] || OAuthAuthenticator.new(options)
8
+ end
9
+
10
+ def headers
11
+ authenticator.headers.merge(
12
+ 'Accept' => 'v2'
13
+ )
14
+ end
15
+
16
+ attr_reader :authenticator
17
+
18
+ def get(endpoint, **params)
19
+ perform_request(:get, endpoint, params)
20
+ end
21
+
22
+ def post(endpoint, **params)
23
+ perform_request(:post, endpoint, params)
24
+ end
25
+
26
+ private
27
+
28
+ def perform_request(method, endpoint, params = {})
29
+ Request.perform(method, endpoint, params_with_headers(params))
30
+ end
31
+
32
+ def params_with_headers(original_params)
33
+ params = original_params.dup
34
+ params[:headers] ||= {}
35
+ params[:headers].merge!(headers)
36
+ params
37
+ end
38
+
39
+ def self.namespace(name)
40
+ class_name = namespace_to_class_name(name)
41
+ define_method(name) do
42
+ @namespaces ||= {}
43
+ @namespaces[name] ||= API::Factory.new(class_name, authenticator: authenticator)
44
+ end
45
+ end
46
+
47
+ def self.namespace_to_class_name(name)
48
+ "#{self.name}::#{name.to_s.split('_').map(&:capitalize).join}"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,13 @@
1
+ module Headquarters
2
+ class API
3
+ module Endpoints
4
+ MEMBERS = '/members'
5
+ EMAIL = '/emails'
6
+ OAUTH_TOKEN = '/oauth/token'
7
+
8
+ module Github
9
+ PULL_REQUESTS = '/github/pull_requests'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Headquarters
2
+ class API
3
+ module Factory
4
+ def self.new(klass, **args)
5
+ classify(klass).new(**args)
6
+ end
7
+
8
+ private
9
+
10
+ def self.classify(klass)
11
+ klass.to_s.split('::').inject(Headquarters) do |constant, child_klass|
12
+ constant.const_get child_klass
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ module Headquarters
2
+ class API
3
+ class OAuthAuthenticator
4
+ def initialize(client_id: nil, client_secret: nil)
5
+ @client_id = client_id
6
+ @client_secret = client_secret
7
+ authenticate!
8
+ end
9
+
10
+ attr_reader :access_token, :client_id, :client_secret
11
+
12
+ def headers
13
+ if access_token
14
+ { 'Authorization' => "Bearer #{access_token}" }
15
+ else
16
+ {}
17
+ end
18
+ end
19
+
20
+ def authenticate!
21
+ return if client_id.nil? || client_secret.nil?
22
+
23
+ response = Request.perform(:post, Endpoints::OAUTH_TOKEN, body: authentication_body)
24
+
25
+ @access_token = Hash(response).fetch('access_token', nil)
26
+ end
27
+
28
+ def authentication_body
29
+ {
30
+ grant_type: 'client_credentials',
31
+ client_id: client_id,
32
+ client_secret: client_secret
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ require 'headquarters/api'
2
+
3
+ module Headquarters
4
+ class Client < API
5
+ namespace :members
6
+ namespace :email
7
+ namespace :github
8
+ end
9
+ end
10
+
11
+ require 'headquarters/client/members'
12
+ require 'headquarters/client/email'
13
+ require 'headquarters/client/github'
@@ -1,23 +1,23 @@
1
1
  module Headquarters
2
- class Email
2
+ class Client::Email < API
3
3
  FIELDS = %i(to from subject app_name body)
4
4
 
5
- def self.send(**raw_params)
5
+ def deliver(**raw_params)
6
6
  prepare_params(raw_params)
7
- Request.perform_with_auth(:post, Endpoints::Internal::EMAIL, params)
7
+ post Endpoints::EMAIL, body: params
8
8
  end
9
9
 
10
- class << self
11
- attr_accessor(*FIELDS)
12
- end
10
+ attr_accessor(*FIELDS)
11
+
12
+ private
13
13
 
14
- def self.params
14
+ def params
15
15
  Hash[FIELDS.map do |field|
16
16
  [field, public_send(field)]
17
17
  end.compact]
18
18
  end
19
19
 
20
- def self.prepare_params(raw_params)
20
+ def prepare_params(raw_params)
21
21
  @to = raw_params[:to]
22
22
  if @to.is_a? Array
23
23
  @to = @to.join(',')
@@ -0,0 +1,7 @@
1
+ module Headquarters
2
+ class Client::Github < API
3
+ def pull_requests(query: nil)
4
+ get Endpoints::Github::PULL_REQUESTS, query: { q: query }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'headquarters/api/endpoints'
2
+
3
+ module Headquarters
4
+ class Client::Members < API
5
+ def all
6
+ get Endpoints::MEMBERS
7
+ end
8
+
9
+ def search(query)
10
+ get Endpoints::MEMBERS, query: { q: query }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ require 'headquarters/client/email'
2
+
3
+ module Headquarters
4
+ class RailsDeliveryMethod
5
+ def initialize(**_)
6
+ end
7
+
8
+ class << self
9
+ attr_accessor :credentials
10
+ end
11
+
12
+ def deliver(mail)
13
+ params = {
14
+ from: mail.from,
15
+ to: mail.to,
16
+ subject: mail.subject,
17
+ body: mail.body.to_s,
18
+ app_name: mail.header['app_name'].to_s
19
+ }
20
+ client.deliver(params)
21
+ end
22
+
23
+ alias_method :deliver!, :deliver
24
+ alias_method :deliver_now, :deliver
25
+ alias_method :deliver_now!, :deliver
26
+ alias_method :deliver_later, :deliver
27
+ alias_method :deliver_later!, :deliver
28
+
29
+ private
30
+
31
+ def client
32
+ @client ||= Headquarters::Client::Email.new(self.class.credentials)
33
+ end
34
+ end
35
+ end
@@ -1,11 +1,10 @@
1
- require 'headquarters/email'
2
- require 'headquarters/email/rails_delivery_method'
1
+ require 'headquarters/rails_delivery_method'
3
2
 
4
3
  module Headquarters
5
- class Railtie < Rails::Railtie
4
+ class Railtie < ::Rails::Railtie
6
5
  initializer 'headquaters.add_delivery_method' do
7
6
  ActiveSupport.on_load :action_mailer do
8
- ActionMailer::Base.add_delivery_method :headquarters, Headquarters::Email::RailsDeliveryMethod
7
+ ActionMailer::Base.add_delivery_method :headquarters, Headquarters::RailsDeliveryMethod
9
8
  end
10
9
  end
11
10
  end
@@ -5,69 +5,37 @@ module Headquarters
5
5
  include ::HTTParty
6
6
  base_uri Headquarters.api_base
7
7
 
8
- def self.perform_with_auth(http_method, path, params = {}, options = {})
9
- options_with_auth = options.merge(basic_auth_info)
10
- perform(http_method, path, params, options_with_auth)
8
+ def self.perform(http_method, path, params = {})
9
+ new(path, params).public_send(http_method)
11
10
  end
12
11
 
13
- def self.perform(http_method, path, params = {}, options = {})
14
- new(path, params, options).public_send(http_method)
15
- end
16
-
17
- def initialize(path, params, options)
12
+ def initialize(path, params)
18
13
  @path = path
19
- @options = options
20
14
  @params = params
21
15
  end
22
16
 
23
17
  def get
24
- @options.merge!(query: params) if params && params.any?
25
- response = Request.get(path, options)
18
+ response = Request.get(path, params)
26
19
  log_request_info(:get, response)
27
20
  response.parsed_response
28
21
  end
29
22
 
30
23
  def post
31
- @options.merge!(body: params) if params && params.any?
32
- response = Request.post(path, options)
24
+ response = Request.post(path, params)
33
25
  log_request_info(:post, response)
34
26
  response.parsed_response
35
27
  end
36
28
 
37
29
  private
38
30
 
39
- attr_reader :path, :options, :params
31
+ attr_reader :path, :params
40
32
 
41
33
  def log_request_info(http_method, response)
42
- Headquarters.logger.info "[HQ] [#{current_time}] #{http_method.to_s.upcase} #{path} #{options} #{response.code}"
34
+ Headquarters.logger.info "[HQ] [#{current_time}] #{http_method.to_s.upcase} #{path} #{params} #{response.code}"
43
35
  end
44
36
 
45
37
  def current_time
46
38
  Time.now.utc.strftime('%d/%b/%Y %H:%M:%S %Z')
47
39
  end
48
-
49
- def self.basic_auth_info
50
- hq_basic_auth_info || deprecated_basic_auth_info
51
- end
52
-
53
- def self.hq_basic_auth_info
54
- return unless ENV['HQ_BASIC_AUTH_USER']
55
- {
56
- basic_auth: {
57
- username: ENV['HQ_BASIC_AUTH_USER'],
58
- password: ENV['HQ_BASIC_AUTH_PASS']
59
- }
60
- }
61
- end
62
-
63
- def self.deprecated_basic_auth_info
64
- warn '[DEPRECATED] Using ENV["BASIC_AUTH_USER"] is deprecated. Please use ENV["HQ_BASIC_AUTH_USER"]'
65
- {
66
- basic_auth: {
67
- username: ENV['BASIC_AUTH_USER'],
68
- password: ENV['BASIC_AUTH_PASS']
69
- }
70
- }
71
- end
72
40
  end
73
41
  end
@@ -1,3 +1,3 @@
1
1
  module Headquarters
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ module Headquarters
4
+ class API
5
+ describe Factory do
6
+ class ::Headquarters::FakeClass < API
7
+ namespace :fake_nested_class
8
+ end
9
+
10
+ context '.new' do
11
+ it 'creates an instance of the given class' do
12
+ instance = Factory.new(:FakeClass)
13
+
14
+ expect(instance.class).to eq(::Headquarters::FakeClass)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Headquarters
4
+ class API
5
+ describe OAuthAuthenticator do
6
+ context '#authenticate!' do
7
+ context 'client_id or client_secret are missing' do
8
+ it 'does nothing' do
9
+ allow(Request).to receive(:perform)
10
+
11
+ OAuthAuthenticator.new
12
+ OAuthAuthenticator.new client_id: 'id'
13
+ OAuthAuthenticator.new client_secret: 'secret'
14
+
15
+ expect(Request).not_to have_received(:perform)
16
+ end
17
+ end
18
+
19
+ context 'client_id and client_secret exist' do
20
+ it 'makes a new POST request with the correct parameters' do
21
+ allow(Request).to receive(:perform).and_return({})
22
+
23
+ credentials = { client_id: 'id', client_secret: 'secret' }
24
+ OAuthAuthenticator.new(**credentials)
25
+
26
+ expect(Request).to have_received(:perform).with(:post, Endpoints::OAUTH_TOKEN, hash_including(body: hash_including(credentials)))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/an_http_requester'
3
+
4
+ module Headquarters
5
+ describe API do
6
+ it_behaves_like 'an HTTP requester'
7
+
8
+ context '#headers' do
9
+ context 'no authentication' do
10
+ it 'includes only the API version' do
11
+ api = API.new
12
+
13
+ expect(api.headers).to eq('Accept' => 'v2')
14
+ end
15
+ end
16
+
17
+ context 'with authentication' do
18
+ let(:credentials) { { client_id: 'id', client_secret: 'secret' } }
19
+
20
+ it 'includes the API version' do
21
+ allow(Request).to receive(:perform)
22
+
23
+ api = API.new(credentials)
24
+
25
+ expect(api.headers).to match hash_including('Accept' => 'v2')
26
+ end
27
+
28
+ it 'includes authentication headers' do
29
+ expected_headers = { header: :value }
30
+ fake_authenticator = double('OAuthAuthenticator', headers: expected_headers)
31
+ allow(API::OAuthAuthenticator).to receive(:new).and_return(fake_authenticator)
32
+
33
+ api = API.new(credentials)
34
+
35
+ expect(api.headers).to match hash_including(expected_headers)
36
+ end
37
+ end
38
+ end
39
+
40
+ context '.namespace' do
41
+ class API::FakeNamespace
42
+ def initialize(**_)
43
+ end
44
+ end
45
+
46
+ it 'creates a new method' do
47
+ API.namespace(:fake_namespace)
48
+
49
+ expect(API.new.methods).to include(:fake_namespace)
50
+ end
51
+
52
+ it 'sets the return value to an instance of the expected class' do
53
+ API.namespace(:fake_namespace)
54
+
55
+ expect(API.new.fake_namespace).to be_a(API::FakeNamespace)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/an_http_requester'
3
+
4
+ module Headquarters
5
+ class Client
6
+ describe Email do
7
+ it_behaves_like 'an HTTP requester'
8
+
9
+ subject(:client) { described_class.new }
10
+
11
+ context '#deliver' do
12
+ it 'posts an email to be sent' do
13
+ allow(client).to receive(:post)
14
+ params = { subject: 'fake subject' }
15
+
16
+ client.deliver(params)
17
+
18
+ expect(client).to have_received(:post).with(Endpoints::EMAIL, body: hash_including(params))
19
+ end
20
+
21
+ context 'with multiple destinations' do
22
+ it 'comma-separates the list of emails' do
23
+ allow(client).to receive(:post)
24
+ params = { to: %w(1@email.com 2@email.com') }
25
+
26
+ client.deliver(params)
27
+
28
+ expect(client).to have_received(:post).with(Endpoints::EMAIL, body: hash_including(to: params[:to].join(',')))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/an_http_requester'
3
+
4
+ module Headquarters
5
+ class Client
6
+ describe Github do
7
+ it_behaves_like 'an HTTP requester'
8
+
9
+ subject(:client) { described_class.new }
10
+
11
+ context '#pull_requests' do
12
+ it 'asks for all the pull requests' do
13
+ allow(client).to receive(:get)
14
+
15
+ client.pull_requests
16
+
17
+ expect(client).to have_received(:get).with(Endpoints::Github::PULL_REQUESTS, query: { q: nil })
18
+ end
19
+
20
+ it 'asks for the open pull requests' do
21
+ allow(client).to receive(:get)
22
+
23
+ client.pull_requests(query: 'is:open')
24
+
25
+ expect(client).to have_received(:get).with(Endpoints::Github::PULL_REQUESTS, query: { q: 'is:open' })
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/an_http_requester'
3
+
4
+ module Headquarters
5
+ class Client
6
+ describe Members do
7
+ it_behaves_like 'an HTTP requester'
8
+
9
+ subject(:client) { described_class.new }
10
+
11
+ context '#all' do
12
+ it 'asks for all the members' do
13
+ allow(client).to receive(:get)
14
+
15
+ client.all
16
+
17
+ expect(client).to have_received(:get).with(Endpoints::MEMBERS)
18
+ end
19
+ end
20
+
21
+ context '#search' do
22
+ it 'asks for the members using an extra query param' do
23
+ allow(client).to receive(:get)
24
+
25
+ client.search('a_query')
26
+
27
+ expect(client).to have_received(:get).with(Endpoints::MEMBERS, query: { q: 'a_query' })
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'shared_examples/an_http_requester'
3
+
4
+ module Headquarters
5
+ describe Client do
6
+ it_behaves_like 'an HTTP requester'
7
+
8
+ subject(:client) { described_class.new }
9
+
10
+ it { expect(client.members).to be_a Client::Members }
11
+ it { expect(client.email).to be_a Client::Email }
12
+ it { expect(client.github).to be_a Client::Github }
13
+ end
14
+ end
@@ -33,24 +33,5 @@ module Headquarters
33
33
  expect(Request).to have_received(:get).with(url, {})
34
34
  end
35
35
  end
36
-
37
- context '.perform_with_auth' do
38
- it 'makes the actual call with basic auth' do
39
- url = '/some-url'
40
- credentials = { basic_auth: { username: 'user', password: 'pass' } }
41
- new_env = {
42
- BASIC_AUTH_PASS: credentials[:basic_auth][:password],
43
- BASIC_AUTH_USER: credentials[:basic_auth][:username]
44
- }
45
- stub_request(:get, 'user:pass@' + Headquarters.api_base + url)
46
- allow(Request).to receive(:get).and_call_original
47
-
48
- with_modified_env new_env do
49
- Request.perform_with_auth(:get, url)
50
-
51
- expect(Request).to have_received(:get).with(url, credentials)
52
- end
53
- end
54
- end
55
36
  end
56
37
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Headquarters do
4
+ context '.new' do
5
+ it 'instantiates a new client' do
6
+ expect(Headquarters::Client).to receive(:new)
7
+
8
+ Headquarters.new
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ RSpec.shared_examples 'an HTTP requester' do
2
+ let(:client) { described_class.new }
3
+
4
+ context '#get' do
5
+ it 'makes a GET request to the correct endpoint' do
6
+ allow(client).to receive(:perform_request)
7
+
8
+ client.get :fake_endpoint
9
+
10
+ expect(client).to have_received(:perform_request).with(:get, :fake_endpoint, {})
11
+ end
12
+
13
+ it 'accepts optional arguments' do
14
+ allow(client).to receive(:perform_request)
15
+
16
+ client.get :fake_endpoint, arg: :value
17
+
18
+ expect(client).to have_received(:perform_request).with(:get, :fake_endpoint, arg: :value)
19
+ end
20
+ end
21
+
22
+ context '#post' do
23
+ it 'makes a POST request' do
24
+ allow(client).to receive(:perform_request)
25
+
26
+ client.post :fake_endpoint
27
+
28
+ expect(client).to have_received(:perform_request).with(:post, :fake_endpoint, {})
29
+ end
30
+
31
+ it 'accepts optional arguments' do
32
+ allow(client).to receive(:perform_request)
33
+
34
+ client.post :fake_endpoint, arg: :value
35
+
36
+ expect(client).to have_received(:perform_request).with(:post, :fake_endpoint, arg: :value)
37
+ end
38
+ end
39
+ end
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ require 'headquarters'
2
2
  require 'climate_control'
3
3
 
4
4
  Dir[File.join(Headquarters::ROOT_PATH, 'spec/support/**/*.rb')].each { |f| require f }
5
+ Dir[File.join(Headquarters::ROOT_PATH, 'spec/shared_examples/**/*.rb')].each { |f| require f }
5
6
 
6
7
  class DummyLogger
7
8
  def self.info(_message); end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: headquarters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Palhas
@@ -9,22 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-15 00:00:00.000000000 Z
12
+ date: 2015-02-06 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: dotenv
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: '0'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: httparty
30
16
  requirement: !ruby/object:Gem::Requirement
@@ -125,18 +111,28 @@ files:
125
111
  - Rakefile
126
112
  - headquarters.gemspec
127
113
  - lib/headquarters.rb
128
- - lib/headquarters/email.rb
129
- - lib/headquarters/email/rails_delivery_method.rb
130
- - lib/headquarters/endpoints.rb
131
- - lib/headquarters/github.rb
132
- - lib/headquarters/member.rb
114
+ - lib/headquarters/api.rb
115
+ - lib/headquarters/api/endpoints.rb
116
+ - lib/headquarters/api/factory.rb
117
+ - lib/headquarters/api/oauth_authenticator.rb
118
+ - lib/headquarters/client.rb
119
+ - lib/headquarters/client/email.rb
120
+ - lib/headquarters/client/github.rb
121
+ - lib/headquarters/client/members.rb
122
+ - lib/headquarters/rails_delivery_method.rb
133
123
  - lib/headquarters/railtie.rb
134
124
  - lib/headquarters/request.rb
135
125
  - lib/headquarters/version.rb
136
- - spec/email_spec.rb
137
- - spec/github_spec.rb
138
- - spec/member_spec.rb
139
- - spec/request_spec.rb
126
+ - spec/headquarters/api/factory_spec.rb
127
+ - spec/headquarters/api/oauth_authenticator_spec.rb
128
+ - spec/headquarters/api_spec.rb
129
+ - spec/headquarters/client/email_spec.rb
130
+ - spec/headquarters/client/github_spec.rb
131
+ - spec/headquarters/client/members_spec.rb
132
+ - spec/headquarters/client_spec.rb
133
+ - spec/headquarters/request_spec.rb
134
+ - spec/headquarters_spec.rb
135
+ - spec/shared_examples/an_http_requester.rb
140
136
  - spec/spec_helper.rb
141
137
  homepage: https://github.com/groupbuddies/headquarters-ruby
142
138
  licenses:
@@ -163,8 +159,14 @@ signing_key:
163
159
  specification_version: 4
164
160
  summary: Ruby wrapper for the headquarters API for Group Buddies
165
161
  test_files:
166
- - spec/email_spec.rb
167
- - spec/github_spec.rb
168
- - spec/member_spec.rb
169
- - spec/request_spec.rb
162
+ - spec/headquarters/api/factory_spec.rb
163
+ - spec/headquarters/api/oauth_authenticator_spec.rb
164
+ - spec/headquarters/api_spec.rb
165
+ - spec/headquarters/client/email_spec.rb
166
+ - spec/headquarters/client/github_spec.rb
167
+ - spec/headquarters/client/members_spec.rb
168
+ - spec/headquarters/client_spec.rb
169
+ - spec/headquarters/request_spec.rb
170
+ - spec/headquarters_spec.rb
171
+ - spec/shared_examples/an_http_requester.rb
170
172
  - spec/spec_helper.rb
@@ -1,30 +0,0 @@
1
- require 'headquarters/email'
2
-
3
- module Headquarters
4
- class Email
5
- class RailsDeliveryMethod
6
- attr_accessor :options
7
-
8
- def initialize(options = {})
9
- self.options = options
10
- end
11
-
12
- def deliver(mail)
13
- params = {
14
- from: mail.from,
15
- to: mail.to,
16
- subject: mail.subject,
17
- body: mail.body.to_s,
18
- app_name: mail.header['app_name'].to_s
19
- }
20
- Headquarters::Email.send(params)
21
- end
22
-
23
- alias_method :deliver!, :deliver
24
- alias_method :deliver_now, :deliver
25
- alias_method :deliver_now!, :deliver
26
- alias_method :deliver_later, :deliver
27
- alias_method :deliver_later!, :deliver
28
- end
29
- end
30
- end
@@ -1,14 +0,0 @@
1
- module Headquarters
2
- module Endpoints
3
- MEMBERS = '/members'
4
-
5
- module Github
6
- PULL_REQUESTS = '/github/pull_requests'
7
- end
8
-
9
- module Internal
10
- MEMBERS = '/internal/members'
11
- EMAIL = '/internal/emails'
12
- end
13
- end
14
- end
@@ -1,7 +0,0 @@
1
- module Headquarters
2
- class Github
3
- def self.pull_requests(query: nil)
4
- Request.perform(:get, Endpoints::Github::PULL_REQUESTS, query: { q: query })
5
- end
6
- end
7
- end
@@ -1,15 +0,0 @@
1
- module Headquarters
2
- class Member
3
- def self.all
4
- Request.perform(:get, Endpoints::MEMBERS)
5
- end
6
-
7
- def self.search(query)
8
- Request.perform(:get, Endpoints::MEMBERS, q: query)
9
- end
10
-
11
- def self.all_internal
12
- Request.perform_with_auth(:get, Endpoints::Internal::MEMBERS)
13
- end
14
- end
15
- end
data/spec/email_spec.rb DELETED
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Headquarters
4
- describe Email do
5
- context '.send' do
6
- it 'makes a new POST request using the correct API endpoint' do
7
- allow(Request).to receive(:perform_with_auth)
8
- params = { subject: 'fake subject' }
9
-
10
- Email.send(params)
11
-
12
- expect(Request).to have_received(:perform_with_auth).with(:post, Endpoints::Internal::EMAIL, hash_including(params))
13
- end
14
- end
15
- end
16
- end
data/spec/github_spec.rb DELETED
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Headquarters
4
- describe Github do
5
- context '.pull_requests' do
6
- it 'asks for all the pull requests' do
7
- allow(Request).to receive(:perform)
8
-
9
- Github.pull_requests
10
-
11
- expect(Request).to have_received(:perform).
12
- with(:get, Endpoints::Github::PULL_REQUESTS, query: { q: nil })
13
- end
14
-
15
- it 'asks for the open pull requests' do
16
- allow(Request).to receive(:perform)
17
-
18
- Github.pull_requests(query: 'is:open')
19
-
20
- expect(Request).to have_received(:perform).
21
- with(:get, Endpoints::Github::PULL_REQUESTS, query: { q: 'is:open' })
22
- end
23
- end
24
- end
25
- end
data/spec/member_spec.rb DELETED
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Headquarters
4
- describe Member do
5
- context '.all' do
6
- it 'makes a new GET request using the correct API endpoint' do
7
- allow(Request).to receive(:perform)
8
-
9
- Member.all
10
-
11
- expect(Request).to have_received(:perform).with(:get, Endpoints::MEMBERS)
12
- end
13
- end
14
-
15
- context '.all_internal' do
16
- it 'makes a new GET request using the correct API endpoint' do
17
- allow(Request).to receive(:perform_with_auth)
18
-
19
- Member.all_internal
20
-
21
- expect(Request).to have_received(:perform_with_auth).with(:get, Endpoints::Internal::MEMBERS)
22
- end
23
- end
24
- end
25
- end