totter 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +17 -0
  2. data/.travis.yml +4 -0
  3. data/Contributing.markdown +19 -0
  4. data/Gemfile +22 -0
  5. data/LICENSE +22 -0
  6. data/Rakefile +21 -0
  7. data/Readme.markdown +49 -0
  8. data/lib/totter.rb +26 -0
  9. data/lib/totter/client.rb +152 -0
  10. data/lib/totter/client/choices.rb +74 -0
  11. data/lib/totter/client/decisions.rb +91 -0
  12. data/lib/totter/client/slugs.rb +19 -0
  13. data/lib/totter/client/timelines.rb +16 -0
  14. data/lib/totter/client/users.rb +54 -0
  15. data/lib/totter/client/votes.rb +25 -0
  16. data/lib/totter/error.rb +51 -0
  17. data/lib/totter/version.rb +4 -0
  18. data/test/cassettes/choices/create_choice_upload.yml +85 -0
  19. data/test/cassettes/choices/create_for_image.yml +87 -0
  20. data/test/cassettes/choices/destroy.yml +122 -0
  21. data/test/cassettes/choices/show.yml +42 -0
  22. data/test/cassettes/decisions/analytics.yml +85 -0
  23. data/test/cassettes/decisions/create.yml +44 -0
  24. data/test/cassettes/decisions/destroy.yml +81 -0
  25. data/test/cassettes/decisions/flag.yml +81 -0
  26. data/test/cassettes/decisions/publish.yml +129 -0
  27. data/test/cassettes/decisions/show.yml +84 -0
  28. data/test/cassettes/decisions/unflag.yml +122 -0
  29. data/test/cassettes/slugs/show.yml +75 -0
  30. data/test/cassettes/timelines/global.yml +165 -0
  31. data/test/cassettes/users/following.yml +194 -0
  32. data/test/cassettes/users/me.yml +43 -0
  33. data/test/cassettes/users/user.yml +49 -0
  34. data/test/cassettes/votes/create.yml +96 -0
  35. data/test/support/client_macros.rb +5 -0
  36. data/test/test_helper.rb +24 -0
  37. data/test/totter/client/choices_test.rb +48 -0
  38. data/test/totter/client/decisions_test.rb +77 -0
  39. data/test/totter/client/slugs_test.rb +11 -0
  40. data/test/totter/client/timelines_test.rb +9 -0
  41. data/test/totter/client/users_test.rb +36 -0
  42. data/test/totter/client/votes_test.rb +15 -0
  43. data/test/totter/client_test.rb +31 -0
  44. data/test/totter_test.rb +17 -0
  45. data/totter.gemspec +24 -0
  46. metadata +155 -0
