upland_mobile_commons_rest 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 619f5d766058d364354c1c3209ac651a8b34428b893a9688242bb731cc518d03
4
- data.tar.gz: c2484081c525f961a7604d6b43d1135de04f8a64dbbc4562ea64b5dcff9f6abe
3
+ metadata.gz: 89896717de9faa37dde046fd38ba2fcc8023517cb108a5ae87a69d5673ec6b73
4
+ data.tar.gz: f5764a8149f4097644a8b8a2b99d5d859e246835913239185428c7e7ca0aa51c
5
5
  SHA512:
6
- metadata.gz: 2f8d99f3d0ae8c47d2610d33a5b0b3f03a223a544d055843074cd83370076c0b808bd24dfd1c6bb433040b384144c86f1f16c247a63fef5b7616a1571f87d3a2
7
- data.tar.gz: 6a48dea9cd8e1986f0eada1f54b05fd6b3e02de71024158a79633134fda6e2df45ad097a07c33b0db21f697a1af3107ebc46b8dad1a2315b9c7fc6f0d49bd7d7
6
+ metadata.gz: 7a860c84c083cc39619e4098d9b6f140f882dbb1015e9d7fb15ff3bc735987a323a9d682953fb00a86faf39237feb623dffb80509396afeeae8a7358e996c401
7
+ data.tar.gz: dd7452bb682e7ac71bd96c17b985d26ff7e39210aab3375f0ef61767227746fbf16daa9ed402f47a82d4fe8fcf6232cf124a1deabba1f85922c3457924ee47f4
@@ -0,0 +1,24 @@
1
+ name: CI
2
+ on: [push]
3
+
4
+ jobs:
5
+ test:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v2
9
+ - uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
10
+ with:
11
+ ruby-version: 2.7
12
+ bundler-cache: true
13
+ - run: bundle install
14
+ - run: bundle exec rspec
15
+ rubocop:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
20
+ with:
21
+ ruby-version: 2.7
22
+ bundler-cache: true
23
+ - run: bundle install
24
+ - run: bundle exec rubocop
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ upland_mobile_commons_rest
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.4
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
  # Add dependencies required to use your gem here.
3
5
  # Example:
4
6
  # gem "activesupport", ">= 2.3.5"
@@ -8,14 +10,14 @@ gem 'vertebrae'
8
10
  # Add dependencies to develop your gem here.
9
11
  # Include everything needed to run rake, tests, features, etc.
10
12
  group :development do
