thumbtack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/thumbtack/client.rb +70 -0
- data/lib/thumbtack/note.rb +35 -0
- data/lib/thumbtack/note_summary.rb +35 -0
- data/lib/thumbtack/notes.rb +26 -0
- data/lib/thumbtack/post.rb +37 -0
- data/lib/thumbtack/posts.rb +186 -0
- data/lib/thumbtack/specification.rb +31 -0
- data/lib/thumbtack/tags.rb +45 -0
- data/lib/thumbtack/types/boolean.rb +52 -0
- data/lib/thumbtack/types/date.rb +47 -0
- data/lib/thumbtack/types/date_time.rb +49 -0
- data/lib/thumbtack/types/identity.rb +26 -0
- data/lib/thumbtack/types/integer.rb +27 -0
- data/lib/thumbtack/types/md5.rb +30 -0
- data/lib/thumbtack/types/tags.rb +53 -0
- data/lib/thumbtack/types/text.rb +26 -0
- data/lib/thumbtack/types/title.rb +26 -0
- data/lib/thumbtack/types/url.rb +26 -0
- data/lib/thumbtack/types.rb +10 -0
- data/lib/thumbtack/user.rb +23 -0
- data/lib/thumbtack/version.rb +6 -0
- data/lib/thumbtack.rb +32 -0
- data/test/test_helper.rb +18 -0
- data/test/thumbtack/client_test.rb +35 -0
- data/test/thumbtack/note_summary_test.rb +24 -0
- data/test/thumbtack/note_test.rb +26 -0
- data/test/thumbtack/notes_test.rb +61 -0
- data/test/thumbtack/post_test.rb +30 -0
- data/test/thumbtack/posts_test.rb +178 -0
- data/test/thumbtack/specification_test.rb +15 -0
- data/test/thumbtack/tags_test.rb +56 -0
- data/test/thumbtack/types/boolean_test.rb +28 -0
- data/test/thumbtack/types/date_test.rb +27 -0
- data/test/thumbtack/types/date_time_test.rb +27 -0
- data/test/thumbtack/types/identity_test.rb +18 -0
- data/test/thumbtack/types/integer_test.rb +26 -0
- data/test/thumbtack/types/md5_test.rb +28 -0
- data/test/thumbtack/types/tags_test.rb +29 -0
- data/test/thumbtack/types/text_test.rb +22 -0
- data/test/thumbtack/types/title_test.rb +22 -0
- data/test/thumbtack/types/url_test.rb +23 -0
- data/test/thumbtack/user_test.rb +29 -0
- metadata +162 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of MD5 types as the values supported by the
|
6
|
+
# Pinboard API.
|
7
|
+
class MD5 < Identity
|
8
|
+
# The length of an MD5 value.
|
9
|
+
LENGTH = 32
|
10
|
+
# The valid characters in an MD5 value.
|
11
|
+
CHARACTERS = '0123456789abcdf'.freeze
|
12
|
+
|
13
|
+
# Validate something is a valid MD5 parameter.
|
14
|
+
#
|
15
|
+
# value - A String containing the MD5 to validate.
|
16
|
+
#
|
17
|
+
# Returns nothing.
|
18
|
+
# Raises Types::ValidationError if the value is not a 32 character
|
19
|
+
# hexadecimal MD5 hash.
|
20
|
+
def self.validate(value)
|
21
|
+
unless value.length == 32 &&
|
22
|
+
value.each_char.all? { |char| CHARACTERS.include?(char) }
|
23
|
+
fail ValidationError,
|
24
|
+
"#{value} must be a 32 character hexadecimal MD5 hash"
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of tag lists as the values supported by the
|
6
|
+
# Pinboard API.
|
7
|
+
class Tags
|
8
|
+
# The maximum tag length.
|
9
|
+
MAXIMUM_LENGTH = 255
|
10
|
+
# Tags cannot have commas.
|
11
|
+
INVALID_CHARACTER = ','.freeze
|
12
|
+
# Tag parameters are separated by spaces.
|
13
|
+
SEPARATOR = ' '.freeze
|
14
|
+
|
15
|
+
# Validate a tags value.
|
16
|
+
#
|
17
|
+
# value - A String containing a single tag or an Array containing many
|
18
|
+
# tags.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
# Raises Types::ValidationError if any tag contains commas or are longer
|
22
|
+
# than 255 characters.
|
23
|
+
def self.validate(value)
|
24
|
+
Array(value).each do |tag|
|
25
|
+
unless tag.length < MAXIMUM_LENGTH && !tag.include?(INVALID_CHARACTER)
|
26
|
+
fail ValidationError,
|
27
|
+
"#{tag} cannot contain commas or be longer than 255 characters"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# Convert a tag value to a parameter acceptable to the Pinboard API.
|
34
|
+
#
|
35
|
+
# value - A String containing a single tag or an Array containing many
|
36
|
+
# tags.
|
37
|
+
#
|
38
|
+
# Returns a String containing the tags, space-separated.
|
39
|
+
def self.to_parameter(value)
|
40
|
+
Array(value).map(&:strip).join(SEPARATOR)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convert a parameter from the Pinboard API to an Array of tags.
|
44
|
+
#
|
45
|
+
# parameter - A String containing space-separated tags.
|
46
|
+
#
|
47
|
+
# Returns an Array of tags.
|
48
|
+
def self.from_parameter(parameter)
|
49
|
+
parameter.split(SEPARATOR)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of text values as supported by Pinboard.
|
6
|
+
class Text < Identity
|
7
|
+
# Maximum length of a text value.
|
8
|
+
MAXIMUM_LENGTH = 65_536
|
9
|
+
|
10
|
+
# Validate text.
|
11
|
+
#
|
12
|
+
# value - A String containing the text to validate.
|
13
|
+
#
|
14
|
+
# Returns nothing.
|
15
|
+
# Raises Types::ValidationError if the value is longer than 65536
|
16
|
+
# characters.
|
17
|
+
def self.validate(value)
|
18
|
+
unless value.length <= MAXIMUM_LENGTH
|
19
|
+
fail ValidationError,
|
20
|
+
"#{value} cannot be greater than #{MAXIMUM_LENGTH} characters"
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of title values as supported by Pinboard.
|
6
|
+
class Title < Identity
|
7
|
+
# Maximum length of a title value.
|
8
|
+
MAXIMUM_LENGTH = 255
|
9
|
+
|
10
|
+
# Validate a title.
|
11
|
+
#
|
12
|
+
# value - A String containing the title to validate.
|
13
|
+
#
|
14
|
+
# Returns nothing.
|
15
|
+
# Raises Types::ValidationError if the value is longer than 255
|
16
|
+
# characters.
|
17
|
+
def self.validate(value)
|
18
|
+
unless value.length <= MAXIMUM_LENGTH
|
19
|
+
fail ValidationError,
|
20
|
+
"#{value} cannot be greater than #{MAXIMUM_LENGTH} characters"
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
module Types
|
5
|
+
# Internal: Handles validation of URL values as supported by Pinboard.
|
6
|
+
class URL < Identity
|
7
|
+
# Valid URL schemes.
|
8
|
+
VALID_SCHEMES = %w(http https javascript mailto ftp file feed).freeze
|
9
|
+
|
10
|
+
# Validate a URL.
|
11
|
+
#
|
12
|
+
# value - A String containing the URL to validate.
|
13
|
+
#
|
14
|
+
# Returns nothing.
|
15
|
+
# Raises Types::ValidationError if the URL's scheme isn't one of http,
|
16
|
+
# https, javascript, mailto, ftp, file, or feed.
|
17
|
+
def self.validate(value)
|
18
|
+
unless VALID_SCHEMES.include? URI(value).scheme
|
19
|
+
fail ValidationError,
|
20
|
+
"scheme must be one of #{VALID_SCHEMES.join(', ')}"
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Handlers for each of the data types in the Pinboard API. See
|
5
|
+
# https://pinboard.in/api/#data
|
6
|
+
module Types
|
7
|
+
# Internal: Raised when given an invalid argument
|
8
|
+
class ValidationError < StandardError; end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Thumbtack
|
4
|
+
# Internal: Wraps API calls related to users.
|
5
|
+
class User
|
6
|
+
# Internal: Creates a new User.
|
7
|
+
#
|
8
|
+
# client - a Thumbtack::Client to communicate with the Pinboard API.
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
# Public: Returns the user's secret RSS key for viewing private feeds.
|
14
|
+
def secret
|
15
|
+
@client.get('/user/secret').fetch('result')
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Returns the user's API token for making calls without a password.
|
19
|
+
def api_token
|
20
|
+
@client.get('/user/api_token').fetch('result')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/thumbtack.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# A simple Pinboard API wrapper
|
4
|
+
module Thumbtack
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'date'
|
8
|
+
require 'json'
|
9
|
+
require 'net/http'
|
10
|
+
require 'uri'
|
11
|
+
|
12
|
+
require 'thumbtack/types'
|
13
|
+
require 'thumbtack/types/boolean'
|
14
|
+
require 'thumbtack/types/date'
|
15
|
+
require 'thumbtack/types/date_time'
|
16
|
+
require 'thumbtack/types/identity'
|
17
|
+
require 'thumbtack/types/integer'
|
18
|
+
require 'thumbtack/types/md5'
|
19
|
+
require 'thumbtack/types/tags'
|
20
|
+
require 'thumbtack/types/text'
|
21
|
+
require 'thumbtack/types/title'
|
22
|
+
require 'thumbtack/types/url'
|
23
|
+
require 'thumbtack/specification'
|
24
|
+
require 'thumbtack/post'
|
25
|
+
require 'thumbtack/posts'
|
26
|
+
require 'thumbtack/tags'
|
27
|
+
require 'thumbtack/user'
|
28
|
+
require 'thumbtack/note'
|
29
|
+
require 'thumbtack/note_summary'
|
30
|
+
require 'thumbtack/notes'
|
31
|
+
require 'thumbtack/client'
|
32
|
+
require 'thumbtack/version'
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'thumbtack'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
def auth_token
|
7
|
+
File.open(File.expand_path('../auth_token.txt', __FILE__)).read.strip
|
8
|
+
end
|
9
|
+
|
10
|
+
def username
|
11
|
+
auth_token.split(':').first
|
12
|
+
end
|
13
|
+
|
14
|
+
def token
|
15
|
+
auth_token.split(':').last
|
16
|
+
end
|
17
|
+
|
18
|
+
include Thumbtack
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class ClientTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@client = Client.new(username, token)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_requests_return_parsed_json
|
11
|
+
response = @client.get('/user/api_token')
|
12
|
+
assert_equal({ 'result' => token }, response)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_request_query_parameters
|
16
|
+
response = @client.get('/tags/delete', tag: 'thumbtack-test-query-params')
|
17
|
+
assert_equal({ 'result' => 'done' }, response)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_posts
|
21
|
+
assert_instance_of Posts, @client.posts
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_tags
|
25
|
+
assert_instance_of Tags, @client.tags
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_user
|
29
|
+
assert_instance_of User, @client.user
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_notes
|
33
|
+
assert_instance_of Notes, @client.notes
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class NoteSummaryTest < Minitest::Test
|
6
|
+
def test_from_hash
|
7
|
+
hash = {
|
8
|
+
'id' => '8e5d6964bb810e0050b0',
|
9
|
+
'title' => 'StarCraft beta coming this week!',
|
10
|
+
'hash' => '0c9c30f60cadabd31415',
|
11
|
+
'created_at' => '2010-02-11 03:46:56',
|
12
|
+
'updated_at' => '2010-02-11 03:47:47',
|
13
|
+
'length' => 19,
|
14
|
+
}
|
15
|
+
note = NoteSummary.from_hash(hash)
|
16
|
+
|
17
|
+
assert_equal '8e5d6964bb810e0050b0', note.id
|
18
|
+
assert_equal 'StarCraft beta coming this week!', note.title
|
19
|
+
assert_equal '0c9c30f60cadabd31415', note.hash
|
20
|
+
assert_equal '2010-02-11 03:46:56', note.created_at
|
21
|
+
assert_equal '2010-02-11 03:47:47', note.updated_at
|
22
|
+
assert_equal 19, note.length
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class NoteTest < Minitest::Test
|
6
|
+
def test_from_hash
|
7
|
+
hash = {
|
8
|
+
'id' => '8e5d6964bb810e0050b0',
|
9
|
+
'title' => 'StarCraft beta coming this week!',
|
10
|
+
'hash' => '0c9c30f60cadabd31415',
|
11
|
+
'created_at' => '2010-02-11 03:46:56',
|
12
|
+
'updated_at' => '2010-02-11 03:47:47',
|
13
|
+
'length' => 19,
|
14
|
+
'text' => 'This is a test note'
|
15
|
+
}
|
16
|
+
note = Note.from_hash(hash)
|
17
|
+
|
18
|
+
assert_equal '8e5d6964bb810e0050b0', note.id
|
19
|
+
assert_equal 'StarCraft beta coming this week!', note.title
|
20
|
+
assert_equal '0c9c30f60cadabd31415', note.hash
|
21
|
+
assert_equal '2010-02-11 03:46:56', note.created_at
|
22
|
+
assert_equal '2010-02-11 03:47:47', note.updated_at
|
23
|
+
assert_equal 19, note.length
|
24
|
+
assert_equal 'This is a test note', note.text
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class NotesTest < Minitest::Test
|
6
|
+
def mock_client(url, params, response)
|
7
|
+
client = Minitest::Mock.new
|
8
|
+
client.expect(:get, response, [url, params].compact)
|
9
|
+
client
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_list
|
13
|
+
client = mock_client('/notes/list',
|
14
|
+
nil,
|
15
|
+
{
|
16
|
+
'count' => 2,
|
17
|
+
'notes' => [
|
18
|
+
{
|
19
|
+
'id' => 'cf73bfc02e00edaa1e2b',
|
20
|
+
'title' => 'Paul Graham on Hirin\' The Ladies',
|
21
|
+
'hash' => '0bbca3cba9246bbbda2c',
|
22
|
+
'created_at' => '2011-10-28 13:37:23',
|
23
|
+
'updated_at' => '2011-10-28 13:37:23',
|
24
|
+
'length' => '890',
|
25
|
+
},
|
26
|
+
{
|
27
|
+
'id' => '8e5d6964bb810e0050b0',
|
28
|
+
'title' => 'StarCraft beta coming this week!',
|
29
|
+
'hash' => '0c9c30f60cadabd31415',
|
30
|
+
'created_at' => '2010-02-11 03:46:56',
|
31
|
+
'updated_at' => '2010-02-11 03:47:47',
|
32
|
+
'length' => '153',
|
33
|
+
},
|
34
|
+
]
|
35
|
+
})
|
36
|
+
notes = Notes.new(client)
|
37
|
+
result = notes.list
|
38
|
+
|
39
|
+
assert_equal 2, result.length
|
40
|
+
assert_equal 'cf73bfc02e00edaa1e2b', result[0].id
|
41
|
+
assert_equal '8e5d6964bb810e0050b0', result[1].id
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_list
|
45
|
+
client = mock_client('/notes/8e5d6964bb810e0050b0',
|
46
|
+
nil,
|
47
|
+
{
|
48
|
+
'id' => '8e5d6964bb810e0050b0',
|
49
|
+
'title' => 'StarCraft beta coming this week!',
|
50
|
+
'text' => 'This is a test note',
|
51
|
+
'hash' => '0c9c30f60cadabd31415',
|
52
|
+
'created_at' => '2010-02-11 03:46:56',
|
53
|
+
'updated_at' => '2010-02-11 03:47:47',
|
54
|
+
'length' => 19
|
55
|
+
})
|
56
|
+
notes = Notes.new(client)
|
57
|
+
result = notes.get('8e5d6964bb810e0050b0')
|
58
|
+
assert_equal '8e5d6964bb810e0050b0', result.id
|
59
|
+
assert_equal 19, result.length
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class PostTest < Minitest::Test
|
6
|
+
def test_from_hash
|
7
|
+
hash = {
|
8
|
+
'href' => 'http://example.org',
|
9
|
+
'description' => 'example.org',
|
10
|
+
'extended' => '',
|
11
|
+
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
12
|
+
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
13
|
+
'time' => '2014-06-29T16:57:45Z',
|
14
|
+
'shared' => 'yes',
|
15
|
+
'toread' => 'no',
|
16
|
+
'tags' => 'test123'
|
17
|
+
}
|
18
|
+
post = Post.from_hash(hash)
|
19
|
+
|
20
|
+
assert_equal 'http://example.org', post.href
|
21
|
+
assert_equal 'example.org', post.description
|
22
|
+
assert_equal '', post.extended
|
23
|
+
assert_equal '46ca40b9b92ee0ea1284785a5d2a9b38', post.meta
|
24
|
+
assert_equal 'dab521de65f9250b4cca7383feef67dc', post.hash
|
25
|
+
assert_equal '2014-06-29T16:57:45Z', post.time
|
26
|
+
assert_equal 'yes', post.shared
|
27
|
+
assert_equal 'no', post.toread
|
28
|
+
assert_equal 'test123', post.tags
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class PostsTest < Minitest::Test
|
6
|
+
def mock_client(url, params, response)
|
7
|
+
client = Minitest::Mock.new
|
8
|
+
client.expect(:get, response, [url, params].compact)
|
9
|
+
client
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_update
|
13
|
+
client = mock_client('/posts/update',
|
14
|
+
nil,
|
15
|
+
{ 'update_time' => '2014-06-26T19:01:33Z' })
|
16
|
+
posts = Posts.new(client)
|
17
|
+
|
18
|
+
assert_equal DateTime.new(2014, 6, 26, 19, 1, 33), posts.update
|
19
|
+
client.verify
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_add
|
23
|
+
client = mock_client('/posts/add',
|
24
|
+
{ url: 'http://example.org',
|
25
|
+
description: 'example.org' },
|
26
|
+
{ 'result_code' => 'done' })
|
27
|
+
posts = Posts.new(client)
|
28
|
+
|
29
|
+
assert_equal posts, posts.add('http://example.org', 'example.org')
|
30
|
+
client.verify
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_add_with_tags
|
34
|
+
client = mock_client('/posts/add',
|
35
|
+
{ url: 'http://example.org',
|
36
|
+
description: 'example.org',
|
37
|
+
tags: 'thumbtack test' },
|
38
|
+
{ 'result_code' => 'done' })
|
39
|
+
posts = Posts.new(client)
|
40
|
+
|
41
|
+
assert_equal posts,
|
42
|
+
posts.add('http://example.org', 'example.org', tags: %w(thumbtack test))
|
43
|
+
client.verify
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_delete
|
47
|
+
client = mock_client('/posts/delete',
|
48
|
+
{ url: 'http://example.org' },
|
49
|
+
{ 'result_code' => 'done' })
|
50
|
+
posts = Posts.new(client)
|
51
|
+
|
52
|
+
assert_equal posts, posts.delete('http://example.org')
|
53
|
+
client.verify
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_get
|
57
|
+
client = mock_client('/posts/get',
|
58
|
+
{ url: 'http://example.org' },
|
59
|
+
{
|
60
|
+
'date' => '2014-06-29T16:57:45Z',
|
61
|
+
'user' => 'nwjsmith',
|
62
|
+
'posts' => [{
|
63
|
+
'href' => 'http://example.org',
|
64
|
+
'description' => 'example.org',
|
65
|
+
'extended' => '',
|
66
|
+
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
67
|
+
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
68
|
+
'time' => '2014-06-29T16:57:45Z',
|
69
|
+
'shared' => 'yes',
|
70
|
+
'toread' => 'no',
|
71
|
+
'tags' => 'test123'
|
72
|
+
}]
|
73
|
+
})
|
74
|
+
posts = Posts.new(client)
|
75
|
+
response = posts.get(url: 'http://example.org')
|
76
|
+
|
77
|
+
assert_equal 1, response.size
|
78
|
+
assert_equal 'http://example.org', response.first.href
|
79
|
+
client.verify
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_recent
|
83
|
+
client = mock_client('/posts/recent',
|
84
|
+
{tag: 'webdev'},
|
85
|
+
{
|
86
|
+
'date' => '2014-06-29T16:57:45Z',
|
87
|
+
'user' => 'nwjsmith',
|
88
|
+
'posts' => [{
|
89
|
+
'href' => 'http://example.org',
|
90
|
+
'description' => 'example.org',
|
91
|
+
'extended' => '',
|
92
|
+
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
93
|
+
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
94
|
+
'time' => '2014-06-29T16:57:45Z',
|
95
|
+
'shared' => 'yes',
|
96
|
+
'toread' => 'no',
|
97
|
+
'tags' => 'webdev'
|
98
|
+
}]
|
99
|
+
})
|
100
|
+
posts = Posts.new(client)
|
101
|
+
response = posts.recent(tag: 'webdev')
|
102
|
+
|
103
|
+
assert_equal 1, response.size
|
104
|
+
assert_equal 'http://example.org', response.first.href
|
105
|
+
client.verify
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_all
|
109
|
+
client = mock_client('/posts/all',
|
110
|
+
{tag: 'webdev'},
|
111
|
+
[{
|
112
|
+
'href' => 'http://example.org',
|
113
|
+
'description' => 'example.org',
|
114
|
+
'extended' => '',
|
115
|
+
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
116
|
+
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
117
|
+
'time' => '2014-06-29T16:57:45Z',
|
118
|
+
'shared' => 'yes',
|
119
|
+
'toread' => 'no',
|
120
|
+
'tags' => 'webdev'
|
121
|
+
}])
|
122
|
+
posts = Posts.new(client)
|
123
|
+
response = posts.all(tag: 'webdev')
|
124
|
+
|
125
|
+
assert_equal 1, response.size
|
126
|
+
assert_equal 'http://example.org', response.first.href
|
127
|
+
client.verify
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_suggest
|
131
|
+
client = mock_client('/posts/suggest',
|
132
|
+
{url: 'http://blog.com'},
|
133
|
+
{
|
134
|
+
'popular' => ['blog', 'blogs', 'people', 'writing'],
|
135
|
+
'recommended' => ['blog', 'writing', 'weblog']
|
136
|
+
})
|
137
|
+
posts = Posts.new(client)
|
138
|
+
response = posts.suggest('http://blog.com')
|
139
|
+
|
140
|
+
assert_equal 2, response.size
|
141
|
+
assert_equal 'blog', response[:popular].first
|
142
|
+
assert_equal 'weblog', response[:recommended].last
|
143
|
+
client.verify
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_dates
|
147
|
+
client = mock_client('/posts/dates',
|
148
|
+
{tag: 'argentina'},
|
149
|
+
{
|
150
|
+
'user' => 'user',
|
151
|
+
'tag' => 'argentina',
|
152
|
+
'dates' => {
|
153
|
+
'2010-11-29' => '5',
|
154
|
+
'2010-11-28' => '15',
|
155
|
+
'2010-11-26' => '2',
|
156
|
+
'2010-11-25' => '2',
|
157
|
+
'2010-11-23' => '7',
|
158
|
+
'2010-11-22' => '20',
|
159
|
+
'2010-11-21' => '16',
|
160
|
+
'2010-11-19' => '4'
|
161
|
+
}
|
162
|
+
})
|
163
|
+
posts = Posts.new(client)
|
164
|
+
response = posts.dates(tag: 'argentina')
|
165
|
+
|
166
|
+
assert_equal({
|
167
|
+
Date.new(2010, 11, 29) => 5,
|
168
|
+
Date.new(2010, 11, 28) => 15,
|
169
|
+
Date.new(2010, 11, 26) => 2,
|
170
|
+
Date.new(2010, 11, 25) => 2,
|
171
|
+
Date.new(2010, 11, 23) => 7,
|
172
|
+
Date.new(2010, 11, 22) => 20,
|
173
|
+
Date.new(2010, 11, 21) => 16,
|
174
|
+
Date.new(2010, 11, 19) => 4
|
175
|
+
}, response)
|
176
|
+
client.verify
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class SpecificationTest < Minitest::Test
|
6
|
+
def test_parameters
|
7
|
+
type_handler = Minitest::Mock.new
|
8
|
+
type_handler.expect(:validate, type_handler, ['value'])
|
9
|
+
type_handler.expect(:to_parameter, 'parameterized', ['value'])
|
10
|
+
|
11
|
+
assert_equal({ key: 'parameterized' },
|
12
|
+
Specification.new(key: type_handler).parameters(key: 'value'))
|
13
|
+
type_handler.verify
|
14
|
+
end
|
15
|
+
end
|