podio 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/README.md +36 -5
  2. data/Rakefile +3 -1
  3. data/lib/podio/active_podio/base.rb +311 -0
  4. data/lib/podio/active_podio/updatable.rb +22 -0
  5. data/lib/podio/client.rb +7 -4
  6. data/lib/podio/error.rb +1 -0
  7. data/lib/podio/middleware/error_response.rb +5 -1
  8. data/lib/podio/middleware/response_recorder.rb +1 -1
  9. data/lib/podio/models/app_store_share.rb +67 -0
  10. data/lib/podio/{areas → models}/application.rb +23 -7
  11. data/lib/podio/models/application_email.rb +22 -0
  12. data/lib/podio/models/application_field.rb +17 -0
  13. data/lib/podio/{areas → models}/bulletin.rb +16 -5
  14. data/lib/podio/models/by_line.rb +11 -0
  15. data/lib/podio/models/category.rb +49 -0
  16. data/lib/podio/models/comment.rb +63 -0
  17. data/lib/podio/{areas → models}/connection.rb +20 -4
  18. data/lib/podio/models/contact.rb +10 -0
  19. data/lib/podio/models/conversation.rb +72 -0
  20. data/lib/podio/models/conversation_message.rb +12 -0
  21. data/lib/podio/models/conversation_participant.rb +9 -0
  22. data/lib/podio/models/email_subscription_setting.rb +39 -0
  23. data/lib/podio/models/embed.rb +34 -0
  24. data/lib/podio/models/file_attachment.rb +127 -0
  25. data/lib/podio/models/form.rb +25 -0
  26. data/lib/podio/{areas → models}/hook.rb +15 -5
  27. data/lib/podio/{areas → models}/importer.rb +4 -6
  28. data/lib/podio/{areas → models}/integration.rb +40 -4
  29. data/lib/podio/models/item.rb +122 -0
  30. data/lib/podio/models/item_diff.rb +16 -0
  31. data/lib/podio/models/item_field.rb +19 -0
  32. data/lib/podio/models/item_revision.rb +18 -0
  33. data/lib/podio/models/news.rb +83 -0
  34. data/lib/podio/models/notification.rb +47 -0
  35. data/lib/podio/models/notification_group.rb +19 -0
  36. data/lib/podio/models/o_auth.rb +32 -0
  37. data/lib/podio/models/o_auth_client.rb +93 -0
  38. data/lib/podio/{areas → models}/organization.rb +39 -6
  39. data/lib/podio/models/organization_contact.rb +14 -0
  40. data/lib/podio/{areas → models}/organization_member.rb +13 -5
  41. data/lib/podio/models/organization_profile.rb +61 -0
  42. data/lib/podio/{areas/contact.rb → models/profile.rb} +23 -6
  43. data/lib/podio/{areas → models}/rating.rb +5 -7
  44. data/lib/podio/{areas → models}/search.rb +6 -7
  45. data/lib/podio/models/space.rb +45 -0
  46. data/lib/podio/models/space_contact.rb +23 -0
  47. data/lib/podio/models/space_invite.rb +57 -0
  48. data/lib/podio/models/space_member.rb +32 -0
  49. data/lib/podio/models/status.rb +35 -0
  50. data/lib/podio/{areas → models}/subscription.rb +8 -7
  51. data/lib/podio/{areas → models}/tag.rb +14 -7
  52. data/lib/podio/models/task.rb +153 -0
  53. data/lib/podio/models/task_label.rb +50 -0
  54. data/lib/podio/models/user.rb +66 -0
  55. data/lib/podio/models/user_status.rb +18 -0
  56. data/lib/podio/models/via.rb +7 -0
  57. data/lib/podio/{areas → models}/widget.rb +9 -5
  58. data/lib/podio/version.rb +1 -1
  59. data/lib/podio.rb +97 -39
  60. data/podio.gemspec +4 -3
  61. data/test/active_podio_test.rb +256 -0
  62. data/test/client_test.rb +20 -15
  63. data/test/fixtures/client/18a224aaf83ac57a7b8159cecdbb1263.rack +1 -0
  64. data/test/fixtures/client/a87c69a0624af0413a670094c6615651.rack +1 -0
  65. data/test/fixtures/client/ac493997db62308972c208afa76f8479.rack +1 -0
  66. data/test/fixtures/client/d7fbf422c77af768552423633d0389e8.rack +1 -0
  67. data/test/fixtures/client/e2d68afe39f5531195273ea259b63916.rack +1 -0
  68. data/test/fixtures/fixtures.yaml +34 -0
  69. data/test/models_sanity_test.rb +19 -0
  70. data/test/test_helper.rb +22 -28
  71. metadata +89 -64
  72. data/lib/podio/areas/app_store.rb +0 -69
  73. data/lib/podio/areas/comment.rb +0 -36
  74. data/lib/podio/areas/conversation.rb +0 -39
  75. data/lib/podio/areas/email.rb +0 -24
  76. data/lib/podio/areas/file.rb +0 -81
  77. data/lib/podio/areas/form.rb +0 -11
  78. data/lib/podio/areas/item.rb +0 -68
  79. data/lib/podio/areas/notification.rb +0 -39
  80. data/lib/podio/areas/oauth.rb +0 -107
  81. data/lib/podio/areas/organization_profile.rb +0 -32
  82. data/lib/podio/areas/space.rb +0 -77
  83. data/lib/podio/areas/status.rb +0 -19
  84. data/lib/podio/areas/task.rb +0 -108
  85. data/lib/podio/areas/user.rb +0 -31
  86. data/lib/podio/areas/user_status.rb +0 -11