11
- gem "shoulda", ">= 0"
12
- gem "rdoc", "> 3.12"
13
- gem "bundler", "> 2.0"
14
- gem "juwelier", git: 'https://github.com/flajann2/juwelier.git'
15
- gem "simplecov", ">= 0"
16
- gem "dotenv"
17
- gem "byebug"
18
- gem "rubocop"
19
- gem "rspec"
20
- gem "webmock"
13
+ gem 'bundler', '> 2.0'
14
+ gem 'byebug'
15
+ gem 'dotenv'
16
+ gem 'juwelier', git: 'https://github.com/flajann2/juwelier.git'
17
+ gem 'rdoc', '> 3.12'
18
+ gem 'rspec'
19
+ gem 'rubocop'
20
+ gem 'shoulda', '>= 0'
21
+ gem 'simplecov', '>= 0'
22
+ gem 'webmock'
21
23
  end
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Upland Mobile Commons Ruby Gem
2
- [![Build Status](https://travis-ci.org/controlshift/upland_mobile_commons_rest.svg?branch=master)](https://travis-ci.org/controlshift/upland_mobile_commons_rest)
2
+ [![CI Status](https://github.com/controlshift/upland_mobile_commons_rest/actions/workflows/ci.yml/badge.svg)](https://github.com/controlshift/upland_mobile_commons_rest/actions/workflows/ci.yml)
3
3
 
4
4
  A ruby gem for interacting with the Upland Mobile Commons API.
5
5
 
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'rubygems'
@@ -6,42 +5,40 @@ require 'bundler'
6
5
  begin
7
6
  Bundler.setup(:default, :development)
8
7
  rescue Bundler::BundlerError => e
9
- $stderr.puts e.message
10
- $stderr.puts "Run `bundle install` to install missing gems"
8
+ warn e.message
9
+ warn 'Run `bundle install` to install missing gems'
11
10
  exit e.status_code
12
11
  end
13
12
  require 'rake'
14
13
  require 'juwelier'
15
14
  Juwelier::Tasks.new do |gem|
16
15
  # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
- gem.name = "upland_mobile_commons_rest"
18
- gem.homepage = "http://github.com/controlshift/upland_mobile_commons_rest"
19
- gem.license = "MIT"
20
- gem.summary = %Q{API client gem for Upland Mobile Commons}
21
- gem.description = %Q{A simple ruby API client gem for the Upland Mobile Commons REST API}
22
- gem.email = "nathan@controlshiftlabs.com"
23
- gem.authors = ["Nathan Woodhull"]
16
+ gem.name = 'upland_mobile_commons_rest'
17
+ gem.homepage = 'http://github.com/controlshift/upland_mobile_commons_rest'
18
+ gem.license = 'MIT'
19
+ gem.summary = %(API client gem for Upland Mobile Commons)
20
+ gem.description = %(A simple ruby API client gem for the Upland Mobile Commons REST API)
21
+ gem.email = 'team@controlshiftlabs.com'
22
+ gem.authors = ['Kathy Lu', 'Diego Marcet', 'Grey Moore', 'Nathan Woodhull']
24
23
 
25
24
  # dependencies defined in Gemfile
26
25
  end
27
26
  Juwelier::RubygemsDotOrgTasks.new
28
27
 
29
- desc "Code coverage detail"
28
+ desc 'Code coverage detail'
30
29
  task :simplecov do
31
- ENV['COVERAGE'] = "true"
30
+ ENV['COVERAGE'] = 'true'
32
31
  Rake::Task['test'].execute
33
32
  end
34
33
 
35
-
36
34
  require 'rspec/core/rake_task'
37
35
  RSpec::Core::RakeTask.new(:spec)
38
36
 
39
-
40
- task :default => :spec
37
+ task default: :spec
41
38
 
42
39
  require 'rdoc/task'
43
40
  Rake::RDocTask.new do |rdoc|
44
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
45
42
 
46
43
  rdoc.rdoc_dir = 'rdoc'
47
44
  rdoc.title = "upland_mobile_commons_rest #{version}"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
data/example.rb CHANGED
@@ -1,4 +1,5 @@
1
-
1
+ # frozen_string_literal: true
2
+
2
3
  $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
3
4
 
4
5
  require 'upland_mobile_commons_rest'
@@ -7,9 +8,9 @@ require 'byebug'
7
8
 
8
9
  Dotenv.load('.env')
9
10
 
10
- client = UplandMobileCommonsRest.new(username: ENV['USERNAME'], password: ENV['PASSWORD'] ) # rubocop:disable Lint/UselessAssignment
11
+ client = UplandMobileCommonsRest.new(username: ENV['USERNAME'], password: ENV['PASSWORD']) # rubocop:disable Lint/UselessAssignment
11
12
 
12
13
  puts "Ready to call MobileCommons API using 'client' object"
13
14
  byebug # rubocop:disable Lint/Debugger
14
15
 
15
- puts "Bye!"
16
+ puts 'Bye!'
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UplandMobileCommonsRest
2
4
  class Base < Vertebrae::Model
3
5
  def url_escape(string)
4
6
  CGI.escape(string.to_s)
5
7
  end
6
-
7
8
  end
8
9
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UplandMobileCommonsRest
2
4
  class Campaigns < Base
3
-
4
5
  def base_path
5
6
  'campaigns'
6
7
  end
@@ -4,7 +4,7 @@ module UplandMobileCommonsRest
4
4
  class Client < Vertebrae::API
5
5
  attr_accessor :username, :password, :company_key
6
6
 
7
- def initialize(options={}, &block)
7
+ def initialize(options = {}, &block)
8
8
  self.username = options[:username]
9
9
  self.password = options[:password]
10
10
  self.company_key = options[:company_key]
@@ -25,15 +25,19 @@ module UplandMobileCommonsRest
25
25
 
26
26
  def setup
27
27
  connection.stack do |builder|
28
+ # Request middlewares, in the order they should run
28
29
  builder.use Faraday::Request::Multipart
29
30
  builder.use Faraday::Request::UrlEncoded
30
31
  if connection.configuration.authenticated?
31
- builder.use Faraday::Request::BasicAuthentication, connection.configuration.username, connection.configuration.password
32
+ builder.use Faraday::Request::BasicAuthentication, connection.configuration.username,
33
+ connection.configuration.password
32
34
  end
33
35
 
36
+ # Response middlewares, in the *reverse* order they should run
34
37
  builder.use UplandMobileCommonsRest::TypedErrorMiddleware
35
38
  builder.use Faraday::Response::Logger if ENV['DEBUG']
36
39
  builder.use FaradayMiddleware::ParseXml
40
+ builder.use UplandMobileCommonsRest::HttpErrorMiddleware
37
41
 
38
42
  builder.adapter connection.configuration.adapter
39
43
  end
@@ -1,47 +1,129 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UplandMobileCommonsRest
4
+ class NetworkError < StandardError
5
+ attr_accessor :status, :body
6
+
7
+ def initialize(params)
8
+ self.status = params[:status]
9
+ self.body = params[:body]
10
+
11
+ # Including the parentheses means we call #super with no arguments,
12
+ # rather than passing params along. We do this to avoid the params being
13
+ # treated as the "message" of the exception.
14
+ super()
15
+ end
16
+
17
+ def to_s
18
+ "#{super}\n status: #{status}\n body: #{body}"
19
+ end
20
+ end
21
+
22
+ class BadGatewayError < NetworkError; end
23
+ class GatewayTimeoutError < NetworkError; end
24
+
25
+ # This middleware runs *before* XML parsing, so we can include the raw response body in the exception.
26
+ class HttpErrorMiddleware < Faraday::Response::Middleware
27
+ def on_complete(response)
28
+ status_code = response[:status].to_i
29
+
30
+ # Raise an exception for 5xx errors.
31
+ # Q: Shouldn't we also raise for 4xx errors?
32
+ # A: We let TypedErrorMiddleware handle those, in case they have useful info.
33
+ case status_code
34
+ when 502
35
+ raise BadGatewayError.new(response)
36
+ when 504
37
+ raise GatewayTimeoutError.new(response)
38
+ when 500...600
39
+ # Just in case we get other 5xx errors, raise something for those
40
+ # This has not happened that we know of, but better safe than sorry!
41
+ raise UnknownError, response.inspect
42
+ end
43
+ end
44
+ end
45
+
2
46
  class MobileCommonsError < StandardError
3
47
  attr_accessor :code, :raw_message
4
48
  end
5
49
 
6
50
  class UnknownError < MobileCommonsError; end
51
+
7
52
  class InvalidCampaignId < MobileCommonsError; end
53
+
8
54
  class InvalidBroadcastTime < MobileCommonsError; end
55
+
9
56
  class InvalidMessageBody < MobileCommonsError; end
57
+
10
58
  class InvalidCompanyId < MobileCommonsError; end
59
+
11
60
  class InvalidPhoneNumber < MobileCommonsError; end
61
+
12
62
  class InvalidGroupId < MobileCommonsError; end
63
+
13
64
  class InvalidStartTime < MobileCommonsError; end
65
+
14
66
  class InvalidEndTime < MobileCommonsError; end
67
+
15
68
  class InvalidMdataId < MobileCommonsError; end
69
+
16
70
  class InvalidKey < MobileCommonsError; end
71
+
17
72
  class PhoneIsNotOptedIntoThisCampaign < MobileCommonsError; end
73
+
18
74
  class InvalidFundraisingId < MobileCommonsError; end
75
+
19
76
  class InvalidMessageTemplate < MobileCommonsError; end
77
+
20
78
  class PhoneIsNotTextable < MobileCommonsError; end
79
+
21
80
  class InvalidMconnectId < MobileCommonsError; end
81
+
22
82
  class InvalidQueryParameters < MobileCommonsError; end
83
+
23
84
  class TooManyMessages < MobileCommonsError; end
85
+
24
86
  class InvalidName < MobileCommonsError; end
87
+
25
88
  class InvalidOptInPath < MobileCommonsError; end
89
+
26
90
  class InvalidUrl < MobileCommonsError; end
91
+
27
92
  class InvalidAttachment < MobileCommonsError; end
93
+
28
94
  class InvalidBroadcastId < MobileCommonsError; end
95
+
29
96
  class InvalidBroadcastStateChange < MobileCommonsError; end
97
+
30
98
  class BroadcastHasNotBeenSent < MobileCommonsError; end
99
+
31
100
  class MessageTemplateInvalid < MobileCommonsError; end
101
+
32
102
  class InvalidUserId < MobileCommonsError; end
103
+
33
104
  class APIRateLimitExceeded < MobileCommonsError; end
105
+
34
106
  class MissingPhoneNumberParameter < MobileCommonsError; end
107
+
35
108
  class InvalidProfileSaveItemBehavior < MobileCommonsError; end
109
+
36
110
  class InvalidProfileAttributes < MobileCommonsError; end
111
+
37
112
  class InvalidPreviousId < MobileCommonsError; end
113
+
38
114
  class InvalidTagName < MobileCommonsError; end
115
+
39
116
  class InvalidTagParameters < MobileCommonsError; end
117
+
40
118
  class InvalidShortcodeId < MobileCommonsError; end
119
+
41
120
  class InvalidDateRange < MobileCommonsError; end
121
+
42
122
  class InvalidScheduledMessageId < MobileCommonsError; end
123
+
43
124
  class MessageHasAlreadyBeenSent < MobileCommonsError; end
44
125
 
126
+ # This middleware runs *after* XML parsing, because it uses information extracted from the body
45
127
  class TypedErrorMiddleware < Faraday::Response::Middleware
46
128
  POSSIBLE_ERRORS = {
47
129
  '0' => UnknownError,
@@ -82,17 +164,15 @@ module UplandMobileCommonsRest
82
164
  '35' => InvalidDateRange,
83
165
  '36' => InvalidScheduledMessageId,
84
166
  '37' => MessageHasAlreadyBeenSent
85
- }
167
+ }.freeze
86
168
 
87
169
  def on_complete(response)
88
170
  # First ensure responses without the expected format are correctly handled
89
- if response.body.nil? || response.body['response'].nil?
90
- raise UnknownError.new(response.inspect)
91
- end
171
+ raise UnknownError, response.inspect if response.body.nil? || response.body['response'].nil?
92
172
 
93
173
  # Now verify that response was successful or raise a corresponding exception otherwise
94
174
  if response.body['response']['success'] == 'false'
95
- raise POSSIBLE_ERRORS[response.body['response']['error']['id']].new(response.body['response']['error']['message'])
175
+ raise POSSIBLE_ERRORS[response.body['response']['error']['id']], response.body['response']['error']['message']
96
176
  end
97
177
  end
98
178
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UplandMobileCommonsRest
2
4
  class Groups < Base
3
-
4
5
  def base_path
5
6
  'groups'
6
7
  end
@@ -8,18 +9,12 @@ module UplandMobileCommonsRest
8
9
  def list(page: nil, limit: nil)
9
10
  params = []
10
11
 
11
- if page
12
- params << "page=#{url_escape(page)}"
13
- end
12
+ params << "page=#{url_escape(page)}" if page
14
13
 
15
- if limit
16
- params << "limit=#{url_escape(limit)}"
17
- end
14
+ params << "limit=#{url_escape(limit)}" if limit
18
15
 
19
16
  request_path = base_path
20
- if params.any?
21
- request_path += "?#{params.join('&')}"
22
- end
17
+ request_path += "?#{params.join('&')}" if params.any?
23
18
 
24
19
  resp = client.get_request(request_path)
25
20
  resp.body['response']['groups']['group']
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UplandMobileCommonsRest
2
4
  class Profiles < Base
3
5
  def base_path
@@ -17,4 +17,4 @@ require 'upland_mobile_commons_rest/base'
17
17
  require 'upland_mobile_commons_rest/campaigns'
18
18
  require 'upland_mobile_commons_rest/groups'
19
19
  require 'upland_mobile_commons_rest/profiles'
20
- require 'upland_mobile_commons_rest/errors'
20
+ require 'upland_mobile_commons_rest/errors'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe UplandMobileCommonsRest::Campaigns do
@@ -26,4 +28,4 @@ describe UplandMobileCommonsRest::Campaigns do
26
28
  end
27
29
  end
28
30
  end
29
- end
31
+ end
data/spec/client_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe UplandMobileCommonsRest::Client do
@@ -15,4 +17,110 @@ describe UplandMobileCommonsRest::Client do
15
17
  expect(campaigns.client).to eq(subject)
16
18
  end
17
19
  end
20
+
21
+ describe 'error handling' do
22
+ let(:request_params) { {example: 'data'} }
23
+
24
+ subject { UplandMobileCommonsRest::Client.new(username: 'foo', password: 'bar') }
25
+
26
+ before :each do
27
+ stub_request(:post, 'https://secure.mcommons.com/api/do_something')
28
+ .to_return(status: response_status, body: response_body)
29
+ end
30
+
31
+ shared_examples_for 'error code parsing' do
32
+ UplandMobileCommonsRest::TypedErrorMiddleware::POSSIBLE_ERRORS.each do |code, ex_type|
33
+ context "response body with success=false and error code #{code}" do
34
+ let(:response_body) do
35
+ <<~XML
36
+ <response success="false">
37
+ <error id="#{code}" message="This is not correct!"/>
38
+ </response>
39
+ XML
40
+ end
41
+
42
+ it "should raise #{ex_type}" do
43
+ expect{ subject.post_request('do_something', request_params) }.to raise_error(ex_type)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ context '200 status response' do
50
+ let(:response_status) { 200 }
51
+
52
+ context 'no response body' do
53
+ let(:response_body) { nil }
54
+
55
+ it 'should raise an UnknownError' do
56
+ expect{ subject.post_request('do_something', request_params) }.to raise_error(UplandMobileCommonsRest::UnknownError)
57
+ end
58
+ end
59
+
60
+ context 'response body without <response> tag' do
61
+ let(:response_body) { '<body>Well, this is unexpected!</body>' }
62
+
63
+ it 'should raise an UnknownError' do
64
+ expect{ subject.post_request('do_something', request_params) }.to raise_error(UplandMobileCommonsRest::UnknownError)
65
+ end
66
+ end
67
+
68
+ context 'response body with success=true' do
69
+ let(:response_body) { '<response success="true">hurray!</response>' }
70
+
71
+ it 'should not raise' do
72
+ expect{ subject.post_request('do_something', request_params) }.not_to raise_error
73
+ end
74
+ end
75
+
76
+ include_examples 'error code parsing'
77
+ end
78
+
79
+ context '400 status response' do
80
+ let(:response_status) { 400 }
81
+
82
+ include_examples 'error code parsing'
83
+ end
84
+
85
+ context '502 status response' do
86
+ let(:response_status) { 502 }
87
+ let(:response_body) { '<html><head><title>502 Bad Gateway</title></head><body><center><h1>502 Bad Gateway</h1></center></body></html>' }
88
+
89
+ it 'should raise an BadGatewayError' do
90
+ expect do
91
+ subject.post_request('do_something', request_params)
92
+ end.to raise_error(UplandMobileCommonsRest::BadGatewayError) do |error|
93
+ expect(error.body).to eq response_body
94
+ expect(error.to_s).to include(response_body)
95
+ end
96
+ end
97
+ end
98
+
99
+ context '503 status response' do
100
+ let(:response_status) { 503 }
101
+ let(:response_body) { '<html><head><title>503 Internal Server Error</title></head><body><center><h1>503 Internal Server Error</h1></center></body></html>' }
102
+
103
+ it 'should raise an UnknownError' do
104
+ expect do
105
+ subject.post_request('do_something', request_params)
106
+ end.to raise_error(UplandMobileCommonsRest::UnknownError) do |error|
107
+ expect(error.to_s).to include(response_body)
108
+ end
109
+ end
110
+ end
111
+
112
+ context '504 status response' do
113
+ let(:response_status) { 504 }
114
+ let(:response_body) { '<html><head><title>504 Gateway Time-out</title></head><body><center><h1>504 Gateway Time-out</h1></center></body></html>' }
115
+
116
+ it 'should raise an GatewayTimeoutError' do
117
+ expect do
118
+ subject.post_request('do_something', request_params)
119
+ end.to raise_error(UplandMobileCommonsRest::GatewayTimeoutError) do |error|
120
+ expect(error.body).to eq response_body
121
+ expect(error.to_s).to include(response_body)
122
+ end
123
+ end
124
+ end
125
+ end
18
126
  end
data/spec/group_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe UplandMobileCommonsRest::Groups do
@@ -24,30 +26,35 @@ describe UplandMobileCommonsRest::Groups do
24
26
  it 'should return a list of groups' do
25
27
  list = subject.list
26
28
  expect(list).to be_a(Enumerable)
27
- expect(list).to eq([{"id"=>"14", "name"=>"Group One", "size"=>"2", "status"=>"active", "type"=>"FilteredGroup"},
28
- {"id"=>"91", "name"=>"Group Two", "size"=>"1", "status"=>"active", "type"=>"UploadedGroup"}])
29
+ expect(list).to eq([{ 'id' => '14', 'name' => 'Group One', 'size' => '2', 'status' => 'active', 'type' => 'FilteredGroup' },
30
+ { 'id' => '91', 'name' => 'Group Two', 'size' => '1', 'status' => 'active',
31
+ 'type' => 'UploadedGroup' }])
29
32
  end
30
33
  end
31
34
 
32
35
  context 'paginated request' do
33
36
  it 'should return a list of groups when both parameters provided' do
34
- stub_upland_mobile_commons_request('groups?limit=50&page=35', method: :get).to_return(status: 200, body: response_body)
37
+ stub_upland_mobile_commons_request('groups?limit=50&page=35', method: :get).to_return(status: 200,
38
+ body: response_body)
35
39
 
36
40
  list = subject.list(page: 35, limit: 50)
37
41
 
38
42
  expect(list).to be_a(Enumerable)
39
- expect(list).to eq([{"id"=>"14", "name"=>"Group One", "size"=>"2", "status"=>"active", "type"=>"FilteredGroup"},
40
- {"id"=>"91", "name"=>"Group Two", "size"=>"1", "status"=>"active", "type"=>"UploadedGroup"}])
43
+ expect(list).to eq([{ 'id' => '14', 'name' => 'Group One', 'size' => '2', 'status' => 'active', 'type' => 'FilteredGroup' },
44
+ { 'id' => '91', 'name' => 'Group Two', 'size' => '1', 'status' => 'active',
45
+ 'type' => 'UploadedGroup' }])
41
46
  end
42
47
 
43
48
  it 'should return a list of groups when only limit parameter provided' do
44
- stub_upland_mobile_commons_request('groups?limit=50', method: :get).to_return(status: 200, body: response_body)
49
+ stub_upland_mobile_commons_request('groups?limit=50', method: :get).to_return(status: 200,
50
+ body: response_body)
45
51
 
46
52
  list = subject.list(limit: 50)
47
53
 
48
54
  expect(list).to be_a(Enumerable)
49
- expect(list).to eq([{"id"=>"14", "name"=>"Group One", "size"=>"2", "status"=>"active", "type"=>"FilteredGroup"},
50
- {"id"=>"91", "name"=>"Group Two", "size"=>"1", "status"=>"active", "type"=>"UploadedGroup"}])
55
+ expect(list).to eq([{ 'id' => '14', 'name' => 'Group One', 'size' => '2', 'status' => 'active', 'type' => 'FilteredGroup' },
56
+ { 'id' => '91', 'name' => 'Group Two', 'size' => '1', 'status' => 'active',
57
+ 'type' => 'UploadedGroup' }])
51
58
  end
52
59
 
53
60
  it 'should return a list of groups when only page parameter provided' do
@@ -56,8 +63,9 @@ describe UplandMobileCommonsRest::Groups do
56
63
  list = subject.list(page: 35)
57
64
 
58
65
  expect(list).to be_a(Enumerable)
59
- expect(list).to eq([{"id"=>"14", "name"=>"Group One", "size"=>"2", "status"=>"active", "type"=>"FilteredGroup"},
60
- {"id"=>"91", "name"=>"Group Two", "size"=>"1", "status"=>"active", "type"=>"UploadedGroup"}])
66
+ expect(list).to eq([{ 'id' => '14', 'name' => 'Group One', 'size' => '2', 'status' => 'active', 'type' => 'FilteredGroup' },
67
+ { 'id' => '91', 'name' => 'Group Two', 'size' => '1', 'status' => 'active',
68
+ 'type' => 'UploadedGroup' }])
61
69
  end
62
70
  end
63
71
  end
@@ -66,7 +74,9 @@ describe UplandMobileCommonsRest::Groups do
66
74
  let(:response_body) { fixture('groups/create.xml') }
67
75
 
68
76
  before(:each) do
69
- stub_upland_mobile_commons_request('create_group?name=Chocolate%20Lovers', method: :get).to_return(status: 200, body: response_body)
77
+ stub_upland_mobile_commons_request('create_group?name=Chocolate%20Lovers', method: :get).to_return(
78
+ status: 200, body: response_body
79
+ )
70
80
  end
71
81
 
72
82
  it 'should return success' do
@@ -75,4 +85,4 @@ describe UplandMobileCommonsRest::Groups do
75
85
  end
76
86
  end
77
87
  end
78
- end
88
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe UplandMobileCommonsRest::Profiles do
@@ -16,8 +18,8 @@ describe UplandMobileCommonsRest::Profiles do
16
18
 
17
19
  describe 'get' do
18
20
  before(:each) do
19
- stub_upland_mobile_commons_request("profile?phone_number=#{phone_number}", method: :get).
20
- to_return(status: 200, body: response_body)
21
+ stub_upland_mobile_commons_request("profile?phone_number=#{phone_number}", method: :get)
22
+ .to_return(status: 200, body: response_body)
21
23
  end
22
24
 
23
25
  context 'success' do
@@ -45,8 +47,8 @@ describe UplandMobileCommonsRest::Profiles do
45
47
 
46
48
  describe 'update' do
47
49
  before(:each) do
48
- stub_upland_mobile_commons_request('profile_update', method: :post, body: "phone_number=#{phone_number}").
49
- to_return(status: 200, body: response_body)
50
+ stub_upland_mobile_commons_request('profile_update', method: :post, body: "phone_number=#{phone_number}")
51
+ .to_return(status: 200, body: response_body)
50
52
  end
51
53
 
52
54
  context 'success' do
@@ -55,6 +57,10 @@ describe UplandMobileCommonsRest::Profiles do
55
57
  it 'should succeed' do
56
58
  resp = subject.update(phone_number: phone_number)
57
59
  expect(resp).to_not be_nil
60
+
61
+ expect(resp.body['response']['profile']['id']).to eq('34xxxxxxx')
62
+ expect(resp.body['response']['profile']['first_name']).to eq('John')
63
+ expect(resp.body['response']['profile']['last_name']).to eq('Doe')
58
64
  end
59
65
  end
60
66
 
@@ -62,7 +68,9 @@ describe UplandMobileCommonsRest::Profiles do
62
68
  let(:response_body) { fixture('error.xml') }
63
69
 
64
70
  it 'should raise' do
65
- expect { subject.update(phone_number: phone_number) }.to raise_error(UplandMobileCommonsRest::InvalidMessageBody)
71
+ expect do
72
+ subject.update(phone_number: phone_number)
73
+ end.to raise_error(UplandMobileCommonsRest::InvalidMessageBody)
66
74
  end
67
75
  end
68
76
  end
data/spec/spec_helper.rb CHANGED
@@ -5,11 +5,11 @@ require 'upland_mobile_commons_rest'
5
5
  require 'webmock/rspec'
6
6
 
7
7
  # Require everything in the `support` directory
8
- Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].sort.each {|f| require f}
8
+ Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].sort.each { |f| require f }
9
9
 
10
10
  RSpec.configure do |config|
11
11
  # Enable flags like --only-failures and --next-failure
12
- config.example_status_persistence_file_path = ".rspec_status"
12
+ config.example_status_persistence_file_path = '.rspec_status'
13
13
 
14
14
  # Disable RSpec exposing methods globally on `Module` and `main`
15
15
  config.disable_monkey_patching!
@@ -20,4 +20,4 @@ RSpec.configure do |config|
20
20
  config.expect_with :rspec do |c|
21
21
  c.syntax = :expect
22
22
  end
23
- end
23
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def fixture(name)
2
- File.read(File.join(File.dirname(__FILE__), '..','fixtures', name))
4
+ File.read(File.join(File.dirname(__FILE__), '..', 'fixtures', name))
3
5
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def stub_upland_mobile_commons_request(path, method:, body: nil)
2
4
  stub_request(method, "https://secure.mcommons.com/api/#{path}")
3
- .with(body: body, basic_auth: [username, password])
5
+ .with(body: body, basic_auth: [username, password])
4
6
  end
@@ -9,4 +9,4 @@ describe UplandMobileCommonsRest do
9
9
  expect(client.username).to eq('foo')
10
10
  expect(client.password).to eq('bar')
11
11
  end
12
- end
12
+ end
@@ -2,29 +2,30 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: upland_mobile_commons_rest 0.1.2 ruby lib
5
+ # stub: upland_mobile_commons_rest 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "upland_mobile_commons_rest".freeze
9
- s.version = "0.1.2"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
- s.authors = ["Nathan Woodhull".freeze]
14
- s.date = "2020-10-13"
13
+ s.authors = ["Kathy Lu".freeze, "Diego Marcet".freeze, "Grey Moore".freeze, "Nathan Woodhull".freeze]
14
+ s.date = "2021-10-07"
15
15
  s.description = "A simple ruby API client gem for the Upland Mobile Commons REST API".freeze
16
- s.email = "nathan@controlshiftlabs.com".freeze
16
+ s.email = "team@controlshiftlabs.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE.txt",
19
19
  "README.md"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
+ ".github/workflows/ci.yml",
23
24
  ".rubocop.yml",
24
- ".travis.yml",
25
+ ".ruby-gemset",
26
+ ".ruby-version",
25
27
  "CODE_OF_CONDUCT.md",
26
28
  "Gemfile",
27
- "Gemfile.lock",
28
29
  "LICENSE.txt",
29
30
  "README.md",
30
31
  "Rakefile",
@@ -56,48 +57,36 @@ Gem::Specification.new do |s|
56
57
  ]
