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.
- data/README.md +36 -5
- data/Rakefile +3 -1
- data/lib/podio/active_podio/base.rb +311 -0
- data/lib/podio/active_podio/updatable.rb +22 -0
- data/lib/podio/client.rb +7 -4
- data/lib/podio/error.rb +1 -0
- data/lib/podio/middleware/error_response.rb +5 -1
- data/lib/podio/middleware/response_recorder.rb +1 -1
- data/lib/podio/models/app_store_share.rb +67 -0
- data/lib/podio/{areas → models}/application.rb +23 -7
- data/lib/podio/models/application_email.rb +22 -0
- data/lib/podio/models/application_field.rb +17 -0
- data/lib/podio/{areas → models}/bulletin.rb +16 -5
- data/lib/podio/models/by_line.rb +11 -0
- data/lib/podio/models/category.rb +49 -0
- data/lib/podio/models/comment.rb +63 -0
- data/lib/podio/{areas → models}/connection.rb +20 -4
- data/lib/podio/models/contact.rb +10 -0
- data/lib/podio/models/conversation.rb +72 -0
- data/lib/podio/models/conversation_message.rb +12 -0
- data/lib/podio/models/conversation_participant.rb +9 -0
- data/lib/podio/models/email_subscription_setting.rb +39 -0
- data/lib/podio/models/embed.rb +34 -0
- data/lib/podio/models/file_attachment.rb +127 -0
- data/lib/podio/models/form.rb +25 -0
- data/lib/podio/{areas → models}/hook.rb +15 -5
- data/lib/podio/{areas → models}/importer.rb +4 -6
- data/lib/podio/{areas → models}/integration.rb +40 -4
- data/lib/podio/models/item.rb +122 -0
- data/lib/podio/models/item_diff.rb +16 -0
- data/lib/podio/models/item_field.rb +19 -0
- data/lib/podio/models/item_revision.rb +18 -0
- data/lib/podio/models/news.rb +83 -0
- data/lib/podio/models/notification.rb +47 -0
- data/lib/podio/models/notification_group.rb +19 -0
- data/lib/podio/models/o_auth.rb +32 -0
- data/lib/podio/models/o_auth_client.rb +93 -0
- data/lib/podio/{areas → models}/organization.rb +39 -6
- data/lib/podio/models/organization_contact.rb +14 -0
- data/lib/podio/{areas → models}/organization_member.rb +13 -5
- data/lib/podio/models/organization_profile.rb +61 -0
- data/lib/podio/{areas/contact.rb → models/profile.rb} +23 -6
- data/lib/podio/{areas → models}/rating.rb +5 -7
- data/lib/podio/{areas → models}/search.rb +6 -7
- data/lib/podio/models/space.rb +45 -0
- data/lib/podio/models/space_contact.rb +23 -0
- data/lib/podio/models/space_invite.rb +57 -0
- data/lib/podio/models/space_member.rb +32 -0
- data/lib/podio/models/status.rb +35 -0
- data/lib/podio/{areas → models}/subscription.rb +8 -7
- data/lib/podio/{areas → models}/tag.rb +14 -7
- data/lib/podio/models/task.rb +153 -0
- data/lib/podio/models/task_label.rb +50 -0
- data/lib/podio/models/user.rb +66 -0
- data/lib/podio/models/user_status.rb +18 -0
- data/lib/podio/models/via.rb +7 -0
- data/lib/podio/{areas → models}/widget.rb +9 -5
- data/lib/podio/version.rb +1 -1
- data/lib/podio.rb +97 -39
- data/podio.gemspec +4 -3
- data/test/active_podio_test.rb +256 -0
- data/test/client_test.rb +20 -15
- data/test/fixtures/client/18a224aaf83ac57a7b8159cecdbb1263.rack +1 -0
- data/test/fixtures/client/a87c69a0624af0413a670094c6615651.rack +1 -0
- data/test/fixtures/client/ac493997db62308972c208afa76f8479.rack +1 -0
- data/test/fixtures/client/d7fbf422c77af768552423633d0389e8.rack +1 -0
- data/test/fixtures/client/e2d68afe39f5531195273ea259b63916.rack +1 -0
- data/test/fixtures/fixtures.yaml +34 -0
- data/test/models_sanity_test.rb +19 -0
- data/test/test_helper.rb +22 -28
- metadata +89 -64
- data/lib/podio/areas/app_store.rb +0 -69
- data/lib/podio/areas/comment.rb +0 -36
- data/lib/podio/areas/conversation.rb +0 -39
- data/lib/podio/areas/email.rb +0 -24
- data/lib/podio/areas/file.rb +0 -81
- data/lib/podio/areas/form.rb +0 -11
- data/lib/podio/areas/item.rb +0 -68
- data/lib/podio/areas/notification.rb +0 -39
- data/lib/podio/areas/oauth.rb +0 -107
- data/lib/podio/areas/organization_profile.rb +0 -32
- data/lib/podio/areas/space.rb +0 -77
- data/lib/podio/areas/status.rb +0 -19
- data/lib/podio/areas/task.rb +0 -108
- data/lib/podio/areas/user.rb +0 -31
- 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,
|
64
|
-
autoload :ResponseWrapper,
|
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 :
|
81
|
-
autoload :
|
82
|
-
autoload :
|
83
|
-
autoload :
|
84
|
-
autoload :
|
85
|
-
autoload :
|
86
|
-
autoload :
|
87
|
-
autoload :
|
88
|
-
autoload :
|
89
|
-
autoload :
|
90
|
-
autoload :
|
91
|
-
autoload :
|
92
|
-
autoload :
|
93
|
-
autoload :
|
94
|
-
autoload :
|
95
|
-
autoload :
|
96
|
-
autoload :
|
97
|
-
autoload :
|
98
|
-
autoload :
|
99
|
-
autoload :
|
100
|
-
autoload :
|
101
|
-
autoload :
|
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
|
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
|
-
|
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.
|
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
|
-
|
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
|