data/lib/podio.rb CHANGED
@@ -10,6 +10,9 @@ require 'podio/middleware/json_response'
10
10
  require 'podio/middleware/error_response'
11
11
  require 'podio/middleware/response_recorder'
12
12
 
13
+ require 'podio/active_podio/base'
14
+ require 'podio/active_podio/updatable'
15
+
13
16
  module Podio
14
17
  class << self
15
18
  def setup(options={})
@@ -25,7 +28,7 @@ module Podio
25
28
  end
26
29
 
27
30
  def with_client
28
- old_client = Podio.client.dup
31
+ old_client = Podio.client.try(:dup)
29
32
  yield
30
33
  ensure
31
34
  Podio.client = old_client
@@ -60,43 +63,98 @@ module Podio
60
63
  end
61
64
  end
62
65
 
63
- autoload :Client, 'podio/client'
64
- autoload :ResponseWrapper, 'podio/response_wrapper'
66
+ autoload :Client, 'podio/client'
67
+ autoload :ResponseWrapper, 'podio/response_wrapper'
68
+
69
+ autoload :AppStoreShare, 'podio/models/app_store_share'
70
+ autoload :Application, 'podio/models/application'
71
+ autoload :ApplicationEmail, 'podio/models/application_email'
72
+ autoload :ApplicationField, 'podio/models/application_field'
73
+ autoload :Bulletin, 'podio/models/bulletin'
74
+ autoload :ByLine, 'podio/models/by_line'
75
+ autoload :Category, 'podio/models/category'
76
+ autoload :Comment, 'podio/models/comment'
77
+ autoload :Connection, 'podio/models/connection'
78
+ autoload :Contact, 'podio/models/contact'
79
+ autoload :Conversation, 'podio/models/conversation'
80
+ autoload :ConversationMessage, 'podio/models/conversation_message'
81
+ autoload :ConversationParticipant, 'podio/models/conversation_participant'
82
+ autoload :EmailSubscriptionSetting, 'podio/models/email_subscription_setting'
83
+ autoload :Embed, 'podio/models/embed'
84
+ autoload :FileAttachment, 'podio/models/file_attachment'
85
+ autoload :Form, 'podio/models/form'
86
+ autoload :Hook, 'podio/models/hook'
87
+ autoload :Importer, 'podio/models/importer'
88
+ autoload :Integration, 'podio/models/integration'
89
+ autoload :Item, 'podio/models/item'
90
+ autoload :ItemDiff, 'podio/models/item_diff'
91
+ autoload :ItemField, 'podio/models/item_field'
92
+ autoload :ItemRevision, 'podio/models/item_revision'
93
+ autoload :News, 'podio/models/news'
94
+ autoload :Notification, 'podio/models/notification'
95
+ autoload :NotificationGroup, 'podio/models/notification_group'
96
+ autoload :OAuth, 'podio/models/o_auth'
97
+ autoload :OAuthClient, 'podio/models/o_auth_client'
98
+ autoload :Organization, 'podio/models/organization'
99
+ autoload :OrganizationContact, 'podio/models/organization_contact'
100
+ autoload :OrganizationMember, 'podio/models/organization_member'
101
+ autoload :OrganizationProfile, 'podio/models/organization_profile'
102
+ autoload :Profile, 'podio/models/profile'
103
+ autoload :Rating, 'podio/models/rating'
104
+ autoload :Search, 'podio/models/search'
105
+ autoload :Space, 'podio/models/space'
106
+ autoload :SpaceContact, 'podio/models/space_contact'
107
+ autoload :SpaceInvite, 'podio/models/space_invite'
108
+ autoload :SpaceMember, 'podio/models/space_member'
109
+ autoload :Status, 'podio/models/status'
110
+ autoload :Subscription, 'podio/models/subscription'
111
+ autoload :Tag, 'podio/models/tag'
112
+ autoload :Task, 'podio/models/task'
113
+ autoload :TaskLabel, 'podio/models/task_label'
114
+ autoload :User, 'podio/models/user'
115
+ autoload :UserStatus, 'podio/models/user_status'
116
+ autoload :Via, 'podio/models/via'
117
+ autoload :Widget, 'podio/models/widget'
118
+
65
119
 
66
- autoload :Application, 'podio/areas/application'
67
- autoload :Bulletin, 'podio/areas/bulletin'
68
- autoload :Category, 'podio/areas/app_store'
69
- autoload :AppStoreShare, 'podio/areas/app_store'
70
- autoload :Comment, 'podio/areas/comment'
71
- autoload :Connection, 'podio/areas/connection'
72
- autoload :Contact, 'podio/areas/contact'
73
- autoload :Conversation, 'podio/areas/conversation'
74
- autoload :Email, 'podio/areas/email'
75
- autoload :File, 'podio/areas/file'
76
- autoload :Form, 'podio/areas/form'
77
- autoload :Email, 'podio/areas/email'
78
- autoload :Hook, 'podio/areas/hook'
79
- autoload :Item, 'podio/areas/item'
80
- autoload :Importer, 'podio/areas/importer'
81
- autoload :Integration, 'podio/areas/integration'
82
- autoload :Notification, 'podio/areas/notification'
83
- autoload :NotificationGroup, 'podio/areas/notification'
84
- autoload :OAuth, 'podio/areas/oauth'
85
- autoload :OAuthClient, 'podio/areas/oauth'
86
- autoload :Organization, 'podio/areas/organization'
87
- autoload :OrganizationMember, 'podio/areas/organization_member'
88
- autoload :OrganizationProfile, 'podio/areas/organization_profile'
89
- autoload :Rating, 'podio/areas/rating'
90
- autoload :Search, 'podio/areas/search'
91
- autoload :Space, 'podio/areas/space'
92
- autoload :SpaceInvite, 'podio/areas/space'
93
- autoload :SpaceMember, 'podio/areas/space'
94
- autoload :Status, 'podio/areas/status'
95
- autoload :Subscription, 'podio/areas/subscription'
96
- autoload :Tag, 'podio/areas/tag'
97
- autoload :Task, 'podio/areas/task'
98
- autoload :TaskLabel, 'podio/areas/task'
99
- autoload :User, 'podio/areas/user'
100
- autoload :UserStatus, 'podio/areas/user_status'
101
- autoload :Widget, 'podio/areas/widget'
120
+ # autoload :Application, 'podio/areas/application'
121
+ # autoload :Bulletin, 'podio/areas/bulletin'
122
+ # autoload :Category, 'podio/areas/app_store'
123
+ # autoload :AppStoreShare, 'podio/areas/app_store'
124
+ # autoload :Comment, 'podio/areas/comment'
125
+ # autoload :Connection, 'podio/areas/connection'
126
+ # autoload :Contact, 'podio/areas/contact'
127
+ # autoload :Conversation, 'podio/areas/conversation'
128
+ # autoload :Email, 'podio/areas/email'
129
+ # autoload :File, 'podio/areas/file'
130
+ # autoload :Form, 'podio/areas/form'
131
+ # autoload :Email, 'podio/areas/email'
132
+ # autoload :Hook, 'podio/areas/hook'
133
+ # autoload :Item, 'podio/areas/item'
134
+ # autoload :ItemDiff, 'podio/areas/item'
135
+ # autoload :ItemField, 'podio/areas/item'
136
+ # autoload :ItemRevision, 'podio/areas/item'
137
+ # autoload :Importer, 'podio/areas/importer'
138
+ # autoload :Integration, 'podio/areas/integration'
139
+ # autoload :News, 'podio/areas/news'
140
+ # autoload :Notification, 'podio/areas/notification'
141
+ # autoload :NotificationGroup, 'podio/areas/notification'
142
+ # autoload :OAuth, 'podio/areas/oauth'
143
+ # autoload :OAuthClient, 'podio/areas/oauth'
144
+ # autoload :Organization, 'podio/areas/organization'
145
+ # autoload :OrganizationMember, 'podio/areas/organization_member'
146
+ # autoload :OrganizationProfile, 'podio/areas/organization_profile'
147
+ # autoload :Rating, 'podio/areas/rating'
148
+ # autoload :Search, 'podio/areas/search'
149
+ # autoload :Space, 'podio/areas/space'
150
+ # autoload :SpaceInvite, 'podio/areas/space'
151
+ # autoload :SpaceMember, 'podio/areas/space'
152
+ # autoload :Status, 'podio/areas/status'
153
+ # autoload :Subscription, 'podio/areas/subscription'
154
+ # autoload :Tag, 'podio/areas/tag'
155
+ # autoload :Task, 'podio/areas/task'
156
+ # autoload :TaskLabel, 'podio/areas/task'
157
+ # autoload :User, 'podio/areas/user'
158
+ # autoload :UserStatus, 'podio/areas/user_status'
159
+ # autoload :Widget, 'podio/areas/widget'
102
160
  end
data/podio.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.summary = 'Ruby wrapper for the Podio API'
9
9
  s.homepage = 'https://github.com/podio/podio-rb'
10
10
  s.email = 'florian@podio.com'
11
- s.authors = ['Florian Munz']
11
+ s.authors = ['Florian Munz', 'Casper Fabricius']
12
12
  s.has_rdoc = false
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
@@ -16,11 +16,12 @@ Gem::Specification.new do |s|
16
16
  s.require_paths = ['lib']
17
17
 
18
18
  s.add_runtime_dependency 'faraday', '~> 0.7.0'
19
- s.add_runtime_dependency 'activesupport', '~> 3.0'
19
+ s.add_runtime_dependency 'activesupport', '~> 3.0.0'
20
+ s.add_runtime_dependency 'activemodel', '~> 3.0.0'
20
21
  s.add_runtime_dependency 'i18n', '>= 0.4.2'
21
22
  s.add_runtime_dependency 'multi_json', '~> 0.0.5'
22
23
 
23
24
  s.description = <<desc
24
- The humble beginnings of the Ruby wrapper for the Podio API.
25
+ The official Ruby wrapper for the Podio API used and maintained by the Podio team
25
26
  desc
26
27
  end
@@ -0,0 +1,256 @@
1
+ require 'test_helper'
2
+
3
+ class ActivePodioTest < Test::Unit::TestCase
4
+
5
+ class TestAssociationModel < ActivePodio::Base
6
+ property :string, :string
7
+ end
8
+
9
+ class TestModel < ActivePodio::Base
10
+ property :test_id, :integer
11
+ property :string, :string
12
+ property :hash_property, :hash
13
+ property :datetime, :datetime
14
+ property :date, :date
15
+ property :integer, :integer
16
+ property :boolean, :boolean
17
+ property :array, :array
18
+
19
+ has_one :association, :class => 'ActivePodioTest::TestAssociationModel'
20
+ has_one :different_association, :class => 'ActivePodioTest::TestAssociationModel', :property => :other_association
21
+ has_many :associations, :class => 'ActivePodioTest::TestAssociationModel'
22
+ has_many :different_associations, :class => 'ActivePodioTest::TestAssociationModel', :property => :other_associations
23
+
24
+ alias_method :id, :test_id
25
+
26
+ delegate_to_hash :hash_property, :key1, :key2, :really?
27
+
28
+ def save(exception_class = nil)
29
+ if exception_class
30
+ raise exception_class.new({
31
+ 'error' => 'test status',
32
+ 'error_description' => 'test desc',
33
+ 'error_parameters' => 'test parms'
34
+ }, 500, 'http://api.podio.dev')
35
+ end
36
+ end
37
+
38
+ handle_api_errors_for :save
39
+ end
40
+
41
+ test 'should instansiate model' do
42
+ @test = TestModel.new
43
+ assert_not_nil @test
44
+ end
45
+
46
+ test 'should support string property' do
47
+ @test = TestModel.new(:string => 'string')
48
+ assert_equal 'string', @test.string
49
+ end
50
+
51
+ test 'should support hash property' do
52
+ @test = TestModel.new(:hash_property => { :key => 'value' })
53
+ assert_equal({ :key => 'value' }, @test.hash_property)
54
+ end
55
+
56
+ test 'should store given datetime as a db string internally' do
57
+ @test = TestModel.new(:datetime => DateTime.new(2011, 6, 7, 22, 5, 0))
58
+ assert_equal '2011-06-07 22:05:00', @test[:datetime]
59
+ end
60
+
61
+ test 'should expose datetime string as datetime' do
62
+ @test = TestModel.new(:datetime => '2011-06-07 22:05:00')
63
+ assert_equal DateTime.new(2011, 6, 7, 22, 5, 0), @test.datetime
64
+ end
65
+
66
+ test 'should store given date as a db string internally' do
67
+ @test = TestModel.new(:date => Date.new(2011, 6, 7))
68
+ assert_equal '2011-06-07', @test[:date]
69
+ end
70
+
71
+ test 'should expose date string as date' do
72
+ @test = TestModel.new(:date => '2011-06-07')
73
+ assert_equal Date.new(2011, 6, 7), @test.date
74
+ end
75
+
76
+ test 'should store given integer string as integer internally' do
77
+ @test = TestModel.new(:integer => "42")
78
+ assert_equal 42, @test[:integer]
79
+ end
80
+
81
+ test 'should expose blank integer string as nil' do
82
+ @test = TestModel.new(:integer => "")
83
+ assert_nil @test.integer
84
+ end
85
+
86
+ [true, 'true', 1, '1', 'yes'].each do |boolean_value|
87
+ test "should store and expose given boolean value #{boolean_value} (#{boolean_value.class.name}) as true" do
88
+ @test = TestModel.new(:boolean => boolean_value)
89
+ assert @test.boolean
90
+ end
91
+ end
92
+
93
+ [false, 'false', 0, '0', 'no', 'whatever'].each do |boolean_value|
94
+ test "should store and expose given boolean value #{boolean_value} (#{boolean_value.class.name}) as false" do
95
+ @test = TestModel.new(:boolean => boolean_value)
96
+ assert_equal false, @test.boolean
97
+ end
98
+ end
99
+
100
+ test "should expose singular array getter" do
101
+ @test = TestModel.new(:array => ['foo', 'bar'])
102
+ assert_equal ['foo', 'bar'], @test.array
103
+ end
104
+
105
+ test "should expose singular array setter" do
106
+ @test = TestModel.new
107
+ @test.array = ['foo', 'bar']
108
+ assert_equal ['foo', 'bar'], @test.array
109
+ end
110
+
111
+ test "should expose plural array getter" do
112
+ @test = TestModel.new(:array => ['foo', 'bar'])
113
+ assert_equal ['foo', 'bar'], @test.arrays
114
+ end
115
+
116
+ test "should expose plural array setter" do
117
+ @test = TestModel.new
118
+ @test.arrays = ['foo', 'bar']
119
+ assert_equal ['foo', 'bar'], @test.arrays
120
+ end
121
+
122
+ test "should expose default array getter" do
123
+ @test = TestModel.new(:array => ['foo', 'bar'])
124
+ assert_equal 'foo', @test.default_array
125
+ end
126
+
127
+ test 'should expose has one association' do
128
+ @test = TestModel.new(:association => { :string => 'association string' })
129
+ assert_equal 'association string', @test.association.string
130
+ end
131
+
132
+ test 'should expose nil has one association when no data given' do
133
+ @test = TestModel.new
134
+ assert_nil @test.association
135
+ end
136
+
137
+ test 'should use property option when given to has one association' do
138
+ @test = TestModel.new(:other_association => { :string => 'other association' })
139
+ assert_equal 'other association', @test.different_association.string
140
+ end
141
+
142
+ test 'should expose has many association' do
143
+ @test = TestModel.new(:associations => [{ :string => 'association string 1' }, { :string => 'association string 2' }])
144
+ assert_equal 'association string 1', @test.associations[0].string
145
+ assert_equal 'association string 2', @test.associations[1].string
146
+ end
147
+
148
+ test 'should expose empty has many association when no data given' do
149
+ @test = TestModel.new
150
+ assert_equal [], @test.associations
151
+ end
152
+
153
+ test 'should use property option when given to has many association' do
154
+ @test = TestModel.new(:other_associations => [{ :string => 'other association 1' }, { :string => 'other association 2' }])
155
+ assert_equal 'other association 1', @test.different_associations[0].string
156
+ assert_equal 'other association 2', @test.different_associations[1].string
157
+ end
158
+
159
+ test 'should expose methods defined by delegate to hash' do
160
+ @test = TestModel.new(:hash_property => {'key1' => 'value1', 'key2' => 'value2', 'really' => true})
161
+ assert_equal 'value1', @test.key1
162
+ assert @test.really?
163
+ end
164
+
165
+ test 'should handle non failing api requests' do
166
+ @test = TestModel.new
167
+ assert @test.save
168
+ end
169
+
170
+ [Podio::BadRequestError, Podio::AuthorizationError].each do |exception_class|
171
+ test "should handle failing api requests with #{exception_class.name} exception" do
172
+ @test = TestModel.new
173
+ assert_equal false, @test.save(exception_class)
174
+ assert_equal 'test status', @test.error_code
175
+ assert_equal 'test desc', @test.error_message
176
+ assert_equal 'test parms', @test.error_parameters
177
+ end
178
+ end
179
+
180
+ test 'should return instance from member' do
181
+ assert TestModel.member(:string => 'string').instance_of?(TestModel)
182
+ end
183
+
184
+ test 'should return array of instances from list' do
185
+ instances = TestModel.list([{:string => 'first'}, {:string => 'last'}])
186
+ assert_equal 2, instances.length
187
+ assert instances.all? { |instance| instance.instance_of?(TestModel) }
188
+ assert_equal 'first', instances.first.string
189
+ assert_equal 'last', instances.last.string
190
+ end
191
+
192
+ test 'should return struct with count, total and array from collection' do
193
+ struct = TestModel.collection('items' => [{:string => 'first'}, {:string => 'last'}], 'filtered' => 10, 'total' => 50)
194
+ assert_equal 2, struct.all.length
195
+ assert struct.all.all? { |instance| instance.instance_of?(TestModel) }
196
+ assert_equal 10, struct.count
197
+ assert_equal 50, struct.total_count
198
+ end
199
+
200
+ test 'should be new record without id' do
201
+ @test = TestModel.new
202
+ assert @test.new_record?
203
+ end
204
+
205
+ test 'should not be new record with id' do
206
+ @test = TestModel.new(:test_id => 42)
207
+ assert_equal false, @test.new_record?
208
+ end
209
+
210
+ test 'should not be persisted without id' do
211
+ @test = TestModel.new
212
+ assert_equal false, @test.persisted?
213
+ end
214
+
215
+ test 'should be persisted with id' do
216
+ @test = TestModel.new(:test_id => 42)
217
+ assert @test.persisted?
218
+ end
219
+
220
+ test 'should return id as to_param' do
221
+ @test = TestModel.new(:test_id => 42)
222
+ assert_equal '42', @test.to_param
223
+ end
224
+
225
+ test 'should return nil as to_param when model has no id' do
226
+ @test = TestAssociationModel.new
227
+ assert_nil @test.to_param
228
+ end
229
+
230
+ test 'should initialize nil attributes when constructed without given attributes' do
231
+ @test = TestModel.new
232
+ assert_equal({:string=>nil, :test_id=>nil, :hash_property=>nil, :datetime=>nil, :date=>nil, :integer=>nil, :boolean=>nil, :array=>nil}, @test.attributes)
233
+ end
234
+
235
+ test 'should accept unknown properties when constructed' do
236
+ @test = TestModel.new(:unknown => 'attribute')
237
+ assert_equal({:string=>nil, :test_id=>nil, :hash_property=>nil, :datetime=>nil, :date=>nil, :integer=>nil, :boolean=>nil, :array=>nil, :unknown => 'attribute'}, @test.attributes)
238
+ end
239
+
240
+ test 'should use id for ==' do
241
+ @test1 = TestModel.new(:test_id => 42)
242
+ @test2 = TestModel.new(:test_id => 42)
243
+ assert @test1 == @test2
244
+ end
245
+
246
+ test 'should use hashed id for hash' do
247
+ @test = TestModel.new(:test_id => 42)
248
+ assert_equal 42.hash, @test.hash
249
+ end
250
+
251
+ test 'should return attributes for as_json' do
252
+ @test = TestModel.new(:test_id => 42)
253
+ assert_equal({:string=>nil, :test_id=>42, :hash_property=>nil, :datetime=>nil, :date=>nil, :integer=>nil, :boolean=>nil, :array=>nil}, @test.as_json)
254
+ end
255
+
256
+ end
data/test/client_test.rb CHANGED
@@ -3,41 +3,43 @@ require 'test_helper'
3
3
  class ClientTest < Test::Unit::TestCase
4
4
  test 'should setup client' do
5
5
  Podio.setup(:api_key => 'client_id', :api_secret => 'client_secret')
6
-
6
+
7
7
  assert_equal Podio::Client, Podio.client.class
8
8
  assert_equal 'client_id', Podio.client.api_key
9
9
  assert_equal 'client_secret', Podio.client.api_secret
10
10
  end
11
-
11
+
12
12
  test 'should initialize client' do
13
13
  podio = Podio::Client.new(:api_url => 'https://new.podio.com', :api_key => 'new_client_id', :api_secret => 'new_client_secret')
14
-
14
+
15
15
  assert_equal 'https://new.podio.com', podio.api_url
16
16
  assert_equal 'new_client_id', podio.api_key
17
17
  assert_equal 'new_client_secret', podio.api_secret
18
18
  end
19
-
19
+
20
20
  test 'should setup connection' do
21
21
  token = Podio::OAuthToken.new('access_token' => 'access', 'refresh_token' => 'refresh')
22
22
  podio = Podio::Client.new(:oauth_token => token)
23
-
23
+
24
24
  assert_equal token, podio.oauth_token
25
-
25
+
26
26
  assert_equal 'OAuth2 access', podio.connection.headers['authorization']
27
27
  end
28
-
28
+
29
29
  test 'should get an access token' do
