thumbtack 1.1.1 → 2.0.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.
- checksums.yaml +5 -5
- data/lib/thumbtack.rb +3 -3
- data/lib/thumbtack/adapters/basic_adapter.rb +31 -6
- data/lib/thumbtack/client.rb +3 -2
- data/lib/thumbtack/hash_to_digest.rb +5 -4
- data/lib/thumbtack/note.rb +15 -15
- data/lib/thumbtack/note_summary.rb +14 -14
- data/lib/thumbtack/notes.rb +1 -1
- data/lib/thumbtack/post.rb +14 -14
- data/lib/thumbtack/posts.rb +11 -11
- data/lib/thumbtack/specification.rb +1 -1
- data/lib/thumbtack/suggestion.rb +3 -3
- data/lib/thumbtack/symbolize_keys.rb +1 -1
- data/lib/thumbtack/tags.rb +1 -1
- data/lib/thumbtack/types/boolean.rb +2 -2
- data/lib/thumbtack/types/date.rb +1 -1
- data/lib/thumbtack/types/identity.rb +1 -1
- data/lib/thumbtack/types/integer.rb +1 -1
- data/lib/thumbtack/types/length_validation.rb +3 -3
- data/lib/thumbtack/types/md5.rb +4 -4
- data/lib/thumbtack/types/range_validation.rb +3 -3
- data/lib/thumbtack/types/tags.rb +7 -7
- data/lib/thumbtack/types/text.rb +1 -1
- data/lib/thumbtack/types/{date_time.rb → time.rb} +13 -13
- data/lib/thumbtack/types/title.rb +1 -1
- data/lib/thumbtack/types/url.rb +4 -4
- data/lib/thumbtack/user.rb +1 -1
- data/lib/thumbtack/version.rb +2 -2
- data/test/test_helper.rb +7 -4
- data/test/thumbtack/client_test.rb +1 -1
- data/test/thumbtack/integration/basic_adapter_test.rb +2 -2
- data/test/thumbtack/note_summary_test.rb +3 -3
- data/test/thumbtack/note_test.rb +3 -3
- data/test/thumbtack/notes_test.rb +1 -1
- data/test/thumbtack/post_test.rb +3 -3
- data/test/thumbtack/posts_test.rb +24 -46
- data/test/thumbtack/specification_test.rb +3 -2
- data/test/thumbtack/suggestion_test.rb +5 -5
- data/test/thumbtack/tags_test.rb +1 -9
- data/test/thumbtack/types/boolean_test.rb +1 -1
- data/test/thumbtack/types/date_test.rb +1 -1
- data/test/thumbtack/types/identity_test.rb +1 -1
- data/test/thumbtack/types/integer_test.rb +1 -1
- data/test/thumbtack/types/md5_test.rb +1 -1
- data/test/thumbtack/types/tags_test.rb +3 -3
- data/test/thumbtack/types/text_test.rb +1 -1
- data/test/thumbtack/types/time_test.rb +32 -0
- data/test/thumbtack/types/title_test.rb +1 -1
- data/test/thumbtack/types/url_test.rb +1 -1
- data/test/thumbtack/user_test.rb +1 -1
- metadata +37 -39
- data/test/thumbtack/types/date_time_test.rb +0 -33
data/lib/thumbtack/types/date.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
@@ -19,8 +19,8 @@ module Thumbtack
|
|
19
19
|
# if the value is not less or equal to the maximum length
|
20
20
|
def self.validate(value, maximum_length)
|
21
21
|
unless value.length <= maximum_length
|
22
|
-
|
23
|
-
|
22
|
+
raise ValidationError,
|
23
|
+
"#{value} cannot be greater than #{maximum_length} characters"
|
24
24
|
end
|
25
25
|
self
|
26
26
|
end
|
data/lib/thumbtack/types/md5.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
@@ -9,7 +9,7 @@ module Thumbtack
|
|
9
9
|
# The length of an MD5 value
|
10
10
|
LENGTH = 32
|
11
11
|
# The valid characters in an MD5 value
|
12
|
-
CHARACTERS = '0123456789abcdf'
|
12
|
+
CHARACTERS = '0123456789abcdf'
|
13
13
|
|
14
14
|
# Validate a string is a valid MD5 parameter
|
15
15
|
#
|
@@ -22,8 +22,8 @@ module Thumbtack
|
|
22
22
|
# if the value is not a 32 character hexadecimal MD5 hash
|
23
23
|
def self.validate(value)
|
24
24
|
unless valid_md5?(value)
|
25
|
-
|
26
|
-
|
25
|
+
raise ValidationError,
|
26
|
+
"#{value} must be a 32 character hexadecimal MD5 hash"
|
27
27
|
end
|
28
28
|
self
|
29
29
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
@@ -22,8 +22,8 @@ module Thumbtack
|
|
22
22
|
# if the value is not within the range
|
23
23
|
def self.validate(value, range)
|
24
24
|
unless range.cover?(value)
|
25
|
-
|
26
|
-
|
25
|
+
raise ValidationError,
|
26
|
+
"#{value} must be between #{range.begin} and #{range.end}"
|
27
27
|
end
|
28
28
|
self
|
29
29
|
end
|
data/lib/thumbtack/types/tags.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
@@ -10,9 +10,9 @@ module Thumbtack
|
|
10
10
|
# The maximum tag length
|
11
11
|
MAXIMUM_LENGTH = 255
|
12
12
|
# Tags cannot have commas
|
13
|
-
INVALID_CHARACTER = ','
|
13
|
+
INVALID_CHARACTER = ','
|
14
14
|
# Tag parameters are separated by spaces
|
15
|
-
SEPARATOR = ' '
|
15
|
+
SEPARATOR = ' '
|
16
16
|
|
17
17
|
# Validate a tags value
|
18
18
|
#
|
@@ -25,10 +25,10 @@ module Thumbtack
|
|
25
25
|
# if any tags contain commas or are longer than 255 characters
|
26
26
|
def self.validate(value)
|
27
27
|
Array(value).each do |tag|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
next if tag_valid?(tag)
|
29
|
+
|
30
|
+
raise ValidationError,
|
31
|
+
"#{tag} cannot contain commas or be longer than 255 characters"
|
32
32
|
end
|
33
33
|
self
|
34
34
|
end
|
data/lib/thumbtack/types/text.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
5
|
-
# Handles conversion and validation of
|
5
|
+
# Handles conversion and validation of Times to parameters supported by
|
6
6
|
# Pinboard
|
7
7
|
#
|
8
8
|
# @api private
|
9
|
-
class
|
9
|
+
class Time
|
10
10
|
# The earliest allowable time
|
11
|
-
EARLIEST = ::
|
11
|
+
EARLIEST = ::Time.new(1, 1, 1, 0, 0, 0, 0)
|
12
12
|
# The latest allowable time
|
13
|
-
LATEST = ::
|
13
|
+
LATEST = ::Time.new(2100, 1, 1, 0, 0, 0, 0)
|
14
14
|
# Pinboard's date time format
|
15
|
-
FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
15
|
+
FORMAT = '%Y-%m-%dT%H:%M:%SZ'
|
16
16
|
# Pinboard's date time format for notes
|
17
|
-
NOTE_FORMAT = '%Y-%m-%d %H:%M:%S'
|
17
|
+
NOTE_FORMAT = '%Y-%m-%d %H:%M:%S'
|
18
18
|
|
19
19
|
# Validate a time
|
20
20
|
#
|
21
|
-
# @param [
|
21
|
+
# @param [Time] value
|
22
22
|
# The time to validate
|
23
23
|
#
|
24
24
|
# @return [self]
|
@@ -32,7 +32,7 @@ module Thumbtack
|
|
32
32
|
|
33
33
|
# Convert a time to a parameter acceptable to Pinboard
|
34
34
|
#
|
35
|
-
# @param [
|
35
|
+
# @param [Time] value
|
36
36
|
# the time to convert
|
37
37
|
#
|
38
38
|
# @return [String]
|
@@ -46,9 +46,9 @@ module Thumbtack
|
|
46
46
|
# @param [String] parameter
|
47
47
|
# the time formatted yyyy-mm-ddTHH:MM:SSZ
|
48
48
|
#
|
49
|
-
# @return [
|
49
|
+
# @return [Time]
|
50
50
|
def self.deserialize(parameter)
|
51
|
-
::
|
51
|
+
::Time.strptime(parameter, FORMAT)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Convert a parameter from Pinboard's notes to a datetime value
|
@@ -56,9 +56,9 @@ module Thumbtack
|
|
56
56
|
# @param [String] parameter
|
57
57
|
# the time formatted yyyy-mm-dd HH:MM:SS
|
58
58
|
#
|
59
|
-
# @return [
|
59
|
+
# @return [Time]
|
60
60
|
def self.deserialize_from_note(parameter)
|
61
|
-
::
|
61
|
+
::Time.strptime(parameter, NOTE_FORMAT)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
data/lib/thumbtack/types/url.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Thumbtack
|
4
4
|
module Types
|
@@ -7,7 +7,7 @@ module Thumbtack
|
|
7
7
|
# @api private
|
8
8
|
class URL < Identity
|
9
9
|
# Valid URL schemes
|
10
|
-
VALID_SCHEMES = %w
|
10
|
+
VALID_SCHEMES = %w[http https javascript mailto ftp file feed].freeze
|
11
11
|
|
12
12
|
# Validate a URL
|
13
13
|
#
|
@@ -21,8 +21,8 @@ module Thumbtack
|
|
21
21
|
# file, or feed
|
22
22
|
def self.validate(value)
|
23
23
|
unless VALID_SCHEMES.include? URI(value).scheme
|
24
|
-
|
25
|
-
|
24
|
+
raise ValidationError,
|
25
|
+
"scheme must be one of #{VALID_SCHEMES.join(', ')}"
|
26
26
|
end
|
27
27
|
self
|
28
28
|
end
|
data/lib/thumbtack/user.rb
CHANGED
data/lib/thumbtack/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if ENV.fetch('COVERAGE', false)
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start { add_filter 'test/' }
|
6
|
+
end
|
4
7
|
|
5
8
|
require 'thumbtack'
|
6
9
|
require 'minitest/autorun'
|
@@ -17,4 +20,4 @@ def mock_client_action(url, params)
|
|
17
20
|
client
|
18
21
|
end
|
19
22
|
|
20
|
-
include Thumbtack
|
23
|
+
Minitest::Test.include Thumbtack
|
@@ -1,11 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
module Integration
|
6
6
|
class BasicAdapterTest < Minitest::Test
|
7
7
|
def setup
|
8
|
-
path = File.expand_path('
|
8
|
+
path = File.expand_path('../../auth_token.txt', __dir__)
|
9
9
|
auth_token = File.open(path).read.strip
|
10
10
|
@username, @token = auth_token.split(':')
|
11
11
|
@adapter = Adapters::BasicAdapter.new(@username, @token)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
@@ -17,8 +17,8 @@ class NoteSummaryTest < Minitest::Test
|
|
17
17
|
assert_equal '8e5d6964bb810e0050b0', note.id
|
18
18
|
assert_equal 'StarCraft beta coming this week!', note.title
|
19
19
|
assert_equal '0c9c30f60cadabd31415', note.digest
|
20
|
-
assert_equal
|
21
|
-
assert_equal
|
20
|
+
assert_equal Time.new(2010, 2, 11, 3, 46, 56), note.created_at
|
21
|
+
assert_equal Time.new(2010, 2, 11, 3, 47, 47), note.updated_at
|
22
22
|
assert_equal 19, note.length
|
23
23
|
end
|
24
24
|
end
|
data/test/thumbtack/note_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
@@ -18,8 +18,8 @@ class NoteTest < Minitest::Test
|
|
18
18
|
assert_equal '8e5d6964bb810e0050b0', note.id
|
19
19
|
assert_equal 'StarCraft beta coming this week!', note.title
|
20
20
|
assert_equal '0c9c30f60cadabd31415', note.digest
|
21
|
-
assert_equal
|
22
|
-
assert_equal
|
21
|
+
assert_equal Time.new(2010, 2, 11, 3, 46, 56), note.created_at
|
22
|
+
assert_equal Time.new(2010, 2, 11, 3, 47, 47), note.updated_at
|
23
23
|
assert_equal 19, note.length
|
24
24
|
assert_equal 'This is a test note', note.text
|
25
25
|
end
|
data/test/thumbtack/post_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
@@ -22,9 +22,9 @@ class PostTest < Minitest::Test
|
|
22
22
|
assert_equal '', post.extended
|
23
23
|
assert_equal '46ca40b9b92ee0ea1284785a5d2a9b38', post.meta
|
24
24
|
assert_equal 'dab521de65f9250b4cca7383feef67dc', post.digest
|
25
|
-
assert_equal
|
25
|
+
assert_equal Time.new(2014, 6, 29, 16, 57, 45), post.time
|
26
26
|
assert_equal true, post.shared
|
27
27
|
assert_equal false, post.toread
|
28
|
-
assert_equal %w
|
28
|
+
assert_equal %w[test123 another], post.tags
|
29
29
|
end
|
30
30
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
@@ -11,7 +11,7 @@ class PostsTest < Minitest::Test
|
|
11
11
|
)
|
12
12
|
posts = Posts.new(client)
|
13
13
|
|
14
|
-
assert_equal
|
14
|
+
assert_equal Time.new(2014, 6, 26, 19, 1, 33), posts.update
|
15
15
|
client.verify
|
16
16
|
end
|
17
17
|
|
@@ -40,7 +40,7 @@ class PostsTest < Minitest::Test
|
|
40
40
|
posts.add(
|
41
41
|
'http://example.org',
|
42
42
|
'example.org',
|
43
|
-
tags: %w
|
43
|
+
tags: %w[thumbtack test]
|
44
44
|
)
|
45
45
|
client.verify
|
46
46
|
end
|
@@ -62,17 +62,7 @@ class PostsTest < Minitest::Test
|
|
62
62
|
{ url: 'http://example.org' },
|
63
63
|
'date' => '2014-06-29T16:57:45Z',
|
64
64
|
'user' => 'nwjsmith',
|
65
|
-
'posts' => [
|
66
|
-
'href' => 'http://example.org',
|
67
|
-
'description' => 'example.org',
|
68
|
-
'extended' => '',
|
69
|
-
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
70
|
-
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
71
|
-
'time' => '2014-06-29T16:57:45Z',
|
72
|
-
'shared' => 'yes',
|
73
|
-
'toread' => 'no',
|
74
|
-
'tags' => 'test123'
|
75
|
-
}]
|
65
|
+
'posts' => [example_post_hash]
|
76
66
|
)
|
77
67
|
posts = Posts.new(client)
|
78
68
|
response = posts.get(url: 'http://example.org')
|
@@ -88,17 +78,7 @@ class PostsTest < Minitest::Test
|
|
88
78
|
{ tag: 'webdev' },
|
89
79
|
'date' => '2014-06-29T16:57:45Z',
|
90
80
|
'user' => 'nwjsmith',
|
91
|
-
'posts' => [
|
92
|
-
'href' => 'http://example.org',
|
93
|
-
'description' => 'example.org',
|
94
|
-
'extended' => '',
|
95
|
-
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
96
|
-
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
97
|
-
'time' => '2014-06-29T16:57:45Z',
|
98
|
-
'shared' => 'yes',
|
99
|
-
'toread' => 'no',
|
100
|
-
'tags' => 'webdev'
|
101
|
-
}]
|
81
|
+
'posts' => [example_post_hash]
|
102
82
|
)
|
103
83
|
posts = Posts.new(client)
|
104
84
|
response = posts.recent(tag: 'webdev')
|
@@ -112,19 +92,7 @@ class PostsTest < Minitest::Test
|
|
112
92
|
client = mock_client_get(
|
113
93
|
'/posts/all',
|
114
94
|
{ tag: 'webdev' },
|
115
|
-
[
|
116
|
-
{
|
117
|
-
'href' => 'http://example.org',
|
118
|
-
'description' => 'example.org',
|
119
|
-
'extended' => '',
|
120
|
-
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
121
|
-
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
122
|
-
'time' => '2014-06-29T16:57:45Z',
|
123
|
-
'shared' => 'yes',
|
124
|
-
'toread' => 'no',
|
125
|
-
'tags' => 'webdev'
|
126
|
-
}
|
127
|
-
]
|
95
|
+
[example_post_hash]
|
128
96
|
)
|
129
97
|
posts = Posts.new(client)
|
130
98
|
response = posts.all(tag: 'webdev')
|
@@ -139,8 +107,8 @@ class PostsTest < Minitest::Test
|
|
139
107
|
'/posts/suggest',
|
140
108
|
{ url: 'http://blog.com' },
|
141
109
|
[
|
142
|
-
{ 'popular' => %w
|
143
|
-
{ 'recommended' => %w
|
110
|
+
{ 'popular' => %w[blog blogs people] },
|
111
|
+
{ 'recommended' => %w[blog writing weblog] }
|
144
112
|
]
|
145
113
|
)
|
146
114
|
posts = Posts.new(client)
|
@@ -159,10 +127,7 @@ class PostsTest < Minitest::Test
|
|
159
127
|
'tag' => 'argentina',
|
160
128
|
'dates' => {
|
161
129
|
'2010-11-29' => '5',
|
162
|
-
'2010-11-28' => '15',
|
163
|
-
'2010-11-26' => '2',
|
164
130
|
'2010-11-25' => '2',
|
165
|
-
'2010-11-23' => '7',
|
166
131
|
'2010-11-22' => '20',
|
167
132
|
'2010-11-21' => '16',
|
168
133
|
'2010-11-19' => '4'
|
@@ -174,10 +139,7 @@ class PostsTest < Minitest::Test
|
|
174
139
|
assert_equal(
|
175
140
|
{
|
176
141
|
Date.new(2010, 11, 29) => 5,
|
177
|
-
Date.new(2010, 11, 28) => 15,
|
178
|
-
Date.new(2010, 11, 26) => 2,
|
179
142
|
Date.new(2010, 11, 25) => 2,
|
180
|
-
Date.new(2010, 11, 23) => 7,
|
181
143
|
Date.new(2010, 11, 22) => 20,
|
182
144
|
Date.new(2010, 11, 21) => 16,
|
183
145
|
Date.new(2010, 11, 19) => 4
|
@@ -186,4 +148,20 @@ class PostsTest < Minitest::Test
|
|
186
148
|
)
|
187
149
|
client.verify
|
188
150
|
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def example_post_hash
|
155
|
+
{
|
156
|
+
'href' => 'http://example.org',
|
157
|
+
'description' => 'example.org',
|
158
|
+
'extended' => '',
|
159
|
+
'meta' => '46ca40b9b92ee0ea1284785a5d2a9b38',
|
160
|
+
'hash' => 'dab521de65f9250b4cca7383feef67dc',
|
161
|
+
'time' => '2014-06-29T16:57:45Z',
|
162
|
+
'shared' => 'yes',
|
163
|
+
'toread' => 'no',
|
164
|
+
'tags' => 'webdev'
|
165
|
+
}
|
166
|
+
end
|
189
167
|
end
|