freshdesk_apiclient 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +3 -1
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -1
- data/README.md +58 -5
- data/lib/core_extensions/object/class_name.rb +16 -0
- data/lib/freshdesk_apiclient/rest/client.rb +38 -17
- data/lib/freshdesk_apiclient/rest/resources.rb +27 -16
- data/lib/freshdesk_apiclient/rest/tickets.rb +2 -1
- data/lib/freshdesk_apiclient/utils/camelizable.rb +5 -1
- data/lib/freshdesk_apiclient/version.rb +1 -1
- data/lib/freshdesk_apiclient.rb +9 -0
- data/spec/core_extensions/object/class_name_spec.rb +32 -0
- data/spec/freshdesk_apiclient_spec.rb +3 -0
- data/spec/rest/client_spec.rb +1 -0
- data/spec/rest/resources_spec.rb +40 -26
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6429194a2b6efcbe4c6cad46d080fd2b16679a01
|
4
|
+
data.tar.gz: 948d6153138e7c8f1b2e887eae23e713de6c15a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aac732b4c3e702350e3afecbc2b1227212857750b967115a86cda6e72bf00155e4efe4daea82d21ff14407363e55225d7591b3f11643346a9c2226a6106497cc
|
7
|
+
data.tar.gz: 97e3e57d0922e6afe2c007eadd7040c4534be4f1c2dfdc386bd32f55fccb4dcd0ec858bde172a745b6ce0d8bb952a0b6982ca40734d8986e8e68f11502b233d7
|
data/.codeclimate.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -143,7 +143,7 @@ Style/StringLiteralsInInterpolation:
|
|
143
143
|
Metrics/AbcSize:
|
144
144
|
Description: A calculated magnitude based on number of assignments, branches, and
|
145
145
|
conditions.
|
146
|
-
Enabled:
|
146
|
+
Enabled: true
|
147
147
|
Max: 15
|
148
148
|
Metrics/BlockLength:
|
149
149
|
ExcludedMethods: ['describe', 'context', 'shared_examples']
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
[![Dependency Status](https://gemnasium.com/badges/github.com/qbantek/freshdesk_apiclient.svg)](https://gemnasium.com/github.com/qbantek/freshdesk_apiclient)
|
9
9
|
[![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://freshdesk_apiclient.mit-license.org)
|
10
10
|
|
11
|
-
A ruby client for [freshdesk
|
11
|
+
A ruby client for [freshdesk](https://developer.freshdesk.com/api/) API.
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
@@ -25,20 +25,73 @@ And then execute:
|
|
25
25
|
Or install it yourself as:
|
26
26
|
|
27
27
|
$ gem install freshdesk_apiclient
|
28
|
+
|
29
|
+
#### Setup your authentication credentials
|
30
|
+
|
31
|
+
You'll need to create your account and get the credentials at [freshdesk](https://freshdesk.com/).
|
32
|
+
See [Authentication](https://developers.freshdesk.com/api/#authentication) for more information.
|
33
|
+
|
34
|
+
Username and password:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# config/initializers/freshdesk_apiclient.rb
|
38
|
+
FreshdeskApiclient.username_or_api_key = ENV["FRESHDESK_USERNAME"]
|
39
|
+
FreshdeskApiclient.password = ENV["FRESHDESK_PASWWORD"]
|
40
|
+
```
|
41
|
+
|
42
|
+
Or API key:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# config/initializers/freshdesk_apiclient.rb
|
46
|
+
FreshdeskApiclient.username_or_api_key = ENV["FRESHDESK_API_KEY"]
|
47
|
+
```
|
48
|
+
(If you use the API key, there is no need for a password.)
|
49
|
+
|
50
|
+
#### Other configuration
|
51
|
+
|
52
|
+
You might want to set the Logger to be used by the gem.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# config/initializers/freshdesk_apiclient.rb
|
56
|
+
FreshdeskApiclient.logger = Rails.logger
|
57
|
+
```
|
28
58
|
|
29
59
|
## Usage
|
30
60
|
|
31
|
-
|
61
|
+
Currently, only the following requests are supported:
|
62
|
+
|
63
|
+
#### Tickets
|
64
|
+
|
65
|
+
- Create a ticket
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
client = FreshdeskApiclient::Client.new
|
69
|
+
client.tickets.create payload # payload is a hash,
|
70
|
+
```
|
71
|
+
See [Create a ticket](https://developers.freshdesk.com/api/#create_ticket) for allowed attributes on the payload.
|
72
|
+
|
73
|
+
- List all tickets
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
client = FreshdeskApiclient::Client.new
|
77
|
+
client.tickets.list
|
78
|
+
```
|
32
79
|
|
33
80
|
## Development
|
34
81
|
|
35
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
82
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec spec` to run the tests.
|
83
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
36
84
|
|
37
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
85
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
86
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
87
|
+
which will create a git tag for the version, push git commits and tags,
|
88
|
+
and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
38
89
|
|
39
90
|
## Contributing
|
40
91
|
|
41
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/qbantek/freshdesk_apiclient.
|
92
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/qbantek/freshdesk_apiclient.
|
93
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
|
94
|
+
to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
42
95
|
|
43
96
|
|
44
97
|
## License
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ObjectExtensions
|
3
|
+
refine Object do
|
4
|
+
def class_name
|
5
|
+
full_class_name_as_array.last
|
6
|
+
end
|
7
|
+
|
8
|
+
def full_class_name_as_array
|
9
|
+
full_class_name.split('::')
|
10
|
+
end
|
11
|
+
|
12
|
+
def full_class_name
|
13
|
+
self.class.name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require_relative '../../../lib/freshdesk_apiclient'
|
3
|
+
|
2
4
|
module FreshdeskApiclient
|
3
5
|
module REST
|
4
6
|
class Client
|
@@ -13,8 +15,7 @@ module FreshdeskApiclient
|
|
13
15
|
# @param [Logger] logger
|
14
16
|
def initialize(domain: FreshdeskApiclient.domain,
|
15
17
|
username_or_api_key: FreshdeskApiclient.username_or_api_key,
|
16
|
-
password: FreshdeskApiclient.password,
|
17
|
-
logger: nil)
|
18
|
+
password: FreshdeskApiclient.password, logger: FreshdeskApiclient.logger)
|
18
19
|
@base_url = "https://#{domain}.freshdesk.com/api/v2/"
|
19
20
|
@credentials = {username: username_or_api_key, password: password}
|
20
21
|
@logger = logger
|
@@ -22,21 +23,41 @@ module FreshdeskApiclient
|
|
22
23
|
|
23
24
|
# obj.method_missing(symbol [, *args] ) -> result
|
24
25
|
def method_missing(symbol, *arguments, &block)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
RESOURCES.include?(symbol) ? instance_variable(symbol) : super
|
27
|
+
end
|
28
|
+
|
29
|
+
def respond_to_missing?(method, *)
|
30
|
+
RESOURCES.include?(method) ? true : super
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def instance_variable(symbol)
|
36
|
+
class_name = camelize symbol
|
37
|
+
get_set_ivar class_name, as_ivar(class_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_set_ivar(class_name, ivar)
|
41
|
+
instance_variable_defined?(ivar) ? instance_variable_get(ivar) : set(ivar, class_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def set(ivar, class_name)
|
45
|
+
obj = instantiate class_name
|
46
|
+
instance_variable_set ivar, obj
|
47
|
+
end
|
48
|
+
|
49
|
+
def as_ivar(name)
|
50
|
+
"@#{name.downcase}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def instantiate(class_name)
|
54
|
+
klass(class_name, 'FreshdeskApiclient', 'REST').new(@base_url, credentials: @credentials, logger: logger)
|
55
|
+
end
|
56
|
+
|
57
|
+
def klass(class_name, *module_names)
|
58
|
+
c = Object
|
59
|
+
module_names.each {|m| c = c.const_get m }
|
60
|
+
c.const_get class_name
|
40
61
|
end
|
41
62
|
end
|
42
63
|
end
|
@@ -1,44 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'rest-client'
|
3
3
|
require 'forwardable'
|
4
|
-
|
4
|
+
require_relative '../../../lib/core_extensions/object/class_name'
|
5
5
|
|
6
6
|
module FreshdeskApiclient
|
7
7
|
module REST
|
8
8
|
class Resources
|
9
|
+
using ObjectExtensions
|
10
|
+
|
9
11
|
def initialize(base_url, options={})
|
10
|
-
@
|
11
|
-
@headers = headers options[:credentials]
|
12
|
+
@args = default_arguments options[:credentials], base_url, options[:path]
|
12
13
|
RestClient.log = options[:logger]
|
13
14
|
end
|
14
15
|
|
15
16
|
def list
|
16
|
-
execute(method: :get, headers:
|
17
|
+
execute(method: :get, headers: headers)
|
17
18
|
end
|
18
19
|
|
19
20
|
def create(json_payload)
|
20
|
-
execute(method: :post, headers:
|
21
|
+
execute(method: :post, headers: content_headers, payload: json_payload)
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
+
private
|
24
25
|
|
25
|
-
def
|
26
|
-
|
26
|
+
def resource
|
27
|
+
class_name.downcase
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
def execute(options)
|
32
|
-
RestClient::Request.execute @options.merge(options)
|
30
|
+
def execute(args)
|
31
|
+
RestClient::Request.execute @args.merge(args)
|
33
32
|
end
|
34
33
|
|
35
|
-
def
|
34
|
+
def default_arguments(credentials, base_url, path=nil)
|
36
35
|
{
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
user: credentials[:username],
|
37
|
+
password: credentials[:password],
|
38
|
+
url: full_url(base_url, path)
|
40
39
|
}
|
41
40
|
end
|
41
|
+
|
42
|
+
def full_url(base_url, path)
|
43
|
+
"#{base_url}/#{path || resource}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def content_headers
|
47
|
+
headers.merge('Content-Type': 'application/json')
|
48
|
+
end
|
49
|
+
|
50
|
+
def headers
|
51
|
+
{Accept: 'application/json'}
|
52
|
+
end
|
42
53
|
end
|
43
54
|
end
|
44
55
|
end
|
@@ -4,8 +4,12 @@ module FreshdeskApiclient
|
|
4
4
|
module Camelizable
|
5
5
|
def camelize(term)
|
6
6
|
string = term.to_s
|
7
|
+
format string
|
8
|
+
end
|
9
|
+
|
10
|
+
def format(string)
|
7
11
|
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
8
|
-
string.gsub!(%r{(?:_|(/))([a-z\d]*)}) { $2.capitalize
|
12
|
+
string.gsub!(%r{(?:_|(/))([a-z\d]*)}) { $2.capitalize }
|
9
13
|
string
|
10
14
|
end
|
11
15
|
end
|
data/lib/freshdesk_apiclient.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'core_extensions/object/class_name'
|
2
3
|
require 'freshdesk_apiclient/version'
|
3
4
|
|
4
5
|
require 'freshdesk_apiclient/utils/loggeable'
|
@@ -32,4 +33,12 @@ module FreshdeskApiclient
|
|
32
33
|
def self.password=(password)
|
33
34
|
@password = password
|
34
35
|
end
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
@logger ||= nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.logger=(logger)
|
42
|
+
@logger = logger
|
43
|
+
end
|
35
44
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative '../../../lib/core_extensions/object/class_name'
|
3
|
+
RSpec.describe ObjectExtensions do
|
4
|
+
module Foo
|
5
|
+
class Bar
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'when refining Object' do
|
10
|
+
using ObjectExtensions
|
11
|
+
|
12
|
+
context 'for any Foo:Bar instance' do
|
13
|
+
subject { Foo::Bar.new }
|
14
|
+
describe '#full_class_name' do
|
15
|
+
it { expect(subject.full_class_name).to eq('Foo::Bar') }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#full_class_name_as_array' do
|
19
|
+
it('should return an Array of 2 items') do
|
20
|
+
expect(subject.full_class_name_as_array).to be_a(Array)
|
21
|
+
expect(subject.full_class_name_as_array.size).to eq(2)
|
22
|
+
end
|
23
|
+
it('first array item should eq Foo') { expect(subject.full_class_name_as_array[0]).to eq('Foo') }
|
24
|
+
it('second array item should eq Bar') { expect(subject.full_class_name_as_array[0]).to eq('Foo') }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#class_name' do
|
28
|
+
it { expect(subject.class_name).to eq('Bar') }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -17,4 +17,7 @@ RSpec.describe FreshdeskApiclient do
|
|
17
17
|
before { FreshdeskApiclient.password = nil }
|
18
18
|
it('has a default password') { expect(FreshdeskApiclient.password).to eq('X') }
|
19
19
|
end
|
20
|
+
|
21
|
+
before { FreshdeskApiclient.logger = :l }
|
22
|
+
it('allows to set logger') { expect(FreshdeskApiclient.logger).to eq(:l) }
|
20
23
|
end
|
data/spec/rest/client_spec.rb
CHANGED
data/spec/rest/resources_spec.rb
CHANGED
@@ -5,45 +5,36 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
5
5
|
subject { FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}) }
|
6
6
|
|
7
7
|
RSpec.shared_examples 'a resource' do
|
8
|
-
let(:get_headers) { {
|
8
|
+
let(:get_headers) { {Accept: 'application/json'} }
|
9
9
|
let(:post_headers) { get_headers.merge('Content-Type': 'application/json') }
|
10
10
|
let(:resource) { subject.class.name.split('::').last.downcase }
|
11
11
|
|
12
12
|
describe '#new' do
|
13
|
+
it 'sets the user using given credentials' do
|
14
|
+
expect(subject.instance_variable_get(:@args)[:user]).to eql(:u)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets the password using given credentials' do
|
18
|
+
expect(subject.instance_variable_get(:@args)[:password]).to eql(:p)
|
19
|
+
end
|
20
|
+
|
13
21
|
context 'when path option is provided' do
|
14
22
|
subject { FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}, path: :foo) }
|
15
23
|
it 'sets the url using given path' do
|
16
|
-
expect(subject.instance_variable_get(:@
|
24
|
+
expect(subject.instance_variable_get(:@args)[:url]).to eql("#{:url}/#{:foo}")
|
17
25
|
end
|
18
26
|
end
|
19
27
|
|
20
28
|
context 'when path option is not provided' do
|
21
29
|
it 'sets the url for the given resource' do
|
22
|
-
expect(subject.instance_variable_get(:@
|
30
|
+
expect(subject.instance_variable_get(:@args)[:url]).to eql("#{:url}/#{resource}")
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
|
-
it 'sets the Authorization header for the given credentials' do
|
27
|
-
expect(subject.instance_variable_get(:@headers)[:Authorization]).to eql(get_headers[:Authorization])
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'sets the Accept header to accept JSON' do
|
31
|
-
expect(subject.instance_variable_get(:@headers)[:Accept]).to eql(get_headers[:Accept])
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'sets the Content-Type header to indicate JSON content' do
|
35
|
-
expect(subject.instance_variable_get(:@headers)[:'Content-Type']).to eql(post_headers[:'Content-Type'])
|
36
|
-
end
|
37
|
-
|
38
34
|
it('sets the logger on RestClient') do
|
39
35
|
rest_client = object_double('RestClient', :log= => nil).as_stubbed_const
|
40
36
|
logger = Logger.new(STDOUT)
|
41
|
-
FreshdeskApiclient::REST::Resources.new(:url,
|
42
|
-
credentials: {
|
43
|
-
username: :u,
|
44
|
-
password: :p
|
45
|
-
},
|
46
|
-
logger: logger)
|
37
|
+
FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}, logger: logger)
|
47
38
|
expect(rest_client).to have_received(:log=).with(logger)
|
48
39
|
end
|
49
40
|
end
|
@@ -52,7 +43,14 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
52
43
|
it('executes the request as a GET') do
|
53
44
|
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
54
45
|
subject.list
|
55
|
-
expect(request).to have_received(:execute).with(method: :get
|
46
|
+
expect(request).to have_received(:execute).with(hash_including(method: :get))
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'sets the Accept header to accept JSON' do
|
50
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
51
|
+
subject.list
|
52
|
+
expect(get_headers[:Accept]).to eq('application/json')
|
53
|
+
expect(request).to have_received(:execute).with(hash_including(headers: get_headers))
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
@@ -60,10 +58,26 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
60
58
|
it('executes the request as a POST') do
|
61
59
|
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
62
60
|
subject.create :payload
|
63
|
-
expect(request).to have_received(:execute).with(method: :post
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
expect(request).to have_received(:execute).with(hash_including(method: :post))
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'sets the Accept header to accept JSON' do
|
65
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
66
|
+
subject.create :payload
|
67
|
+
expect(request).to have_received(:execute).with(hash_including(headers: post_headers))
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'sets the Content-Type header to indicate JSON content' do
|
71
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
72
|
+
subject.create :payload
|
73
|
+
expect(post_headers[:'Content-Type']).to eq('application/json')
|
74
|
+
expect(request).to have_received(:execute).with(hash_including(headers: post_headers))
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'submits the payload' do
|
78
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
79
|
+
subject.create :payload
|
80
|
+
expect(request).to have_received(:execute).with(hash_including(payload: :payload))
|
67
81
|
end
|
68
82
|
end
|
69
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freshdesk_apiclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erich Quintero
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- bin/console
|
195
195
|
- bin/setup
|
196
196
|
- freshdesk_apiclient.gemspec
|
197
|
+
- lib/core_extensions/object/class_name.rb
|
197
198
|
- lib/freshdesk_apiclient.rb
|
198
199
|
- lib/freshdesk_apiclient/rest/client.rb
|
199
200
|
- lib/freshdesk_apiclient/rest/resources.rb
|
@@ -202,6 +203,7 @@ files:
|
|
202
203
|
- lib/freshdesk_apiclient/utils/loggeable.rb
|
203
204
|
- lib/freshdesk_apiclient/version.rb
|
204
205
|
- lib/tasks/releaser.rake
|
206
|
+
- spec/core_extensions/object/class_name_spec.rb
|
205
207
|
- spec/freshdesk_apiclient_spec.rb
|
206
208
|
- spec/rest/client_spec.rb
|
207
209
|
- spec/rest/resources_spec.rb
|
@@ -237,3 +239,4 @@ test_files:
|
|
237
239
|
- spec/rest/resources_spec.rb
|
238
240
|
- spec/freshdesk_apiclient_spec.rb
|
239
241
|
- spec/spec_helper.rb
|
242
|
+
- spec/core_extensions/object/class_name_spec.rb
|