upland_mobile_commons_rest 0.1.2 → 0.2.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.
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