sabre_dev_studio 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +68 -0
- data/Rakefile +20 -0
- data/lib/sabre_dev_studio.rb +8 -0
- data/lib/sabre_dev_studio/base.rb +102 -0
- data/lib/sabre_dev_studio/error.rb +22 -0
- data/lib/sabre_dev_studio/hashie_key_conversion.rb +57 -0
- data/lib/sabre_dev_studio/helpers/date.rb +15 -0
- data/lib/sabre_dev_studio/request_object.rb +46 -0
- data/lib/sabre_dev_studio/version.rb +3 -0
- data/sabre_dev_studio.gemspec +26 -0
- data/test/date_test.rb +17 -0
- data/test/error_test.rb +42 -0
- data/test/fixtures/air_shopping_themes.json +113 -0
- data/test/request_test.rb +33 -0
- data/test/test_helper.rb +31 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e3987a8a8043ded426fcba76b4736da4ea9d0fa4
|
4
|
+
data.tar.gz: 977345c11500725ffae4c8bcba4df18ec4440be8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 96d142581d6dddfecf389cafc330a9f3db2ded4209bf39e627ebe82be7e439cc731482486f3722b889556a8bd86662ca692e0c9a2c9474db4d996fdefbcb07be
|
7
|
+
data.tar.gz: 8bc891c6255b385fdafe7ca45491171fe459b71511a5ee8dc87a6e0002f1b00e0acd159f4776251ef220edecb404fda8d7948a949dabed81fc874feef887ff9b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Sabre Corp
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# SabreDevStudio
|
2
|
+
|
3
|
+
This is the base gem for a suite of API wrappers for the Sabre Dev Studio APIs.
|
4
|
+
|
5
|
+
This gem includes the token authentication and basic error handling.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'sabre_dev_studio'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install sabre_dev_studio
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Register for an account at http://developer.sabre.com
|
24
|
+
|
25
|
+
Require this gem and whatever other sabre_dev_studio gem(s) that you need.
|
26
|
+
|
27
|
+
Configuration block (required, use your credentials):
|
28
|
+
|
29
|
+
SabreDevStudio.configure do |c|
|
30
|
+
c.user = 'USER'
|
31
|
+
c.group = 'GROUP'
|
32
|
+
c.domain = 'DOMAIN'
|
33
|
+
c.password = 'PASSWORD'
|
34
|
+
end
|
35
|
+
|
36
|
+
To see an access token:
|
37
|
+
|
38
|
+
token = SabreDevStudio::Base.get_access_token
|
39
|
+
|
40
|
+
An example request:
|
41
|
+
|
42
|
+
themes = SabreDevStudio::Base.get('/v1/shop/themes')
|
43
|
+
|
44
|
+
cURL to test the account token dance:
|
45
|
+
|
46
|
+
curl \
|
47
|
+
-X POST \
|
48
|
+
--header "Content-Type: application/x-www-form-urlencoded" \
|
49
|
+
--header "Authorization:Basic VmpFNk1UQTBNanBUVkZCVE9rVllWQT09OlFrdENRVzh6V0RNPQ==" \
|
50
|
+
--data "grant_type=client_credentials" \
|
51
|
+
https://api.test.sabre.com/v1/auth/token
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
1. Fork it
|
56
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
57
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
58
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
59
|
+
5. Create new Pull Request
|
60
|
+
|
61
|
+
## License
|
62
|
+
|
63
|
+
See LICENSE.txt
|
64
|
+
|
65
|
+
## Disclaimer of Warranty and Limitation of Liability
|
66
|
+
|
67
|
+
This software and any compiled programs created using this software are furnished “as is” without warranty of any kind, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. No oral or written information or advice given by Sabre, its agents or employees shall create a warranty or in any way increase the scope of this warranty, and you may not rely on any such information or advice.
|
68
|
+
Sabre does not warrant, guarantee, or make any representations regarding the use, or the results of the use, of this software, compiled programs created using this software, or written materials in terms of correctness, accuracy, reliability, currentness, or otherwise. The entire risk as to the results and performance of this software and any compiled applications created using this software is assumed by you. Neither Sabre nor anyone else who has been involved in the creation, production or delivery of this software shall be liable for any direct, indirect, consequential, or incidental damages (including damages for loss of business profits, business interruption, loss of business information, and the like) arising out of the use of or inability to use such product even if Sabre has been advised of the possibility of such damages.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList['test/*test.rb']
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Run tests"
|
12
|
+
task :default => :test
|
13
|
+
|
14
|
+
RDoc::Task.new do |rdoc|
|
15
|
+
rdoc.main = 'README.md'
|
16
|
+
rdoc.title = 'Sabre Dev Studio Base Gem'
|
17
|
+
rdoc.options << '--line-numbers --inline-source'
|
18
|
+
rdoc.rdoc_dir = 'doc'
|
19
|
+
rdoc.rdoc_files.include('README.md', 'lib/*.rb', 'lib/**')
|
20
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require File.expand_path("../sabre_dev_studio/base", __FILE__)
|
2
|
+
require File.expand_path("../sabre_dev_studio/error", __FILE__)
|
3
|
+
require File.expand_path("../sabre_dev_studio/helpers/date", __FILE__)
|
4
|
+
require File.expand_path("../sabre_dev_studio/request_object", __FILE__)
|
5
|
+
require File.expand_path("../sabre_dev_studio/version", __FILE__)
|
6
|
+
|
7
|
+
module SabreDevStudio
|
8
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module SabreDevStudio
|
5
|
+
class << self
|
6
|
+
attr_accessor :configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.configure
|
10
|
+
self.configuration ||= Configuration.new
|
11
|
+
yield(configuration)
|
12
|
+
end
|
13
|
+
|
14
|
+
class Configuration
|
15
|
+
attr_accessor :user, :group, :domain, :password, :uri
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Base
|
22
|
+
include HTTParty
|
23
|
+
|
24
|
+
@@token = nil
|
25
|
+
|
26
|
+
def self.access_token
|
27
|
+
@@token
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get_access_token
|
31
|
+
user = SabreDevStudio.configuration.user
|
32
|
+
group = SabreDevStudio.configuration.group
|
33
|
+
domain = SabreDevStudio.configuration.domain
|
34
|
+
client_id = Base64.strict_encode64("V1:#{user}:#{group}:#{domain}")
|
35
|
+
client_secret = Base64.strict_encode64(SabreDevStudio.configuration.password)
|
36
|
+
credentials = Base64.strict_encode64("#{client_id}:#{client_secret}")
|
37
|
+
headers = { 'Authorization' => "Basic #{credentials}" }
|
38
|
+
req = post("#{SabreDevStudio.configuration.uri}/v1/auth/token",
|
39
|
+
:body => { :grant_type => 'client_credentials' },
|
40
|
+
:ssl_version => :TLSv1,
|
41
|
+
:verbose => true,
|
42
|
+
:headers => headers)
|
43
|
+
@@token = req['access_token']
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.get(path, options = {})
|
47
|
+
attempt = 0
|
48
|
+
begin
|
49
|
+
attempt += 1
|
50
|
+
get_access_token if @@token.nil?
|
51
|
+
headers = {
|
52
|
+
'Authorization' => "Bearer #{@@token}",
|
53
|
+
'Accept-Encoding' => 'gzip'
|
54
|
+
}
|
55
|
+
data = super(
|
56
|
+
SabreDevStudio.configuration.uri + path,
|
57
|
+
:query => options[:query],
|
58
|
+
:ssl_version => :TLSv1,
|
59
|
+
:headers => headers
|
60
|
+
)
|
61
|
+
verify_response(data)
|
62
|
+
return data
|
63
|
+
rescue SabreDevStudio::Unauthorized
|
64
|
+
if attempt == 1
|
65
|
+
get_access_token
|
66
|
+
retry
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def self.verify_response(data)
|
74
|
+
# NOTE: should all of these raise or should some reissue the request?
|
75
|
+
case data.response.code.to_i
|
76
|
+
when 200
|
77
|
+
# nothing to see here, please move on
|
78
|
+
return
|
79
|
+
when 400
|
80
|
+
raise SabreDevStudio::BadRequest.new(data)
|
81
|
+
when 401
|
82
|
+
raise SabreDevStudio::Unauthorized.new(data)
|
83
|
+
when 403
|
84
|
+
raise SabreDevStudio::Forbidden.new(data)
|
85
|
+
when 404
|
86
|
+
raise SabreDevStudio::NotFound.new(data)
|
87
|
+
when 406
|
88
|
+
raise SabreDevStudio::NotAcceptable.new(data)
|
89
|
+
when 429
|
90
|
+
raise SabreDevStudio::RateLimited.new(data)
|
91
|
+
when 500
|
92
|
+
raise SabreDevStudio::InternalServerError.new(data)
|
93
|
+
when 503
|
94
|
+
raise SabreDevStudio::ServiceUnavailable.new(data)
|
95
|
+
when 504
|
96
|
+
raise SabreDevStudio::GatewayTimeout.new(data)
|
97
|
+
else
|
98
|
+
raise SabreDevStudio::Error.new(data)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SabreDevStudio
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :data
|
4
|
+
def initialize(data)
|
5
|
+
super(data)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class BadRequest < Error # 400
|
10
|
+
def initialize(data)
|
11
|
+
super("(#{data['type']}): #{data['message']}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
class Unauthorized < Error; end # 401
|
15
|
+
class Forbidden < Error; end # 403
|
16
|
+
class NotFound < Error; end # 404
|
17
|
+
class NotAcceptable < Error; end # 406
|
18
|
+
class RateLimited < Error; end # 429
|
19
|
+
class InternalServerError < Error; end # 500
|
20
|
+
class ServiceUnavailable < Error; end # 503
|
21
|
+
class GatewayTimeout < Error; end # 504
|
22
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
##
|
2
|
+
# NOTE: Hashie does not make it easy to write a custom KeyConversion.
|
3
|
+
# So here we are. :construction_worker: :arrow_heading_down:
|
4
|
+
|
5
|
+
##
|
6
|
+
# Reopen String to underscore the camel-cased strings. Miss you ActiveSupport.
|
7
|
+
module Underscore
|
8
|
+
def underscore
|
9
|
+
word = self.dup
|
10
|
+
word.gsub!(/::/, '/')
|
11
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
12
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
13
|
+
word.tr!("-", "_")
|
14
|
+
word.downcase!
|
15
|
+
word
|
16
|
+
end
|
17
|
+
end
|
18
|
+
String.send :include, Underscore
|
19
|
+
|
20
|
+
##
|
21
|
+
# Reopen Hash to lowercase the keys.
|
22
|
+
# Hashie does not have a KeyConversion for that
|
23
|
+
module KeyConversion
|
24
|
+
def downcase_keys!
|
25
|
+
keys.each do |k|
|
26
|
+
downcase_keys_recursively!(self[k])
|
27
|
+
self[k.to_s.underscore.downcase] = delete(k)
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return a new hash with all keys converted
|
33
|
+
# to downcase strings.
|
34
|
+
def downcase_keys
|
35
|
+
dup.downcase_keys!
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# Downcase all keys recursively within nested
|
41
|
+
# hashes and arrays.
|
42
|
+
def downcase_keys_recursively!(object)
|
43
|
+
if self.class === object
|
44
|
+
object.downcase_keys!
|
45
|
+
elsif ::Array === object
|
46
|
+
object.each do |i|
|
47
|
+
downcase_keys_recursively!(i)
|
48
|
+
end
|
49
|
+
object
|
50
|
+
elsif object.respond_to?(:downcase_keys!)
|
51
|
+
object.downcase_keys!
|
52
|
+
else
|
53
|
+
object
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
Hash.send :include, KeyConversion
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SabreDevStudio
|
2
|
+
module Helpers
|
3
|
+
module DateExtensions
|
4
|
+
# "2013-01-21"
|
5
|
+
def self.make_date(str)
|
6
|
+
Date.strptime(str, "%Y-%m-%d")
|
7
|
+
end
|
8
|
+
|
9
|
+
# "2013-01-21T17:00:00 -5"
|
10
|
+
def self.make_time(str, gmt_offset)
|
11
|
+
DateTime.strptime("#{str} #{gmt_offset}", "%Y-%m-%dT%H:%M:%S %z")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require File.expand_path("../hashie_key_conversion", __FILE__)
|
3
|
+
|
4
|
+
module SabreDevStudio
|
5
|
+
##
|
6
|
+
# Base RequestObject that other API objects can inherit from
|
7
|
+
#
|
8
|
+
# ==== Example:
|
9
|
+
# module SabreDevStudio
|
10
|
+
# module Flight
|
11
|
+
# class TravelThemeLookup < SabreDevStudio::RequestObject
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
class RequestObject < Hash
|
16
|
+
attr_reader :response
|
17
|
+
|
18
|
+
def initialize(endpoint, options = {})
|
19
|
+
@response = SabreDevStudio::Base.get(endpoint, :query => options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(meth, *args, &block)
|
23
|
+
if hashie.respond_to?(meth)
|
24
|
+
hashie.send(meth)
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to?(meth)
|
31
|
+
if hashie.respond_to?(meth)
|
32
|
+
true
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def hashie
|
40
|
+
unless @hashie
|
41
|
+
@hashie ||= Hashie::Mash.new(@response.parsed_response).downcase_keys
|
42
|
+
end
|
43
|
+
@hashie
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sabre_dev_studio/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "sabre_dev_studio"
|
8
|
+
gem.version = SabreDevStudio::VERSION
|
9
|
+
gem.authors = ["Barrett Clark"]
|
10
|
+
gem.email = ["barrett.clark@sabre.com"]
|
11
|
+
gem.description = %q{Sabre Travel Platform Services (TPS) Dev Studio Base Gem}
|
12
|
+
gem.summary = %q{Base gem for Sabre Dev Studio API wrappers}
|
13
|
+
gem.homepage = "http://developer.sabre.com"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'webmock'
|
21
|
+
gem.add_development_dependency 'geminabox'
|
22
|
+
gem.add_development_dependency 'rdoc'
|
23
|
+
gem.add_runtime_dependency 'multi_json'
|
24
|
+
gem.add_runtime_dependency 'httparty'
|
25
|
+
gem.add_runtime_dependency 'hashie'
|
26
|
+
end
|
data/test/date_test.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class SabreDevStudio::Helpers::DateExtensionTests < Test::Unit::TestCase
|
4
|
+
def test_make_date
|
5
|
+
str = "2013-01-21"
|
6
|
+
date = SabreDevStudio::Helpers::DateExtensions.make_date(str)
|
7
|
+
assert_equal str, date.to_s
|
8
|
+
assert_equal 2013, date.year
|
9
|
+
end
|
10
|
+
def test_make_date_time
|
11
|
+
str = "2013-01-21T17:00:00"
|
12
|
+
gmt_offset = -5
|
13
|
+
datetime = SabreDevStudio::Helpers::DateExtensions.make_time(str, gmt_offset)
|
14
|
+
assert_equal 2013, datetime.year
|
15
|
+
assert_equal "-05:00", datetime.strftime("%Z")
|
16
|
+
end
|
17
|
+
end
|
data/test/error_test.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class SabreDevStudio::Base
|
4
|
+
@@token = 1
|
5
|
+
end
|
6
|
+
class SabreDevStudio::ErrorTests < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
SabreDevStudio.configure do |c|
|
9
|
+
c.user = 'USER'
|
10
|
+
c.group = 'GROUP'
|
11
|
+
c.domain = 'DOMAIN'
|
12
|
+
c.password = 'PASSWORD'
|
13
|
+
c.uri = 'https://api.test.sabre.com'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def test_canned_response_400
|
17
|
+
assert_raise SabreDevStudio::BadRequest do
|
18
|
+
url = '/v1/shop/flights/fares?origin=ATL&destination=LAS'
|
19
|
+
stub_request(:get, SabreDevStudio.configuration.uri + url).
|
20
|
+
to_return(status: 400, body: "{\"status\":\"NotProcessed\",\"type\":\"Validation\",\"errorCode\":\"ERR.RAF.VALIDATION\",\"timeStamp\":\"2013-04-19T18:51:45+00:00\",\"message\":\"Parameter 'origin' must be specified\"}")
|
21
|
+
response = SabreDevStudio::Base.get(url)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
def test_401_retry
|
25
|
+
url = "/v1/shop/themes?"
|
26
|
+
token_url = "https://VjE6VVNFUjpHUk9VUDpET01BSU4%3D:UEFTU1dPUkQ%3D@api.test.sabre.com/v1/auth/token"
|
27
|
+
stub_request(:get, SabreDevStudio.configuration.uri + url).to_return(status: 401)
|
28
|
+
stub_request(:post, token_url).
|
29
|
+
to_return(:status => 200, :body =>"{\"access_token\":\"Shared/IDL:IceSess\\\\/SessMgr:1\\\\.0.IDL/Common/!ICESMS\\\\/ACPCRTD!ICESMSLB\\\\/CRT.LB!-3801964284027024638!507667!0!F557CBE649675!E2E-1\",\"token_type\":\"bearer\",\"expires_in\":1800}")
|
30
|
+
SabreDevStudio::Base.get(url)
|
31
|
+
assert_requested :get, SabreDevStudio.configuration.uri + url, :times => 2
|
32
|
+
assert_requested :post, token_url, :times => 1
|
33
|
+
end
|
34
|
+
def test_canned_response_404
|
35
|
+
assert_raise SabreDevStudio::NotFound do
|
36
|
+
url = '/v1/shop/themessssss?'
|
37
|
+
stub_request(:get, SabreDevStudio.configuration.uri + url).
|
38
|
+
to_return(status: 404)
|
39
|
+
SabreDevStudio::Base.get(url)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
{
|
2
|
+
"Themes": [
|
3
|
+
{
|
4
|
+
"Theme": "BEACH",
|
5
|
+
"Links": [
|
6
|
+
{
|
7
|
+
"rel": "destinations",
|
8
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/BEACH"
|
9
|
+
}
|
10
|
+
]
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"Theme": "DISNEY",
|
14
|
+
"Links": [
|
15
|
+
{
|
16
|
+
"rel": "destinations",
|
17
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/DISNEY"
|
18
|
+
}
|
19
|
+
]
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"Theme": "GAMBLING",
|
23
|
+
"Links": [
|
24
|
+
{
|
25
|
+
"rel": "destinations",
|
26
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/GAMBLING"
|
27
|
+
}
|
28
|
+
]
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"Theme": "HISTORIC",
|
32
|
+
"Links": [
|
33
|
+
{
|
34
|
+
"rel": "destinations",
|
35
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/HISTORIC"
|
36
|
+
}
|
37
|
+
]
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"Theme": "MOUNTAINS",
|
41
|
+
"Links": [
|
42
|
+
{
|
43
|
+
"rel": "destinations",
|
44
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/MOUNTAINS"
|
45
|
+
}
|
46
|
+
]
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"Theme": "NATIONAL-PARKS",
|
50
|
+
"Links": [
|
51
|
+
{
|
52
|
+
"rel": "destinations",
|
53
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/NATIONAL-PARKS"
|
54
|
+
}
|
55
|
+
]
|
56
|
+
},
|
57
|
+
{
|
58
|
+
"Theme": "OUTDOORS",
|
59
|
+
"Links": [
|
60
|
+
{
|
61
|
+
"rel": "destinations",
|
62
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/OUTDOORS"
|
63
|
+
}
|
64
|
+
]
|
65
|
+
},
|
66
|
+
{
|
67
|
+
"Theme": "ROMANTIC",
|
68
|
+
"Links": [
|
69
|
+
{
|
70
|
+
"rel": "destinations",
|
71
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/ROMANTIC"
|
72
|
+
}
|
73
|
+
]
|
74
|
+
},
|
75
|
+
{
|
76
|
+
"Theme": "SHOPPING",
|
77
|
+
"Links": [
|
78
|
+
{
|
79
|
+
"rel": "destinations",
|
80
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/SHOPPING"
|
81
|
+
}
|
82
|
+
]
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"Theme": "SKIING",
|
86
|
+
"Links": [
|
87
|
+
{
|
88
|
+
"rel": "destinations",
|
89
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/SKIING"
|
90
|
+
}
|
91
|
+
]
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"Theme": "THEME-PARK",
|
95
|
+
"Links": [
|
96
|
+
{
|
97
|
+
"rel": "destinations",
|
98
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes/THEME-PARK"
|
99
|
+
}
|
100
|
+
]
|
101
|
+
}
|
102
|
+
],
|
103
|
+
"Links": [
|
104
|
+
{
|
105
|
+
"rel": "self",
|
106
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes"
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"rel": "linkTemplate",
|
110
|
+
"href": "http://ctovm2454.dev.sabre.com:8080/cto-darwin-raf/v1/shop/themes"
|
111
|
+
}
|
112
|
+
]
|
113
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path("../test_helper", __FILE__)
|
2
|
+
|
3
|
+
class SabreDevStudio::Base
|
4
|
+
@@token = 1
|
5
|
+
end
|
6
|
+
|
7
|
+
class SabreDevStudio::Base::BaseTests < Test::Unit::TestCase
|
8
|
+
def setup
|
9
|
+
SabreDevStudio.configure do |c|
|
10
|
+
c.user = 'USER'
|
11
|
+
c.group = 'GROUP'
|
12
|
+
c.domain = 'DOMAIN'
|
13
|
+
c.password = 'PASSWORD'
|
14
|
+
c.uri = 'https://api.test.sabre.com'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_canned_request_success
|
19
|
+
stub_request(:get, "#{SabreDevStudio.configuration.uri}/v1/shop/themes").
|
20
|
+
to_return(json_response('air_shopping_themes.json'))
|
21
|
+
themes = SabreDevStudio::Base.get('/v1/shop/themes')
|
22
|
+
assert_equal 'BEACH', themes['Themes'].first['Theme']
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_request_object
|
26
|
+
stub_request(:get, "#{SabreDevStudio.configuration.uri}/v1/shop/themes").
|
27
|
+
to_return(json_response('air_shopping_themes.json'))
|
28
|
+
endpoint = '/v1/shop/themes'
|
29
|
+
request = SabreDevStudio::RequestObject.new(endpoint)
|
30
|
+
assert_equal 'self', request.links.first.rel
|
31
|
+
assert_equal 'BEACH', request.themes.first.theme
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'bundler'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'webmock/test_unit'
|
6
|
+
require 'addressable/uri'
|
7
|
+
|
8
|
+
Bundler.require
|
9
|
+
|
10
|
+
# thank you octokit
|
11
|
+
def fixture_path
|
12
|
+
File.expand_path("../fixtures", __FILE__)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fixture(file)
|
16
|
+
File.new(fixture_path + '/' + file)
|
17
|
+
end
|
18
|
+
|
19
|
+
def json_from_fixture(file)
|
20
|
+
json = fixture(file).read
|
21
|
+
JSON.parse(json)
|
22
|
+
end
|
23
|
+
|
24
|
+
def json_response(file)
|
25
|
+
{
|
26
|
+
:body => fixture(file),
|
27
|
+
:headers => {
|
28
|
+
:content_type => 'application/json; charset=utf-8'
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sabre_dev_studio
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Barrett Clark
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: webmock
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: geminabox
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: multi_json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: httparty
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: hashie
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Sabre Travel Platform Services (TPS) Dev Studio Base Gem
|
98
|
+
email:
|
99
|
+
- barrett.clark@sabre.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- lib/sabre_dev_studio.rb
|
110
|
+
- lib/sabre_dev_studio/base.rb
|
111
|
+
- lib/sabre_dev_studio/error.rb
|
112
|
+
- lib/sabre_dev_studio/hashie_key_conversion.rb
|
113
|
+
- lib/sabre_dev_studio/helpers/date.rb
|
114
|
+
- lib/sabre_dev_studio/request_object.rb
|
115
|
+
- lib/sabre_dev_studio/version.rb
|
116
|
+
- sabre_dev_studio.gemspec
|
117
|
+
- test/date_test.rb
|
118
|
+
- test/error_test.rb
|
119
|
+
- test/fixtures/air_shopping_themes.json
|
120
|
+
- test/request_test.rb
|
121
|
+
- test/test_helper.rb
|
122
|
+
homepage: http://developer.sabre.com
|
123
|
+
licenses: []
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
requirements: []
|
140
|
+
rubyforge_project:
|
141
|
+
rubygems_version: 2.0.6
|
142
|
+
signing_key:
|
143
|
+
specification_version: 4
|
144
|
+
summary: Base gem for Sabre Dev Studio API wrappers
|
145
|
+
test_files:
|
146
|
+
- test/date_test.rb
|
147
|
+
- test/error_test.rb
|
148
|
+
- test/fixtures/air_shopping_themes.json
|
149
|
+
- test/request_test.rb
|
150
|
+
- test/test_helper.rb
|