57
58
  s.homepage = "http://github.com/controlshift/upland_mobile_commons_rest".freeze
58
59
  s.licenses = ["MIT".freeze]
59
- s.rubygems_version = "3.0.8".freeze
60
+ s.rubygems_version = "3.1.6".freeze
60
61
  s.summary = "API client gem for Upland Mobile Commons".freeze
61
62
 
62
63
  if s.respond_to? :specification_version then
63
64
  s.specification_version = 4
65
+ end
64
66
 
65
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
66
- s.add_runtime_dependency(%q<vertebrae>.freeze, [">= 0"])
67
- s.add_development_dependency(%q<shoulda>.freeze, [">= 0"])
68
- s.add_development_dependency(%q<rdoc>.freeze, ["> 3.12"])
69
- s.add_development_dependency(%q<bundler>.freeze, ["> 2.0"])
70
- s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
71
- s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
72
- s.add_development_dependency(%q<dotenv>.freeze, [">= 0"])
73
- s.add_development_dependency(%q<byebug>.freeze, [">= 0"])
74
- s.add_development_dependency(%q<rubocop>.freeze, [">= 0"])
75
- s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
76
- s.add_development_dependency(%q<webmock>.freeze, [">= 0"])
77
- else
78
- s.add_dependency(%q<vertebrae>.freeze, [">= 0"])
79
- s.add_dependency(%q<shoulda>.freeze, [">= 0"])
80
- s.add_dependency(%q<rdoc>.freeze, ["> 3.12"])
81
- s.add_dependency(%q<bundler>.freeze, ["> 2.0"])
82
- s.add_dependency(%q<juwelier>.freeze, [">= 0"])
83
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
84
- s.add_dependency(%q<dotenv>.freeze, [">= 0"])
85
- s.add_dependency(%q<byebug>.freeze, [">= 0"])
86
- s.add_dependency(%q<rubocop>.freeze, [">= 0"])
87
- s.add_dependency(%q<rspec>.freeze, [">= 0"])
88
- s.add_dependency(%q<webmock>.freeze, [">= 0"])
89
- end
67
+ if s.respond_to? :add_runtime_dependency then
68
+ s.add_runtime_dependency(%q<vertebrae>.freeze, [">= 0"])
69
+ s.add_development_dependency(%q<bundler>.freeze, ["> 2.0"])
70
+ s.add_development_dependency(%q<byebug>.freeze, [">= 0"])
71
+ s.add_development_dependency(%q<dotenv>.freeze, [">= 0"])
72
+ s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
73
+ s.add_development_dependency(%q<rdoc>.freeze, ["> 3.12"])
74
+ s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
75
+ s.add_development_dependency(%q<rubocop>.freeze, [">= 0"])
76
+ s.add_development_dependency(%q<shoulda>.freeze, [">= 0"])
77
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
78
+ s.add_development_dependency(%q<webmock>.freeze, [">= 0"])
90
79
  else
91
80
  s.add_dependency(%q<vertebrae>.freeze, [">= 0"])
92
- s.add_dependency(%q<shoulda>.freeze, [">= 0"])
93
- s.add_dependency(%q<rdoc>.freeze, ["> 3.12"])
94
81
  s.add_dependency(%q<bundler>.freeze, ["> 2.0"])
95
- s.add_dependency(%q<juwelier>.freeze, [">= 0"])
96
- s.add_dependency(%q<simplecov>.freeze, [">= 0"])
97
- s.add_dependency(%q<dotenv>.freeze, [">= 0"])
98
82
  s.add_dependency(%q<byebug>.freeze, [">= 0"])
99
- s.add_dependency(%q<rubocop>.freeze, [">= 0"])
83
+ s.add_dependency(%q<dotenv>.freeze, [">= 0"])
84
+ s.add_dependency(%q<juwelier>.freeze, [">= 0"])
85
+ s.add_dependency(%q<rdoc>.freeze, ["> 3.12"])
100
86
  s.add_dependency(%q<rspec>.freeze, [">= 0"])
87
+ s.add_dependency(%q<rubocop>.freeze, [">= 0"])
88
+ s.add_dependency(%q<shoulda>.freeze, [">= 0"])
89
+ s.add_dependency(%q<simplecov>.freeze, [">= 0"])
101
90
  s.add_dependency(%q<webmock>.freeze, [">= 0"])
