passtools 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # PassTools
2
2
 
3
- Simple ruby wrapper for the PassTools API. API documentation can be
4
- found at the main [PassTools API wiki](https://github.com/tello/passtools-api/wiki/Methods)
3
+ * Simple ruby wrapper for the PassTools API.
4
+ * API documentation can be found at the main [PassTools API wiki](https://github.com/tello/passtools-api/wiki/Methods)
5
+ * Indexed documentation for the Ruby SDK is available at [http://tello.github.com/passtools-ruby/](http://tello.github.com/passtools-ruby/).
6
+
5
7
 
6
8
  ## Installation
7
9
 
@@ -101,7 +103,44 @@ Passtools::Pass.create(5, data)
101
103
  You could use the same hash with the update call to edit values in an
102
104
  existing Pass based on the same template.
103
105
 
106
+ ## Using utility objects
107
+
108
+ There are some additional methods wrapping the data returned and
109
+ creating an instantiated object that provides some methods for
110
+ convenience
111
+
112
+ There are three constructors:
113
+
114
+ `Passtools::Template.build_from_current(template_id)`
115
+
116
+ returns a Template instance that has read only accessors for the raw
117
+ data, id, field names, and a field data hash that can be used for Pass
118
+ creation.
119
+
120
+ `Passtools::Pass.build_from_current(pass_id)`
121
+
122
+ returns a Pass instance that has read only accessors for id and
123
+ template id. It also has read/write accessors for the raw data
124
+ returned and each of the fields. Changes to either the raw data or the
125
+ fields can be persisted with the #update method.
104
126
 
127
+ `Passtools::Pass.build_from_template(@template_instance)`
128
+
129
+ returns a templated Pass instance that has the same accessors as above.
130
+ This instance can be persisted with the #create method. Once it
131
+ persisted, further changes must be persisted with the #update method
132
+
133
+ ## Usage
134
+
135
+ Given the same example as above you could:
136
+
137
+ ```
138
+ template = Passtools::Template.build_from_current(5)
139
+ pass = Passtools::Pass.build_from_template(template)
140
+ pass.first_name['value'] = 'Abraham'
141
+ pass.last_name['value] = 'Lincoln'
142
+ pass.create
143
+ ```
105
144
 
106
145
  ## Contributing
107
146
 
@@ -13,11 +13,13 @@ module Passtools
13
13
  class << self
14
14
  attr_accessor :api_key, :url, :download_dir
15
15
  end
16
+
16
17
  # Configure through hash
17
18
  def self.configure(opts = {})
18
19
  opts.each {|k,v| instance_variable_set("@#{k}",v) }
19
20
  end
20
21
 
22
+ # Configure with yaml file
21
23
  def self.configure_from_file(pathname)
22
24
  config = YAML::load(IO.read(pathname))
23
25
  configure(config)
@@ -1,6 +1,7 @@
1
1
  module Passtools
2
2
  class Pass
3
3
  extend Request
4
+ attr_accessor :raw_data
4
5
 
5
6
  def self.list
6
7
  get("/pass")
@@ -28,6 +29,57 @@ module Passtools
28
29
  download_file("/pass/#{pass_id}/download", 'PassToolsPass.pkpass')
29
30
  end
30
31
 
31
- end
32
+ def self.build_from_current(pass_id)
33
+ begin
34
+ response = show(pass_id)
35
+ self.new(response)
36
+ rescue RestClient::Exception => e
37
+ data = MultiJson.load(e.response)
38
+ data['message'] = e.message
39
+ new(data)
40
+ end
41
+ end
32
42
 
43
+ def self.build_from_template(template)
44
+ @raw_data = {}
45
+ @raw_data['templateId'] = template.id
46
+ @raw_data['passFields'] = template.fields
47
+ self.new(@raw_data)
48
+ end
49
+
50
+ def initialize(raw_data)
51
+ @raw_data = raw_data
52
+ fields = Array(@raw_data['passFields'])
53
+ fields.each do |k,v|
54
+ # self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
55
+ define_singleton_method k, proc{ @raw_data["passFields"][k.to_s] }
56
+ define_singleton_method "#{k}=", proc{ |v| @raw_data["passFields"][k.to_s] = v}
57
+ end
58
+ end
59
+
60
+ def id
61
+ @raw_data["id"]
62
+ end
63
+
64
+ def template_id
65
+ @raw_data["templateId"]
66
+ end
67
+
68
+ def valid?
69
+ @raw_data.has_key?('id')
70
+ end
71
+
72
+ def create
73
+ return false if self.id
74
+ response = self.class.create(template_id, @raw_data["passFields"])
75
+ new_id = response['id']
76
+ self.raw_data = response if new_id
77
+ end
78
+
79
+ def update
80
+ return false unless self.id
81
+ self.class.update(id, @raw_data["passFields"])
82
+ end
83
+
84
+ end
33
85
  end
@@ -1,15 +1,55 @@
1
1
  module Passtools
2
2
  class Template
3
3
  extend Request
4
+ attr_accessor :raw_data
4
5
 
5
6
  def self.list
6
7
  get("/template/headers")
7
8
  end
8
-
9
9
 
10
10
  def self.show(template_id)
11
11
  get("/template/#{template_id}")
12
12
  end
13
- end
14
13
 
14
+ def self.build_from_current(template_id)
15
+ begin
16
+ response = show(template_id)
17
+ new(response)
18
+ rescue RestClient::Exception => e
19
+ data = MultiJson.load(e.response)
20
+ data['message'] = e.message
21
+ new(data)
22
+ end
23
+ end
24
+
25
+ def initialize(raw_data)
26
+ @raw_data = raw_data
27
+ end
28
+
29
+ def id
30
+ fetch_from_raw('templateHeader','id')
31
+ end
32
+
33
+ # return array of field names
34
+ def field_names
35
+ fetch_from_raw('fieldsModel').keys
36
+ end
37
+
38
+ # return hash required for creating a Pass based on this template
39
+ def fields
40
+ fetch_from_raw('fieldsModel')
41
+ end
42
+
43
+ def fetch_from_raw(*args)
44
+ data = @raw_data
45
+ res = nil
46
+ args.each { |a| data = data.fetch(a, {}); res = data }
47
+ res
48
+ end
49
+
50
+ def valid?
51
+ @raw_data.has_key?('fieldsModel')
52
+ end
53
+
54
+ end
15
55
  end
@@ -1,3 +1,3 @@
1
1
  module Passtools
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -28,7 +28,7 @@ describe 'Pass' do
28
28
  stub = stub_get("http://foobar.com/pass/55/download", 'contents of pass')
29
29
 
30
30
  Passtools::Pass.download(55)
31
- File.open("PassToolsPass.pkpass", 'r').read.should == "contents of pass"
31
+ File.open("PassToolsPass.pkpass", 'r').read.should == "\"contents of pass\""
32
32
  end
33
33
 
34
34
  it "calls Passtools API to create new Pass" do
@@ -66,4 +66,57 @@ describe 'Pass' do
66
66
  expect {Passtools::Pass.list}.to raise_error(RuntimeError, /You must configure api_key before calling/)
67
67
  end
68
68
 
69
+ context "The Pass instance" do
70
+ context 'when built from succesful api call' do
71
+ before(:all) do
72
+ Passtools.configure(:url => 'http://foobar.com',
73
+ :api_key => 'i_am_an_api_key')
74
+ @data = {"id" => 10,
75
+ "templateId" => 55,
76
+ "passFields" => {"first_name" => {"value" => "first", "required" => false},
77
+ "last_name" => {"value" => "last", "required" => true}}
78
+ }
79
+ stub = stub_get("http://foobar.com/pass/10",@data)
80
+ @pass = Passtools::Pass.build_from_current(10)
81
+ end
82
+
83
+ it "should be valid" do
84
+ @pass.valid?.should be_true
85
+ end
86
+
87
+ it "should return id" do
88
+ @pass.id.should == 10
89
+ end
90
+
91
+ it "should return template id" do
92
+ @pass.template_id.should == 55
93
+ end
94
+
95
+ it "should have read accessor for field name data" do
96
+ @pass.first_name.should == {"value" => "first", "required" => false}
97
+ end
98
+
99
+ it "should have write accessor for field name" do
100
+ @pass.last_name = {"value" => "last_name", "required" => false}
101
+ @pass.last_name.should == {"value" => "last_name", "required" => false}
102
+ end
103
+
104
+ end
105
+ context "when built from failed api call" do
106
+
107
+ it "should capture error information" do
108
+ stub_error("http://foobar.com/pass/10", 400)
109
+ @pass = Passtools::Pass.build_from_current(10)
110
+ @pass.raw_data['message'].should == "400 Bad Request"
111
+ end
112
+
113
+ it "should not be valid" do
114
+ stub_error("http://foobar.com/pass/10", 400)
115
+ @pass = Passtools::Pass.build_from_current(10)
116
+ @pass.valid?.should be_false
117
+ end
118
+
119
+ end
120
+ end
121
+
69
122
  end
@@ -20,5 +20,52 @@ describe 'Template' do
20
20
  Passtools::Template.show(55)
21
21
  stub.should have_been_requested
22
22
  end
23
+
24
+ context "The Template instance" do
25
+ context 'when built from succesful api call' do
26
+ before(:all) do
27
+ @data = {"templateHeader" => {"id" => 55},
28
+ "fieldsModel" => {"first_name" => {"value" => "first", "required" => false},
29
+ "last_name" => {"value" => "last", "required" => true}}
30
+ }
31
+ stub = stub_get("http://foobar.com/template/55",@data)
32
+ @template = Passtools::Template.build_from_current(55)
33
+ end
34
+
35
+ it "should return id" do
36
+ @template.id.should == 55
37
+ end
38
+
39
+ it "should be valid" do
40
+ @template.valid?.should be_true
41
+ end
42
+
43
+ it "should return the correct field names" do
44
+ @template.field_names.should == ['first_name', 'last_name']
45
+ end
46
+
47
+ it "should return the correct complete field data" do
48
+ @template.fields.should == @data['fieldsModel']
49
+ end
50
+
51
+ end
52
+ context "when built from failed api call" do
53
+ before(:all) do
54
+ end
55
+
56
+ it "should capture error information" do
57
+ stub_error("http://foobar.com/template/55", 400)
58
+ @template = Passtools::Template.build_from_current(55)
59
+ @template.raw_data['message'].should == "400 Bad Request"
60
+ end
61
+
62
+ it "should not be valid" do
63
+ stub_error("http://foobar.com/template/55", 400)
64
+ @template = Passtools::Template.build_from_current(55)
65
+ @template.valid?.should be_false
66
+ end
67
+
68
+ end
69
+ end
23
70
 
24
71
  end
@@ -1,9 +1,9 @@
1
1
  module PasstoolsHelpers
2
2
 
3
- def stub_get(url, body='{}')
3
+ def stub_get(url, body={})
4
4
  stub_request(:get, url).
5
5
  with(:query => {:api_key => 'i_am_an_api_key'}).
6
- to_return(:body => body)
6
+ to_return(:body => MultiJson.dump(body))
7
7
  end
8
8
 
9
9
  def stub_write(request_type, url, json)
@@ -13,6 +13,14 @@ module PasstoolsHelpers
13
13
  to_return(:body => "{}")
14
14
  end
15
15
 
16
+
17
+ def stub_error(url, error)
18
+ stub_request(:get, url).
19
+ with(:query => {:api_key => 'i_am_an_api_key'}).
20
+ to_return(:status => [error],
21
+ :body => "{\"code\":400,\"description\":\"Invalid Request Parameters.\",\"details\":\"template with id 999 was not found!\"}")
22
+ end
23
+
16
24
  end
17
25
 
18
26
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passtools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-06 00:00:00.000000000 Z
12
+ date: 2012-11-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -159,3 +159,4 @@ test_files:
159
159
  - spec/passtools/template_spec.rb
160
160
  - spec/spec_helper.rb
161
161
  - spec/support/passtools_helpers.rb
162
+ has_rdoc: