podio 0.4.1 → 0.5.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.
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