102
91
  end
103
92
  end
metadata CHANGED
@@ -1,14 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upland_mobile_commons_rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
+ - Kathy Lu
8
+ - Diego Marcet
9
+ - Grey Moore
7
10
  - Nathan Woodhull
8
- autorequire:
11
+ autorequire:
9
12
  bindir: bin
10
13
  cert_chain: []
11
- date: 2020-10-13 00:00:00.000000000 Z
14
+ date: 2021-10-07 00:00:00.000000000 Z
12
15
  dependencies:
13
16
  - !ruby/object:Gem::Dependency
14
17
  name: vertebrae
@@ -25,47 +28,47 @@ dependencies:
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
- name: shoulda
31
+ name: bundler
29
32
  requirement: !ruby/object:Gem::Requirement
30
33
  requirements:
31
- - - ">="
34
+ - - ">"
32
35
  - !ruby/object:Gem::Version
33
- version: '0'
36
+ version: '2.0'
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - ">="
41
+ - - ">"
39
42
  - !ruby/object:Gem::Version
40
- version: '0'
43
+ version: '2.0'
41
44
  - !ruby/object:Gem::Dependency
42
- name: rdoc
45
+ name: byebug
43
46
  requirement: !ruby/object:Gem::Requirement
44
47
  requirements:
45
- - - ">"
48
+ - - ">="
46
49
  - !ruby/object:Gem::Version