@@ -0,0 +1,43 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:5000/v1/me
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ Authorization:
15
+ - Bearer 9774e653f7b3c1de5f21b61adc08ba24
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Content-Type:
22
+ - application/json; charset=utf-8
23
+ X-Ua-Compatible:
24
+ - IE=Edge
25
+ Etag:
26
+ - ! '"95c71ccb1067d7d65324be5f15d45f2c"'
27
+ Cache-Control:
28
+ - max-age=0, private, must-revalidate
29
+ X-Request-Id:
30
+ - 28038b85d34b3e315b81dfde649c2b0c
31
+ X-Runtime:
32
+ - '0.678551'
33
+ Connection:
34
+ - close
35
+ Server:
36
+ - thin 1.5.0 codename Knife
37
+ body:
38
+ encoding: US-ASCII
39
+ string: ! '{"biography":null,"created_at":"2013-01-25T21:06:59Z","email":"test@seesaw.co","family_name":null,"given_name":null,"id":1,"meta":null,"phone_number":"+12147093337","preferences":{"notification_friends":false,"notification_invitee_votes":true,"notification_comments":true,"notification_following_votes":true,"notification_other_votes":true,"notification_after_votes":false,"notification_following":true,"opt_in_to_sms":true},"updated_at":"2013-01-29T23:39:18Z","username":"test123","website":null,"avatar_url":"https://recess-dev.s3.amazonaws.com/default_avatars/v1/photo_1.png","full_name":"test123","short_name":"test123","display_name":"test123","short_display_name":"test123","analytics":{"votes":0,"decisions":0,"followers":0,"following":0},"formatted_phone_number":"(214)
40
+ 709-3337","roles":[],"default_timeline":"g"}'
41
+ http_version:
42
+ recorded_at: Wed, 30 Jan 2013 15:45:06 GMT
43
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,49 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.seesaw.co/v1/users/gotwalt
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Cache-Control:
20
+ - max-age=0, private, must-revalidate
21
+ Content-Type:
22
+ - application/json; charset=utf-8
23
+ Date:
24
+ - Wed, 30 Jan 2013 16:10:55 GMT
25
+ Etag:
26
+ - ! '"4a15d340e2051046340cd2fc1443cba1"'
27
+ Server:
28
+ - thin 1.5.0 codename Knife
29
+ Strict-Transport-Security:
30
+ - max-age=31536000
31
+ X-Rack-Cache:
32
+ - miss
33
+ X-Request-Id:
34
+ - 008de3c6c1b64956f4c0518074b15acb
35
+ X-Runtime:
36
+ - '0.009899'
37
+ X-Ua-Compatible:
38
+ - IE=Edge,chrome=1
39
+ Transfer-Encoding:
40
+ - chunked
41
+ Connection:
42
+ - keep-alive
43
+ body:
44
+ encoding: US-ASCII
45
+ string: ! '{"biography":null,"created_at":"2012-11-13T22:40:33Z","family_name":"Gotwalt","given_name":"Aaron","id":1,"meta":null,"moderated_decisions_count":null,"updated_at":"2013-01-30T15:01:17Z","username":"gotwalt","website":null,"avatar_url":"https://recess.s3.amazonaws.com/avatars/530/1355442979/photo.jpg","full_name":"Aaron
46
+ Gotwalt","short_name":"Aaron G","display_name":"gotwalt","short_display_name":"gotwalt","analytics":{"votes":133,"decisions":17,"following":19,"followers":39,"updated_at":"2013-01-30T15:01:00Z"}}'
47
+ http_version:
48
+ recorded_at: Wed, 30 Jan 2013 16:10:56 GMT
49
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,96 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.seesaw.co/v1/users/5/decisions/3276/votes
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"choice_id":5381,"unique_id":"021a997d8aa785abed0a25c47b9a07be"}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Cache-Control:
22
+ - max-age=0, private, must-revalidate
23
+ Content-Type:
24
+ - application/json; charset=utf-8
25
+ Date:
26
+ - Wed, 30 Jan 2013 23:41:18 GMT
27
+ Etag:
28
+ - ! '"380b1c2aadcb06b0b3c3c006df2ec706"'
29
+ Server:
30
+ - thin 1.5.0 codename Knife
31
+ Strict-Transport-Security:
32
+ - max-age=31536000
33
+ X-Rack-Cache:
34
+ - invalidate, pass
35
+ X-Request-Id:
36
+ - 910c33f18f74e972a8cc2b0070a2b5b8
37
+ X-Runtime:
38
+ - '0.071101'
39
+ X-Ua-Compatible:
40
+ - IE=Edge,chrome=1
41
+ Transfer-Encoding:
42
+ - chunked
43
+ Connection:
44
+ - keep-alive
45
+ body:
46
+ encoding: US-ASCII
47
+ string: ! '{"choice_id":5381,"created_at":"2013-01-30T23:41:18Z","decision_id":3276,"id":5432,"meta":null,"reason":null}'
48
+ http_version:
49
+ recorded_at: Wed, 30 Jan 2013 23:41:17 GMT
50
+ - request:
51
+ method: post
52
+ uri: https://api.seesaw.co/v1/users/5/decisions/3276/votes
53
+ body:
54
+ encoding: UTF-8
55
+ string: ! '{"choice_id":5381,"unique_id":"021a997d8aa785abed0a25c47b9a07be"}'
56
+ headers:
57
+ Accept:
58
+ - ! '*/*'
59
+ User-Agent:
60
+ - Ruby
61
+ Content-Type:
62
+ - application/json
63
+ response:
64
+ status:
65
+ code: 400
66
+ message: Bad Request
67
+ headers:
68
+ Cache-Control:
69
+ - no-cache
70
+ Content-Type:
71
+ - application/json; charset=utf-8
72
+ Date:
73
+ - Wed, 30 Jan 2013 23:41:18 GMT
74
+ Server:
75
+ - thin 1.5.0 codename Knife
76
+ Strict-Transport-Security:
77
+ - max-age=31536000
78
+ X-Rack-Cache:
79
+ - invalidate, pass
80
+ X-Request-Id:
81
+ - 5736b4d2f98ef71c14b3c53fdedca28a
82
+ X-Runtime:
83
+ - '0.111517'
84
+ X-Ua-Compatible:
85
+ - IE=Edge,chrome=1
86
+ Transfer-Encoding:
87
+ - chunked
88
+ Connection:
89
+ - keep-alive
90
+ body:
91
+ encoding: US-ASCII
92
+ string: ! '{"error":"invalid_vote","error_description":"Vote has already been
93
+ recorded"}'
94
+ http_version:
95
+ recorded_at: Wed, 30 Jan 2013 23:41:18 GMT
96
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,5 @@
1
+ module ClientMacros
2
+ def local_client
3
+ client = Totter::Client.new(access_token: '9774e653f7b3c1de5f21b61adc08ba24', api_host: 'localhost:5000', api_scheme: 'http')
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require :test
4
+
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+
8
+ require 'minitest/autorun'
9
+ require 'totter'
10
+
11
+ # Support files
12
+ Dir["#{File.expand_path(File.dirname(__FILE__))}/support/*.rb"].each do |file|
13
+ require file
14
+ end
15
+
16
+ # VCR
17
+ VCR.configure do |c|
18
+ c.cassette_library_dir = 'test/cassettes'
19
+ c.hook_into :webmock
20
+ end
21
+
22
+ class Totter::TestCase < MiniTest::Unit::TestCase
23
+ include ::ClientMacros
24
+ end
@@ -0,0 +1,48 @@
1
+ require 'test_helper'
2
+
3
+ class ChoicesTest < Totter::TestCase
4
+ def test_decision
5
+ VCR.use_cassette 'choices/show' do
6
+ client = local_client
7
+ choice = client.choice(3, 12, 1)
8
+ assert_equal 'ImageChoice', choice.type
9
+ end
10
+ end
11
+
12
+ def test_create_choice_for_image
13
+ VCR.use_cassette 'choices/create_for_image' do
14
+ client = local_client
15
+ data = {
16
+ image_url: 'http://recess.s3.amazonaws.com/default_avatars/v1/photo_1.png',
17
+ subject: 'Test Image',
18
+ link_url: 'http://seesaw.co',
19
+ link_title: 'Seesaw'
20
+ }
21
+ decision = client.create_decision(1)
22
+ choice = client.create_choice_for_image(decision.user_id, decision.id, data)
23
+ assert_equal data[:subject], choice.subject
24
+ assert_equal data[:link_url], choice.meta.link_url
25
+ assert_equal data[:link_title], choice.meta.link_title
26
+ refute choice.respond_to?(:upload), 'should not have an upload form'
27
+ end
28
+ end
29
+
30
+ def test_create_choice_upload
31
+ VCR.use_cassette 'choices/create_choice_upload' do
32
+ client = local_client
33
+ decision = client.create_decision(1)
34
+ choice = client.create_choice_upload(decision.user_id, decision.id)
35
+
36
+ assert choice.respond_to?(:upload), 'should have an upload form'
37
+ end
38
+ end
39
+
40
+ def test_destroy_choice
41
+ VCR.use_cassette 'choices/destroy' do
42
+ client = local_client
43
+ decision = client.create_decision(1)
44
+ choice = client.create_choice_upload(decision.user_id, decision.id)
45
+ assert client.destroy_choice(decision.user_id, decision.id, choice.id)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,77 @@
1
+ require 'test_helper'
2
+
3
+ class DecisionsTest < Totter::TestCase
4
+ def test_decision
5
+ VCR.use_cassette 'decisions/show' do
6
+ decision = Totter.decision(5, 3276)
7
+ assert_equal 'Which lamp for the new apartment?', decision.question
8
+ end
9
+ end
10
+
11
+ def test_create_decision
12
+ VCR.use_cassette 'decisions/create' do
13
+ client = local_client
14
+ decision = client.create_decision(1)
15
+ assert_equal 1, decision.id
16
+ assert_equal 1, decision.user_id
17
+ assert decision.timeline_key
18
+ end
19
+ end
20
+
21
+ def test_publish_decision
22
+ VCR.use_cassette 'decisions/publish' do
23
+ client = local_client
24
+ decision = client.create_decision(1)
25
+ choice = create_test_choice(client, decision.user_id, decision.id)
26
+ result = client.publish_decision(decision.user_id, decision.id, question: 'Why is the sky blue?')
27
+ assert result.published_at
28
+ assert 1, result.choices.length
29
+ end
30
+ end
31
+
32
+ def test_destroy_decision
33
+ VCR.use_cassette 'decisions/destroy' do
34
+ client = local_client
35
+ decision = client.create_decision(1)
36
+ assert client.destroy_decision(decision.user_id, decision.id)
37
+ end
38
+ end
39
+
40
+ def test_decision_analytics
41
+ VCR.use_cassette 'decisions/analytics' do
42
+ client = local_client
43
+ decision = client.create_decision(1)
44
+ analytics = client.decision_analytics(decision.user_id, decision.id)
45
+ assert_equal 0, analytics.total_votes
46
+ end
47
+ end
48
+
49
+ def test_flag_decision
50
+ VCR.use_cassette 'decisions/flag' do
51
+ client = local_client
52
+ decision = client.create_decision(1)
53
+ assert client.flag_decision(decision.user_id, decision.id)
54
+ end
55
+ end
56
+
57
+ def test_unflag_decision
58
+ VCR.use_cassette 'decisions/unflag' do
59
+ client = local_client
60
+ decision = client.create_decision(1)
61
+ assert client.flag_decision(decision.user_id, decision.id)
62
+ assert client.unflag_decision(decision.user_id, decision.id)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def create_test_choice(client, user_id, decision_id)
69
+ data = {
70
+ image_url: 'http://recess.s3.amazonaws.com/default_avatars/v1/photo_1.png',
71
+ subject: 'Test Image',
72
+ link_url: 'http://seesaw.co',
73
+ link_title: 'Seesaw'
74
+ }
75
+ client.create_choice_for_image(user_id, decision_id, data)
76
+ end
77
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class SlugsTest < Totter::TestCase
4
+ def test_slug
5
+ VCR.use_cassette 'slugs/show' do
6
+ client = Totter::Client.new
7
+ slug = client.slug('d/3I0n0g')
8
+ assert_equal 'soffes', slug.decision.user.username
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class TimelinesTest < Totter::TestCase
4
+ def test_global
5
+ VCR.use_cassette 'timelines/global' do
6
+ assert_equal 15, Totter.global_timeline(15).length
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class UsersTest < Totter::TestCase
4
+ def test_me
5
+ VCR.use_cassette 'users/me' do
6
+ user = local_client.me
7
+ assert_equal 'test123', user.username
8
+ end
9
+ end
10
+
11
+ def test_user
12
+ VCR.use_cassette 'users/user' do
13
+ client = Totter::Client.new
14
+ user = client.user('gotwalt')
15
+ assert_equal 'gotwalt', user.username
16
+ end
17
+ end
18
+
19
+ def test_following
20
+ VCR.use_cassette 'users/following' do
21
+ assert local_client.follow('gotwalt'), 'follow user'
22
+ assert local_client.unfollow('gotwalt'), 'unfollow user'
23
+
24
+ # Still true, even if you aren't following them
25
+ assert local_client.unfollow('gotwalt'), 'unfollow user twice'
26
+
27
+ assert_raises Totter::NotFound do
28
+ local_client.follow('nobody')
29
+ end
30
+
31
+ assert_raises Totter::NotFound do
32
+ refute local_client.follow('unnobody')
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class VotesTest < Totter::TestCase
4
+ def test_create_vote
5
+ VCR.use_cassette 'votes/create' do
6
+ vote = Totter.create_vote(5, 3276, 5381, unique_id: '021a997')
7
+ assert_equal 5381, vote.choice_id
8
+
9
+ # Prevent duplicates
10
+ assert_raises Totter::BadRequest do
11
+ Totter.create_vote(5, 3276, 5381, unique_id: '021a997')
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class ClientTest < Totter::TestCase
4
+ def test_initialization
5
+ client = Totter::Client.new(access_token: 'asdf1234')
6
+ assert_equal 'asdf1234', client.access_token
7
+ assert client.authenticated?
8
+
9
+ client = Totter::Client.new('asdf1234')
10
+ assert_equal 'asdf1234', client.access_token
11
+
12
+ client = Totter::Client.new
13
+ refute client.authenticated?
14
+ end
15
+
16
+ def test_base_url
17
+ client = Totter::Client.new
18
+ assert_equal 'https://api.seesaw.co/v1/', client.base_url
19
+
20
+ client = Totter::Client.new(api_scheme: 'http', api_host: 'example.com', api_version: 42)
21
+ assert_equal 'http://example.com/v42/', client.base_url
22
+ end
23
+
24
+ def test_ssl?
25
+ client = Totter::Client.new
26
+ assert client.ssl?
27
+
28
+ client = Totter::Client.new(api_scheme: 'http')
29
+ refute client.ssl?
30
+ end
31
+ end