30
30
  client = Podio.client
31
31
  client.oauth_token = nil
32
32
  assert_nil client.oauth_token
33
-
34
- client.authenticate_with_credentials('pollas@hoisthq.com', 'secret')
35
-
33
+
34
+ user = fixtures[:users][:professor]
35
+ client.authenticate_with_credentials(user[:mail], user[:password])
36
+
36
37
  assert_not_nil client.oauth_token.access_token
37
38
  assert_not_nil client.oauth_token.refresh_token
38
39
  end
39
40
 
40
41
  test 'should be able to refresh access token' do
42
+ login_as(:fry)
41
43
  client = Podio.client
42
44
  old_token = client.oauth_token.dup
43
45
 
@@ -49,17 +51,20 @@ class ClientTest < Test::Unit::TestCase
49
51
 
50
52
  test 'should automatically refresh an expired token' do
51
53
  # this token is already expired in the test database
52
- Podio.client.oauth_token = Podio::OAuthToken.new('access_token' => '30da4594eef93528c11df7fb5deb989cd629ea7060a1ce1ced628d19398214c942bcfe0334cf953ef70a80ea1afdfd80183d5c75d19c1f5526ca4c6f6f3471ef', 'refresh_token' => '82e7a11ae187f28a25261599aa6229cd89f8faee48cba18a75d70efae88ba665ced11d43143b7f5bebb31a4103662b851dd2db1879a3947b843259479fccfad3', 'expires_in' => -10)
54
+ # Podio.client.oauth_token = Podio::OAuthToken.new('access_token' => '30da4594eef93528c11df7fb5deb989cd629ea7060a1ce1ced628d19398214c942bcfe0334cf953ef70a80ea1afdfd80183d5c75d19c1f5526ca4c6f6f3471ef', 'refresh_token' => '82e7a11ae187f28a25261599aa6229cd89f8faee48cba18a75d70efae88ba665ced11d43143b7f5bebb31a4103662b851dd2db1879a3947b843259479fccfad3', 'expires_in' => -10)
55
+
56
+ login_as(:professor)
53
57
  Podio.client.reset