47
- version: '3.12'
50
+ version: '0'
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - ">"
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
- version: '3.12'
57
+ version: '0'
55
58
  - !ruby/object:Gem::Dependency
56
- name: bundler
59
+ name: dotenv
57
60
  requirement: !ruby/object:Gem::Requirement
58
61
  requirements:
59
- - - ">"
62
+ - - ">="
60
63
  - !ruby/object:Gem::Version
61
- version: '2.0'
64
+ version: '0'
62
65
  type: :development
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
- - - ">"
69
+ - - ">="
67
70
  - !ruby/object:Gem::Version
68
- version: '2.0'
71
+ version: '0'
69
72
  - !ruby/object:Gem::Dependency
70
73
  name: juwelier
71
74
  requirement: !ruby/object:Gem::Requirement
@@ -81,21 +84,21 @@ dependencies:
81
84
  - !ruby/object:Gem::Version
82
85
  version: '0'
83
86
  - !ruby/object:Gem::Dependency
84
- name: simplecov
87
+ name: rdoc
85
88
  requirement: !ruby/object:Gem::Requirement
86
89
  requirements:
87
- - - ">="
90
+ - - ">"
88
91
  - !ruby/object:Gem::Version
89
- version: '0'
92
+ version: '3.12'
90
93
  type: :development
