headquarters 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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