54
-
58
+
55
59
  assert_nothing_raised do
56
- response = Podio.client.connection.get('/org/')
60
+ response = Podio.connection.get("/org/")
57
61
  assert_equal 200, response.status
58
62
  end
59
63
  end
60
-
64
+
61
65
  test 'should be able to make arbitrary requests' do
62
- response = Podio.client.connection.get('/org/')
66
+ login_as(:professor)
67
+ response = Podio.connection.get("/org/")
63
68
  assert_equal 200, response.status
64
69
  assert response.body.is_a?(Array)
65
70
  end
@@ -0,0 +1 @@
1
+ ['/oauth/token?client_id=sandbox%40podio.com&client_secret=sandbox_secret&grant_type=refresh_token&refresh_token=1df512a21e418f4171bc0259060655509951081e05114d0a56cee7d025d26a99d6c5b6db6e2b5fdf995f98d8cb3d164210fb546805a45b1c31ea8be6b3597819', :post, 200, {"server"=>"nginx/0.7.65", "date"=>"Tue, 07 Jun 2011 18:24:03 GMT", "content-type"=>"application/json; charset=utf-8", "connection"=>"close", "content-length"=>"364"}, '{"access_token":"f279f1d084f824829ea338c697e17f147542e8d8e9deb8f45f7710e495af855e6d3191c357ef7697bcad11c928199f3c37ddb5ce6dba43de700a5f42dffabb67","token_type":"bearer","ref":{"type":"user","id":5},"expires_in":28799,"refresh_token":"1df512a21e418f4171bc0259060655509951081e05114d0a56cee7d025d26a99d6c5b6db6e2b5fdf995f98d8cb3d164210fb546805a45b1c31ea8be6b3597819"}']
@@ -0,0 +1 @@
1
+ ['/org/', :get, 200, {"server"=>"nginx/0.7.65", "date"=>"Tue, 07 Jun 2011 19:54:57 GMT", "content-type"=>"application/json; charset=utf-8", "connection"=>"close", "content-length"=>"440"}, '[{"type":"premium","spaces":[{"url":"http:\/\/planetexpress.podio.com\/intranet\/","url_label":"intranet","space_id":2,"role":"admin","name":"Intranet"},{"url":"http:\/\/planetexpress.podio.com\/shipping\/","url_label":"shipping","space_id":3,"role":"admin","name":"Shipping"}],"premium":true,"name":"Planet Express","logo":null,"url":"http:\/\/planetexpress.podio.com\/","url_label":"planetexpress","image":null,"role":"admin","org_id":3}]']
@@ -0,0 +1 @@
1
+ ['/oauth/token?client_id=sandbox%40podio.com&client_secret=sandbox_secret&grant_type=password&password=fry&username=fry%40planetexpress.com', :post, 200, {"server"=>"nginx/0.7.65", "date"=>"Tue, 07 Jun 2011 19:54:57 GMT", "content-type"=>"application/json; charset=utf-8", "connection"=>"close", "content-length"=>"364"}, '{"access_token":"7c2efeddf67027a315174741a8c721ac55b75da37fcf1cc33039eb58fe8dc81ad410a9b64d170f74c0c5fb3937bd7143ffd795a0804a6cc52855782da39b258e","token_type":"bearer","ref":{"type":"user","id":5},"expires_in":28799,"refresh_token":"a2a0948c85df6903cd8437e29048134d1bc27c6b013ab25d0e215fb096363d4f8f95f5bb9d0bf167edc0f10883415e8a2a8933ece59d2ccee9700fff45afda0d"}']
@@ -0,0 +1 @@
1
+ ['/oauth/token?client_id=sandbox%40podio.com&client_secret=sandbox_secret&grant_type=password&password=professor&username=professor%40planetexpress.com', :post, 200, {"server"=>"nginx/0.7.65", "date"=>"Tue, 07 Jun 2011 19:54:58 GMT", "content-type"=>"application/json; charset=utf-8", "connection"=>"close", "content-length"=>"364"}, '{"access_token":"c66ab69158ef75f058e154c733ea4c35c26916483229fd230445eb3a75c9023c4a8442d480ffba7d799ec7e37cab13e5e6c1b09de3625e7651c239a550de49c6","token_type":"bearer","ref":{"type":"user","id":4},"expires_in":28799,"refresh_token":"5d0c48600d73b866a838de9afd11ac1b77bdc1831e89ade72ef4f2b879956b01aa336f698cbb32a1c9c967e6493e01e859f9a1e4748fb889dbcda8ac093ff03f"}']
@@ -0,0 +1 @@
1
+ ['/oauth/token?client_id=sandbox%40podio.com&client_secret=sandbox_secret&grant_type=refresh_token&refresh_token=a2a0948c85df6903cd8437e29048134d1bc27c6b013ab25d0e215fb096363d4f8f95f5bb9d0bf167edc0f10883415e8a2a8933ece59d2ccee9700fff45afda0d', :post, 200, {"server"=>"nginx/0.7.65", "date"=>"Tue, 07 Jun 2011 19:54:57 GMT", "content-type"=>"application/json; charset=utf-8", "connection"=>"close", "content-length"=>"364"}, '{"access_token":"10b3af5430fb2071d2f6f003aa11818b15f170a3416809118276e8000d0bede2f1faae6925e54019c5fdd74688368742102e226cb6725314a2b801ffe777a2d9","token_type":"bearer","ref":{"type":"user","id":5},"expires_in":28799,"refresh_token":"a2a0948c85df6903cd8437e29048134d1bc27c6b013ab25d0e215fb096363d4f8f95f5bb9d0bf167edc0f10883415e8a2a8933ece59d2ccee9700fff45afda0d"}']
@@ -0,0 +1,34 @@
1
+ ---
2
+ :users:
3
+ :new_user:
4
+ :mail: new@noname.com
5
+ :password: n00b
6
+ :user_id: 3
7
+ :professor:
8
+ :mail: professor@planetexpress.com
9
+ :password: professor
10
+ :user_id: 4
11
+ :fry:
12
+ :mail: fry@planetexpress.com
13
+ :password: fry
14
+ :user_id: 5
15
+ :leela:
16
+ :mail: leela@planetexpress.com
17
+ :password: leela
18
+ :user_id: 6
19
+ :bender:
20
+ :mail: bender@planetexpress.com
21
+ :password: killallhumans
22
+ :user_id: 7
23
+ :amy:
24
+ :mail: amy@planetexpress.com
25
+ :password: amy
26
+ :user_id: 8
27
+ :zoidberg:
28
+ :mail: zoidberg@planetexpress.com
29
+ :password: zoidberg
30
+ :user_id: 9
31
+ :hermes:
32
+ :mail: hermes@planetexpress.com
33
+ :password: hermes
34
+ :user_id: 10
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class ModelsSanityTest < Test::Unit::TestCase
4
+
5
+ ActiveSupport::Inflector.inflections do |inflect|
6
+ inflect.uncountable %w( status user_status via )
7
+ end
8
+
9
+ models_directory = File.join(File.dirname(__FILE__), '..', 'lib', 'podio', 'models')
10
+ model_files = Dir[File.join(models_directory, '**', '*')]
11
+ model_files.each do |model_file|
12
+ filename = File.basename(model_file, File.extname(model_file))
13
+ model_class = ActiveSupport::Inflector.constantize("Podio::" + filename.classify)
14
+
15
+ test "should instansiate #{model_class.name}" do
16
+ assert_nothing_raised { model_class.new }
17
+ end
18
+ end
19
+ end