91
94
  prerelease: false
92
95
  version_requirements: !ruby/object:Gem::Requirement
93
96
  requirements:
94
- - - ">="
97
+ - - ">"
95
98
  - !ruby/object:Gem::Version
96
- version: '0'
99
+ version: '3.12'
97
100
  - !ruby/object:Gem::Dependency
98
- name: dotenv
101
+ name: rspec
99
102
  requirement: !ruby/object:Gem::Requirement
100
103
  requirements:
101
104
  - - ">="
@@ -109,7 +112,7 @@ dependencies:
109
112
  - !ruby/object:Gem::Version
110
113
  version: '0'
111
114
  - !ruby/object:Gem::Dependency
112
- name: byebug
115
+ name: rubocop
113
116
  requirement: !ruby/object:Gem::Requirement
114
117
  requirements:
115
118
  - - ">="
@@ -123,7 +126,7 @@ dependencies:
123
126
  - !ruby/object:Gem::Version
124
127
  version: '0'
125
128
  - !ruby/object:Gem::Dependency
126
- name: rubocop
129
+ name: shoulda
127
130
  requirement: !ruby/object:Gem::Requirement
128
131
  requirements:
129
132
  - - ">="
@@ -137,7 +140,7 @@ dependencies:
137
140
  - !ruby/object:Gem::Version
138
141
  version: '0'
139
142
  - !ruby/object:Gem::Dependency
140
- name: rspec
143
+ name: simplecov
141
144
  requirement: !ruby/object:Gem::Requirement
142
145
  requirements:
143
146
  - - ">="
@@ -165,7 +168,7 @@ dependencies:
165
168
  - !ruby/object:Gem::Version
166
169
  version: '0'
167
170
  description: A simple ruby API client gem for the Upland Mobile Commons REST API
168
- email: nathan@controlshiftlabs.com
171
+ email: team@controlshiftlabs.com
169
172
  executables: []
170
173
  extensions: []
171
174
  extra_rdoc_files:
@@ -173,11 +176,12 @@ extra_rdoc_files:
173
176
  - README.md
174
177
  files:
175
178
  - ".document"
179
+ - ".github/workflows/ci.yml"
176
180
  - ".rubocop.yml"
177
- - ".travis.yml"
181
+ - ".ruby-gemset"
182
+ - ".ruby-version"
178
183
  - CODE_OF_CONDUCT.md
179
184
  - Gemfile
180
- - Gemfile.lock
181
185
  - LICENSE.txt
182
186
  - README.md
183
187
  - Rakefile
@@ -210,7 +214,7 @@ homepage: http://github.com/controlshift/upland_mobile_commons_rest
210
214
  licenses:
211
215
  - MIT
212
216
  metadata: {}
213
- post_install_message:
217
+ post_install_message:
214
218
  rdoc_options: []
215
219
  require_paths:
216
220
  - lib
@@ -225,8 +229,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
229
  - !ruby/object:Gem::Version
226
230
  version: '0'
227
231
  requirements: []
228
- rubygems_version: 3.0.8
229
- signing_key:
232
+ rubygems_version: 3.1.6
233
+ signing_key:
230
234
  specification_version: 4
231
235
  summary: API client gem for Upland Mobile Commons
232
236
  test_files: []
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.6
4
- cache: bundler
5
- before_install:
6
- - gem install bundler
7
- script:
8
- - bundle exec rspec
9
- - bundle exec rubocop
data/Gemfile.lock DELETED
@@ -1,154 +0,0 @@
1
- GIT
2
- remote: https://github.com/flajann2/juwelier.git
3
- revision: de59d5a2ddea00c1f18957ab62129c1c141acce1
4
- specs:
5
- juwelier (2.4.9)
6
- builder
7
- bundler
8
- git
9
- github_api
10
- highline
11
- kamelcase (~> 0)
12
- nokogiri
13
- psych
14
- rake
15
- rdoc
16
- semver2
17
-
18
- GEM
19
- remote: https://rubygems.org/
20
- specs:
21
- activesupport (6.0.3.1)
22
- concurrent-ruby (~> 1.0, >= 1.0.2)
23
- i18n (>= 0.7, < 2)
24
- minitest (~> 5.1)
25
- tzinfo (~> 1.1)
26
- zeitwerk (~> 2.2, >= 2.2.2)
27
- addressable (2.7.0)
28
- public_suffix (>= 2.0.2, < 5.0)
29
- ast (2.4.0)
30
- builder (3.2.4)
31
- byebug (11.1.3)
32
- concurrent-ruby (1.1.6)
33
- crack (0.4.3)
34
- safe_yaml (~> 1.0.0)
35
- descendants_tracker (0.0.4)
36
- thread_safe (~> 0.3, >= 0.3.1)
37
- diff-lcs (1.3)
38
- docile (1.3.2)
39
- dotenv (2.7.5)
40
- faraday (0.17.3)
41
- multipart-post (>= 1.2, < 3)
42
- faraday_middleware (0.14.0)
43
- faraday (>= 0.7.4, < 1.0)
44
- git (1.7.0)
45
- rchardet (~> 1.8)
46
- github_api (0.18.2)
47
- addressable (~> 2.4)
48
- descendants_tracker (~> 0.0.4)
49
- faraday (~> 0.8)
50
- hashie (~> 3.5, >= 3.5.2)
51
- oauth2 (~> 1.0)
52
- hashdiff (1.0.1)
53
- hashie (3.6.0)
54
- highline (2.0.3)
55
- i18n (1.8.3)
56
- concurrent-ruby (~> 1.0)
57
- jwt (2.2.1)
58
- kamelcase (0.0.2)
59
- semver2 (~> 3)
60
- mini_portile2 (2.4.0)
61
- minitest (5.14.1)
62
- multi_json (1.14.1)
63
- multi_xml (0.6.0)
64
- multipart-post (2.1.1)
65
- nokogiri (1.10.9)
66
- mini_portile2 (~> 2.4.0)
67
- oauth2 (1.4.4)
68
- faraday (>= 0.8, < 2.0)
69
- jwt (>= 1.0, < 3.0)
70
- multi_json (~> 1.3)
71
- multi_xml (~> 0.5)
72
- rack (>= 1.2, < 3)
73
- parallel (1.19.1)
74
- parser (2.7.1.3)
75
- ast (~> 2.4.0)
76
- psych (3.1.0)
77
- public_suffix (4.0.5)
78
- rack (2.2.3)
79
- rainbow (3.0.0)
80
- rake (13.0.1)
81
- rchardet (1.8.0)
82
- rdoc (6.2.1)
83
- regexp_parser (1.7.0)
84
- rexml (3.2.4)
85
- rspec (3.9.0)
86
- rspec-core (~> 3.9.0)
87
- rspec-expectations (~> 3.9.0)
88
- rspec-mocks (~> 3.9.0)
89
- rspec-core (3.9.2)
90
- rspec-support (~> 3.9.3)
91
- rspec-expectations (3.9.2)
92
- diff-lcs (>= 1.2.0, < 2.0)
93
- rspec-support (~> 3.9.0)
94
- rspec-mocks (3.9.1)
95
- diff-lcs (>= 1.2.0, < 2.0)
96
- rspec-support (~> 3.9.0)
97
- rspec-support (3.9.3)
98
- rubocop (0.85.0)
99
- parallel (~> 1.10)
100
- parser (>= 2.7.0.1)
101
- rainbow (>= 2.2.2, < 4.0)
102
- regexp_parser (>= 1.7)
103
- rexml
104
- rubocop-ast (>= 0.0.3)
105
- ruby-progressbar (~> 1.7)
106
- unicode-display_width (>= 1.4.0, < 2.0)
107
- rubocop-ast (0.0.3)
108
- parser (>= 2.7.0.1)
109
- ruby-progressbar (1.10.1)
110
- safe_yaml (1.0.5)
111
- semver2 (3.4.2)
112
- shoulda (3.6.0)
113
- shoulda-context (~> 1.0, >= 1.0.1)
114
- shoulda-matchers (~> 3.0)
115
- shoulda-context (1.2.2)
116
- shoulda-matchers (3.1.3)
117
- activesupport (>= 4.0.0)
118
- simplecov (0.18.5)
119
- docile (~> 1.1)
120
- simplecov-html (~> 0.11)
121
- simplecov-html (0.12.2)
122
- thread_safe (0.3.6)
123
- tzinfo (1.2.7)
124
- thread_safe (~> 0.1)
125
- unicode-display_width (1.7.0)
126
- vertebrae (0.6.2)
127
- activesupport (>= 5.1.4)
128
- faraday (> 0.9.2)
129
- faraday_middleware (> 0.12.2)
130
- hashie (> 3.5.7)
131
- webmock (3.8.3)
132
- addressable (>= 2.3.6)
133
- crack (>= 0.3.2)
134
- hashdiff (>= 0.4.0, < 2.0.0)
135
- zeitwerk (2.3.0)
136
-
137
- PLATFORMS
138
- ruby
139
-
140
- DEPENDENCIES
141
- bundler (> 2.0)
142
- byebug
143
- dotenv
144
- juwelier!
145
- rdoc (> 3.12)
146
- rspec
147
- rubocop
148
- shoulda
149
- simplecov
150
- vertebrae
151
- webmock
152
-
153
- BUNDLED WITH
154
- 2.1.4