pocket-ruby 0.1.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 820f73644ee1f21cea8033e70e5c3c038b6dc061cb9e05b36c3ede86421763e1
4
- data.tar.gz: 30744f3d1257e1d7fcee9cda79abf518f4277d996c8716720ec6cc1bbbce59f8
3
+ metadata.gz: 4d5d9cc7d714e363b5d185ab6c83f9c60c7650dca3bb80942d490342c1b296f1
4
+ data.tar.gz: 895f07cc0c151ab089fbd02a41776894ce94a4a87f5e35e2f3597f3321d531ab
5
5
  SHA512:
6
- metadata.gz: acb0b74a3bd7df194b1ed532dc7f54a1eb860d5632f1854aab803c905c9f8c4c7d3fe23b42553507b82165776a892d93ac38f98874cc5c811cbb81dfcd34b76c
7
- data.tar.gz: e2526ed17125c7c51be1d8baaaa1d30e610858c0968b03348e875aeec75a9384cc566b65b0ca5c02ab85aff5e0288f3fc8d02ce4b364a99e98a820a11debe830
6
+ metadata.gz: 17946cffbd9fdab7faac7e635e2611f0715525f5ad17aa731e0c03c2449bb5f8c1f7bea9d59803bfa81369b55df271cd580106a7aad04ad5cee7d52c0b657e08
7
+ data.tar.gz: 5fcd4d7e3bede834b735ec8efe4e3a024576f358c599f2028e325acf1bd3dc986b1bb60ea42a4c72a886c872c6ff13571fbed792d60326ff28c5495334cae121
data/.yardopts CHANGED
@@ -1,9 +1,6 @@
1
1
  --no-private
2
2
  --protected
3
- --tag format:"Supported formats"
4
- --tag authenticated:"Requires Authentication"
5
- --tag rate_limited:"Rate Limited"
6
3
  --markup markdown
4
+ --output-dir doc/yard
7
5
  -
8
- HISTORY.mkd
9
- LICENSE.mkd
6
+ LICENSE.md
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.0] - 2021-05-15
4
+
5
+ - Use Sinatra 2. ([#92](https://github.com/turadg/pocket-ruby/pull/92))
6
+ - Add `Pocket::Image` class. ([#90](https://github.com/turadg/pocket-ruby/pull/90))
7
+ - Fix demo server. ([#93](https://github.com/turadg/pocket-ruby/pull/33))
8
+ - Fix docs generation. ([#89](https://github.com/turadg/pocket-ruby/pull/89))
9
+ - Add `unfavorite` operation. ([#87](https://github.com/turadg/pocket-ruby/pull/87))
10
+ - Add `favorite` operation. ([#86](https://github.com/turadg/pocket-ruby/pull/86))
11
+
12
+ ## [0.4.0] - 2021-04-18
13
+
14
+ - Fix Faraday error handling. ([#81](https://github.com/turadg/pocket-ruby/pull/81))
15
+ - Don't assume `is_article` is present ([#78](https://github.com/turadg/pocket-ruby/pull/78)).
16
+ - Handle article with missing `resolved_url` or `resolved_title` ([#77](https://github.com/turadg/pocket-ruby/pull/77))
17
+ - Remove unnecessary use of `method_missing`. ([#71](https://github.com/turadg/pocket-ruby/pull/71))
18
+ - Simplify internal structure for `Client` class and modules.
19
+
20
+ ## [0.3.0] - 2021-04-11
21
+
22
+ - Hand article with missing `excerpt`. ([#63](https://github.com/turadg/pocket-ruby/pull/63))
23
+ - Add support for `domain_metadata` in Article response. ([#57](https://github.com/turadg/pocket-ruby/pull/57))
24
+ - Add `time_to_read` field to `Pocket::Article`.
25
+ - Return nil for `word_count` if not present ([#48](https://github.com/turadg/pocket-ruby/pull/48))
26
+
27
+ ## [0.2.1] - 2021-04-10
28
+
29
+ - Return nil if `time_read` or `time_favorited` is '0' in the API response. Otherwise, this may be interpreted the Unix epoch (1970-01-01). ([#46](https://github.com/turadg/pocket-ruby/pull/46))
30
+
31
+ ## [0.2.0] - 2021-04-03
32
+
33
+ - Add support for authors and tags in `Pocket::Article` ([#44](https://github.com/turadg/pocket-ruby/pull/44))
34
+
3
35
  ## [0.1.0] - 2021-04-03
4
36
 
5
37
  - Add `Pocket::Article` for parsing an article response ([#39](https://github.com/turadg/pocket-ruby/pull/39))
data/Gemfile.lock CHANGED
@@ -1,37 +1,49 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pocket-ruby (0.1.0)
5
- faraday (>= 0.7)
4
+ pocket-ruby (0.5.0)
5
+ faraday (>= 1.0)
6
6
  faraday_middleware
7
7
  multi_json (~> 1.0, >= 1.0.3)
8
8
 
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
+ addressable (2.7.0)
13
+ public_suffix (>= 2.0.2, < 5.0)
12
14
  ast (2.4.2)
15
+ crack (0.4.5)
16
+ rexml
13
17
  docile (1.3.5)
14
- faraday (1.3.0)
18
+ faraday (1.4.1)
19
+ faraday-excon (~> 1.1)
15
20
  faraday-net_http (~> 1.0)
21
+ faraday-net_http_persistent (~> 1.1)
16
22
  multipart-post (>= 1.2, < 3)
17
- ruby2_keywords
23
+ ruby2_keywords (>= 0.0.4)
24
+ faraday-excon (1.1.0)
18
25
  faraday-net_http (1.0.1)
26
+ faraday-net_http_persistent (1.1.0)
19
27
  faraday_middleware (1.0.0)
20
28
  faraday (~> 1.0)
29
+ hashdiff (1.0.1)
21
30
  multi_json (1.15.0)
22
31
  multi_xml (0.6.0)
23
32
  multipart-post (2.1.1)
33
+ mustermann (1.1.1)
34
+ ruby2_keywords (~> 0.0.1)
24
35
  parallel (1.20.1)
25
36
  parser (3.0.0.0)
26
37
  ast (~> 2.4.1)
27
38
  power_assert (2.0.0)
28
- rack (1.6.13)
29
- rack-protection (1.5.5)
39
+ public_suffix (4.0.6)
40
+ rack (2.2.3)
41
+ rack-protection (2.1.0)
30
42
  rack
31
43
  rainbow (3.0.0)
32
44
  rake (13.0.3)
33
45
  regexp_parser (2.1.1)
34
- rexml (3.2.4)
46
+ rexml (3.2.5)
35
47
  rubocop (1.11.0)
36
48
  parallel (~> 1.10)
37
49
  parser (>= 3.0.0.0)
@@ -54,20 +66,27 @@ GEM
54
66
  simplecov_json_formatter (~> 0.1)
55
67
  simplecov-html (0.12.3)
56
68
  simplecov_json_formatter (0.1.2)
57
- sinatra (1.3.6)
58
- rack (~> 1.4)
59
- rack-protection (~> 1.3)
60
- tilt (~> 1.3, >= 1.3.3)
69
+ sinatra (2.1.0)
70
+ mustermann (~> 1.0)
71
+ rack (~> 2.2)
72
+ rack-protection (= 2.1.0)
73
+ tilt (~> 2.0)
61
74
  standard (1.0.4)
62
75
  rubocop (= 1.11.0)
63
76
  rubocop-performance (= 1.10.1)
64
77
  test-unit (3.4.0)
65
78
  power_assert
66
- tilt (1.4.1)
79
+ tilt (2.0.10)
67
80
  unicode-display_width (2.0.0)
81
+ webmock (3.12.1)
82
+ addressable (>= 2.3.6)
83
+ crack (>= 0.3.2)
84
+ hashdiff (>= 0.4.0, < 2.0.0)
85
+ yard (0.9.26)
68
86
 
69
87
  PLATFORMS
70
88
  x86_64-darwin-19
89
+ x86_64-darwin-20
71
90
  x86_64-linux
72
91
 
73
92
  DEPENDENCIES
@@ -75,9 +94,11 @@ DEPENDENCIES
75
94
  pocket-ruby!
76
95
  rake
77
96
  simplecov
78
- sinatra (~> 1.3.3)
97
+ sinatra (~> 2)
79
98
  standard
80
99
  test-unit
100
+ webmock
101
+ yard
81
102
 
82
103
  BUNDLED WITH
83
104
  2.2.8
data/README.md CHANGED
@@ -3,11 +3,11 @@ pocket-ruby
3
3
 
4
4
  [![Code Climate](https://codeclimate.com/github/turadg/pocket-ruby.png)](https://codeclimate.com/github/turadg/pocket-ruby) [![Gem Version](https://badge.fury.io/rb/pocket-ruby.png)](http://badge.fury.io/rb/pocket-ruby)
5
5
 
6
- Ruby API for v3 of the [Pocket API](http://getpocket.com/developer/docs/overview) (formerly Read It Later)
6
+ Ruby API for v3 of the [Pocket API](http://getpocket.com/developer/docs/overview) (formerly Read It Later)
7
7
 
8
8
  # Usage
9
9
 
10
- Just clone the repo here and refer to the demo-server.rb file for examples on how to interact with the Pocket API.
10
+ Just clone the repo here and refer to the demo-server.rb file for examples on how to interact with the Pocket API.
11
11
 
12
12
  ```sh
13
13
  git clone
@@ -16,6 +16,27 @@ Just clone the repo here and refer to the demo-server.rb file for examples on ho
16
16
  ruby demo-server.rb
17
17
  ```
18
18
 
19
+ *Note:* Changes to the `demo-server.rb` will require a restart to take effect (or you can use [rerun](https://github.com/alexch/rerun)).
20
+
19
21
  Pocket-Ruby can be installed via the gem, ```gem install pocket-ruby```
20
22
 
21
23
  Or via bundler, ```gem 'pocket-ruby'```
24
+
25
+ ## Pocket API Notes
26
+
27
+ Below are some aspects of the Pocket API that aren't covered in the official documentation, or that have been observed:
28
+
29
+ * For very long articles, the maximum reported `word_count` is 65535, even if the article is longer.
30
+ * If a `count` isn't specified, the `Retreive` call will return maximum of 5000 items.
31
+ * The API response may contain a number of undocumented fields, including:
32
+ * `amp_url`
33
+ * `domain_metadata`
34
+ * `is_index`
35
+ * `lang` ([ISO_639-1](https://en.wikipedia.org/wiki/ISO_639-1)?)
36
+ * `listen_duration_estimate`
37
+ * `sort_id`
38
+ * `time_to_read`
39
+ * `top_image_url`
40
+ * Every integer value is returned as a string, *except* for `time_to_read`, `listen_duration_estimate` and `sort_id`.
41
+ * The `time_to_read` is in minutes, but `listen_duration_estimate` is in seconds.
42
+ * If an article's `status` is `"2"` ('should be deleted') then most fields will not be present.
data/Rakefile CHANGED
@@ -10,22 +10,11 @@ Rake::TestTask.new(:test) do |t|
10
10
  t.test_files = FileList["test/**/*_test.rb"]
11
11
  end
12
12
 
13
- task default: [:test, :standard]
13
+ task default: [:test, :standard, :yard]
14
14
 
15
- namespace :doc do
15
+ begin
16
16
  require "yard"
17
+ YARD::Rake::YardocTask.new
17
18
  rescue LoadError
18
19
  # ignore
19
- else
20
- YARD::Rake::YardocTask.new do |task|
21
- task.files = ["HISTORY.mkd", "LICENSE.mkd", "lib/**/*.rb"]
22
- task.options = [
23
- "--protected",
24
- "--output-dir", "doc/yard",
25
- "--tag", "format:Supported formats",
26
- "--tag", "authenticated:Requires Authentication",
27
- "--tag", "rate_limited:Rate Limited",
28
- "--markup", "markdown"
29
- ]
30
- end
31
20
  end
@@ -16,11 +16,11 @@ module Faraday
16
16
  def on_complete(env)
17
17
  case env[:status]
18
18
  when 404
19
- raise Faraday::Error::ResourceNotFound, response_values(env)
20
- when 400...403
19
+ raise Faraday::ResourceNotFound, response_values(env)
20
+ when 400..403
21
21
  raise Pocket::Error, env[:response_headers]["X-Error"]
22
22
  when CLIENT_ERROR_STATUSES
23
- raise Faraday::Error::ClientError, response_values(env)
23
+ raise Faraday::ClientError, response_values(env)
24
24
  end
25
25
  end
26
26
 
data/lib/pocket-ruby.rb CHANGED
@@ -3,9 +3,14 @@ require File.expand_path("../pocket/configuration", __FILE__)
3
3
  require File.expand_path("../pocket/api", __FILE__)
4
4
  require File.expand_path("../pocket/client", __FILE__)
5
5
  require File.expand_path("../pocket/article", __FILE__)
6
+ require File.expand_path("../pocket/author", __FILE__)
7
+ require File.expand_path("../pocket/domain_metadata", __FILE__)
8
+ require File.expand_path("../pocket/image", __FILE__)
6
9
 
7
10
  module Pocket
8
11
  extend Configuration
12
+ extend Connection
13
+ extend OAuth
9
14
 
10
15
  # Alias for Pocket::Client.new
11
16
  #
@@ -13,15 +18,4 @@ module Pocket
13
18
  def self.client(options = {})
14
19
  Pocket::Client.new(options)
15
20
  end
16
-
17
- # Delegate to Pocket::Client
18
- def self.method_missing(method, *args, &block)
19
- return super unless client.respond_to?(method)
20
- client.send(method, *args, &block)
21
- end
22
-
23
- # Delegate to Pocket::Client
24
- def self.respond_to_missing?(method)
25
- client.respond_to?(method) || super
26
- end
27
21
  end
@@ -21,7 +21,7 @@ module Pocket
21
21
  end
22
22
 
23
23
  def resolved_url
24
- response.fetch("resolved_url")
24
+ response.fetch("resolved_url", nil)
25
25
  end
26
26
 
27
27
  def given_title
@@ -29,7 +29,7 @@ module Pocket
29
29
  end
30
30
 
31
31
  def resolved_title
32
- response.fetch("resolved_title")
32
+ response.fetch("resolved_title", nil)
33
33
  end
34
34
 
35
35
  def favorite?
@@ -41,10 +41,12 @@ module Pocket
41
41
  end
42
42
 
43
43
  def excerpt
44
+ return nil unless response["excerpt"]
44
45
  response.fetch("excerpt")
45
46
  end
46
47
 
47
48
  def article?
49
+ return false unless response["is_article"]
48
50
  Integer(response.fetch("is_article")) == 1
49
51
  end
50
52
 
@@ -65,6 +67,7 @@ module Pocket
65
67
  end
66
68
 
67
69
  def word_count
70
+ return nil unless response["word_count"]
68
71
  Integer(response.fetch("word_count"))
69
72
  end
70
73
 
@@ -88,6 +91,7 @@ module Pocket
88
91
 
89
92
  def time_read
90
93
  return nil unless response["time_read"]
94
+ return nil if response["time_read"] == "0"
91
95
  Time.at(Integer(response["time_read"])).utc
92
96
  end
93
97
 
@@ -97,6 +101,7 @@ module Pocket
97
101
 
98
102
  def time_favorited
99
103
  return nil unless response["time_favorited"]
104
+ return nil if response["time_favorited"] == "0"
100
105
  Time.at(Integer(response["time_favorited"])).utc
101
106
  end
102
107
 
@@ -107,5 +112,38 @@ module Pocket
107
112
  def read_url
108
113
  "https://getpocket.com/read/#{item_id}"
109
114
  end
115
+
116
+ def tags
117
+ Hash(response["tags"]).values.map { |tag| tag["tag"] }
118
+ end
119
+
120
+ def authors
121
+ Hash(response["authors"]).values.map { |value| Pocket::Author.new(value) }
122
+ end
123
+
124
+ def domain_metadata
125
+ return nil unless response["domain_metadata"]
126
+ Pocket::DomainMetadata.new(response["domain_metadata"])
127
+ end
128
+
129
+ def time_to_read
130
+ return nil unless response["time_to_read"]
131
+ return nil if response["time_to_read"] == 0
132
+ response.fetch("time_to_read")
133
+ end
134
+
135
+ def time_to_read_category
136
+ return nil if time_to_read.nil?
137
+
138
+ if time_to_read >= 21
139
+ "very_long"
140
+ elsif time_to_read >= 11
141
+ "long"
142
+ elsif time_to_read >= 6
143
+ "medium"
144
+ else
145
+ "quick"
146
+ end
147
+ end
110
148
  end
111
149
  end
@@ -0,0 +1,23 @@
1
+ module Pocket
2
+ class Author
3
+ def initialize(response)
4
+ @response = response
5
+ end
6
+
7
+ def id
8
+ Integer(response.fetch("author_id"))
9
+ end
10
+
11
+ def name
12
+ response.fetch("name")
13
+ end
14
+
15
+ def url
16
+ response.fetch("url")
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :response
22
+ end
23
+ end
data/lib/pocket/client.rb CHANGED
@@ -1,13 +1,33 @@
1
1
  module Pocket
2
2
  # Wrapper for the Pocket REST API
3
- #
4
- # @note All methods have been separated into modules and follow the same grouping used in {TODO:doc_URL the Pocket API Documentation}.
5
- # @see TODO:doc_url
6
3
  class Client < API
7
- Dir[File.expand_path("../client/*.rb", __FILE__)].sort.each { |f| require f }
4
+ # http://getpocket.com/developer/docs/v3/add
5
+ # required params: url, consumer_key, access_token
6
+ def add params
7
+ response = connection.post("/v3/add", params)
8
+ response.body
9
+ end
8
10
 
9
- include Pocket::Client::Add
10
- include Pocket::Client::Modify
11
- include Pocket::Client::Retrieve
11
+ # http://getpocket.com/developer/docs/v3/modify
12
+ # required params: actions, consumer_key, access_token
13
+ def modify actions
14
+ response = connection.post("/v3/send", {actions: actions})
15
+ response.body
16
+ end
17
+
18
+ # http://getpocket.com/developer/docs/v3/retrieve
19
+ # required params: consumer_key, access_token
20
+ def retrieve params = {}
21
+ response = connection.post("/v3/get", params)
22
+ response.body
23
+ end
24
+
25
+ def favorite(item_id)
26
+ modify([action: "favorite", item_id: item_id])
27
+ end
28
+
29
+ def unfavorite(item_id)
30
+ modify([action: "unfavorite", item_id: item_id])
31
+ end
12
32
  end
13
33
  end
@@ -0,0 +1,23 @@
1
+ module Pocket
2
+ class DomainMetadata
3
+ def initialize(response)
4
+ @response = response
5
+ end
6
+
7
+ def name
8
+ response.fetch("name")
9
+ end
10
+
11
+ def logo
12
+ response.fetch("logo")
13
+ end
14
+
15
+ def greyscale_logo
16
+ response.fetch("greyscale_logo")
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :response
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Pocket
2
+ class Image
3
+ attr_reader :response
4
+
5
+ def initialize(response)
6
+ @response = response
7
+ end
8
+
9
+ def src
10
+ response.fetch("src")
11
+ end
12
+
13
+ def caption
14
+ response.fetch("caption")
15
+ end
16
+
17
+ def image_id
18
+ Integer(response.fetch("image_id"))
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Pocket
2
- VERSION = "0.1.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/pocket-ruby.gemspec CHANGED
@@ -1,13 +1,15 @@
1
1
  require File.expand_path("../lib/pocket/version", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
- s.add_development_dependency("sinatra", "~> 1.3.3")
4
+ s.add_development_dependency("sinatra", "~> 2")
5
5
  s.add_development_dependency("multi_xml")
6
6
  s.add_development_dependency("rake")
7
7
  s.add_development_dependency("standard")
8
8
  s.add_development_dependency("test-unit")
9
9
  s.add_development_dependency("simplecov")
10
- s.add_runtime_dependency("faraday", [">= 0.7"])
10
+ s.add_development_dependency("webmock")
11
+ s.add_development_dependency("yard")
12
+ s.add_runtime_dependency("faraday", ">= 1.0")
11
13
  s.add_runtime_dependency("faraday_middleware")
12
14
  s.add_runtime_dependency("multi_json", ">= 1.0.3", "~> 1.0")
13
15
  s.authors = ["Turadg Aleahmad", "Jason Ng PT", "Andy Waite"]
@@ -17,6 +17,7 @@
17
17
  "time_updated": "1617412993",
18
18
  "time_read": "1617412994",
19
19
  "time_favorited": "1617412995",
20
+ "time_to_read": 14,
20
21
  "images": {
21
22
  "1": {
22
23
  "item_id": "229279689",
@@ -38,5 +39,28 @@
38
39
  "type": "1",
39
40
  "vid": "Er34PbFkVGk"
40
41
  }
42
+ },
43
+ "tags":{
44
+ "bookmark":{
45
+ "item_id":"229279689",
46
+ "tag":"my-tag-1"
47
+ },
48
+ "gtd":{
49
+ "item_id":"229279689",
50
+ "tag":"my-tag-2"
51
+ }
52
+ },
53
+ "authors":{
54
+ "62344201":{
55
+ "item_id":"229279689",
56
+ "author_id":"62344201",
57
+ "name":"Stephen King",
58
+ "url":"https://example.com/author"
59
+ }
60
+ },
61
+ "domain_metadata":{
62
+ "name": "The Verge",
63
+ "logo": "https://logo.clearbit.com/theverge.com?size=800",
64
+ "greyscale_logo": "https://logo.clearbit.com/theverge.com?size=800&greyscale=true"
41
65
  }
42
66
  }
@@ -1,7 +1,11 @@
1
1
  require "test_helper"
2
2
 
3
3
  module Pocket
4
- class VersionTest < Test::Unit::TestCase
4
+ class ArticleTest < Test::Unit::TestCase
5
+ setup do
6
+ @article = Pocket::Article.new(parsed_response)
7
+ end
8
+
5
9
  test "from_json" do
6
10
  json_string = File.read("test/fixtures/retreive.json")
7
11
  article = Pocket::Article.from_json(json_string)
@@ -9,123 +13,214 @@ module Pocket
9
13
  end
10
14
 
11
15
  test "item_id" do
12
- assert_equal 229279689, article.item_id
16
+ assert_equal 229279689, @article.item_id
13
17
  end
14
18
 
15
19
  test "given_url" do
16
- assert_equal "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview?given", article.given_url
20
+ assert_equal "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview?given", @article.given_url
17
21
  end
18
22
 
19
23
  test "resolved_url" do
20
- assert_equal "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview?resolved", article.resolved_url
24
+ assert_equal "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview?resolved", @article.resolved_url
25
+ end
26
+
27
+ test "resolved_url is nil is field not present" do
28
+ parsed_response.delete("resolved_url")
29
+ assert_nil @article.resolved_url
21
30
  end
22
31
 
23
32
  test "given_title" do
24
- assert_equal "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", article.given_title
33
+ assert_equal "The Massive Ryder Cup Preview - The Triangle Blog - Grantland", @article.given_title
25
34
  end
26
35
 
27
36
  test "resolved_title" do
28
- assert_equal "The Massive Ryder Cup Preview", article.resolved_title
37
+ assert_equal "The Massive Ryder Cup Preview", @article.resolved_title
38
+ end
39
+
40
+ test "resolved_title is nil is field not present" do
41
+ parsed_response.delete("resolved_title")
42
+ assert_nil @article.resolved_title
29
43
  end
30
44
 
31
45
  test "favorite? is false is field is '0'" do
32
- assert_equal false, article.favorite?
46
+ assert_equal false, @article.favorite?
33
47
  end
34
48
 
35
49
  test "status" do
36
- assert_equal 0, article.status
50
+ assert_equal 0, @article.status
37
51
  end
38
52
 
39
53
  test "excerpt" do
40
- assert_include article.excerpt, "list of things"
54
+ assert_include @article.excerpt, "list of things"
55
+ end
56
+
57
+ test "excerpt is nil if field not present" do
58
+ parsed_response.delete("excerpt")
59
+ assert_nil @article.excerpt
41
60
  end
42
61
 
43
62
  test "article?" do
44
- assert article.article?
63
+ assert @article.article?
64
+ end
65
+
66
+ test "article? returns false if `is_article` field not present" do
67
+ parsed_response.delete("is_article")
68
+ refute @article.article?
45
69
  end
46
70
 
47
71
  test "has_image?" do
48
- assert article.has_image?
72
+ assert @article.has_image?
49
73
  end
50
74
 
51
75
  test "image?" do
52
- refute article.image?
76
+ refute @article.image?
53
77
  end
54
78
 
55
79
  test "has_video?" do
56
- assert article.has_video?
80
+ assert @article.has_video?
57
81
  end
58
82
 
59
83
  test "video?" do
60
- refute article.video?
84
+ refute @article.video?
61
85
  end
62
86
 
63
87
  test "word_count" do
64
- assert_equal 3197, article.word_count
88
+ assert_equal 3197, @article.word_count
89
+ end
90
+
91
+ test "word_count is nil is field not present" do
92
+ parsed_response.delete("word_count")
93
+ assert_nil @article.word_count
65
94
  end
66
95
 
67
96
  test "resolved_id" do
68
- assert_equal 229279689, article.resolved_id
97
+ assert_equal 229279689, @article.resolved_id
69
98
  end
70
99
 
71
100
  test "thumbnail" do
72
- assert_equal "https://example.com/image.png", article.thumbnail
101
+ assert_equal "https://example.com/image.png", @article.thumbnail
73
102
  end
74
103
 
75
104
  test "time_added" do
76
- assert_equal Time.utc(2021, 4, 3, 1, 23, 12), article.time_added
105
+ assert_equal Time.utc(2021, 4, 3, 1, 23, 12), @article.time_added
77
106
  end
78
107
 
79
108
  test "time_added is nil if field not present" do
80
109
  parsed_response.delete("time_added")
81
- assert_nil article.time_added
110
+ assert_nil @article.time_added
82
111
  end
83
112
 
84
113
  test "time_updated" do
85
- assert_equal Time.utc(2021, 4, 3, 1, 23, 13), article.time_updated
114
+ assert_equal Time.utc(2021, 4, 3, 1, 23, 13), @article.time_updated
86
115
  end
87
116
 
88
117
  test "time_updated is nil if field not present" do
89
118
  parsed_response.delete("time_updated")
90
- assert_nil article.time_updated
119
+ assert_nil @article.time_updated
91
120
  end
92
121
 
93
122
  test "time_read" do
94
- assert_equal Time.utc(2021, 4, 3, 1, 23, 14), article.time_read
123
+ assert_equal Time.utc(2021, 4, 3, 1, 23, 14), @article.time_read
95
124
  end
96
125
 
97
126
  test "time_read is nil if field is not present" do
98
127
  parsed_response.delete("time_read")
99
- assert_nil article.time_read
128
+ assert_nil @article.time_read
129
+ end
130
+
131
+ test "time_read is nil if field is zero" do
132
+ parsed_response["time_read"] = "0"
133
+ assert_nil @article.time_read
100
134
  end
101
135
 
102
136
  test "favorited?" do
103
- assert article.favorited?
137
+ assert @article.favorited?
104
138
  end
105
139
 
106
140
  test "time_favorited" do
107
- assert_equal Time.utc(2021, 4, 3, 1, 23, 15), article.time_favorited
141
+ assert_equal Time.utc(2021, 4, 3, 1, 23, 15), @article.time_favorited
108
142
  end
109
143
 
110
144
  test "time_favorited is nil if field not present" do
111
145
  parsed_response.delete("time_favorited")
112
- assert_nil article.time_favorited
146
+ assert_nil @article.time_favorited
147
+ end
148
+
149
+ test "time_favorited is nil if field is zero" do
150
+ parsed_response["time_favorited"] = "0"
151
+ assert_nil @article.time_favorited
113
152
  end
114
153
 
115
154
  test "read?" do
116
- assert article.read?
155
+ assert @article.read?
117
156
  end
118
157
 
119
158
  test "read_url" do
120
- assert_equal "https://getpocket.com/read/229279689", article.read_url
159
+ assert_equal "https://getpocket.com/read/229279689", @article.read_url
121
160
  end
122
161
 
123
- private
162
+ test "tags" do
163
+ assert_equal ["my-tag-1", "my-tag-2"], @article.tags
164
+ end
165
+
166
+ test "tags returns an empty array if there are no tags" do
167
+ parsed_response.delete("tags")
168
+ assert_equal [], @article.tags
169
+ end
170
+
171
+ test "authors" do
172
+ result = @article.authors
173
+ assert_equal 1, result.size
174
+ assert_equal "Stephen King", result.first.name
175
+ assert_equal 62344201, result.first.id
176
+ assert_equal "https://example.com/author", result.first.url
177
+ end
178
+
179
+ test "authors returns an empty array if there are no tags" do
180
+ parsed_response.delete("authors")
181
+ assert_equal [], @article.authors
182
+ end
183
+
184
+ test "time_to_read" do
185
+ assert_equal 14, @article.time_to_read
186
+ end
187
+
188
+ test "time_to_read returns nil if field not present" do
189
+ parsed_response.delete("time_to_read")
190
+ assert_nil @article.time_to_read
191
+ end
192
+
193
+ test "time_to_read returns nil if value is 0" do
194
+ parsed_response["time_to_read"] = 0
195
+ assert_nil @article.time_to_read
196
+ end
197
+
198
+ test "time_to_read_category" do
199
+ parsed_response.delete("time_to_read")
200
+ assert_nil @article.time_to_read_category
201
+
202
+ parsed_response["time_to_read"] = 0
203
+ assert_nil @article.time_to_read_category
204
+
205
+ parsed_response["time_to_read"] = 25
206
+ assert_equal "very_long", @article.time_to_read_category
207
+
208
+ parsed_response["time_to_read"] = 15
209
+ assert_equal "long", @article.time_to_read_category
124
210
 
125
- def article
126
- @article ||= Pocket::Article.new(parsed_response)
211
+ parsed_response["time_to_read"] = 8
212
+ assert_equal "medium", @article.time_to_read_category
213
+
214
+ parsed_response["time_to_read"] = 3
215
+ assert_equal "quick", @article.time_to_read_category
216
+ end
217
+
218
+ test "domain_metadata" do
219
+ assert_equal "The Verge", @article.domain_metadata.name
127
220
  end
128
221
 
222
+ private
223
+
129
224
  def parsed_response
130
225
  @parsed_response ||= JSON.parse(File.read("test/fixtures/retreive.json"))
131
226
  end
@@ -0,0 +1,59 @@
1
+ require "test_helper"
2
+ require "webmock/test_unit"
3
+
4
+ class ClientTest < Test::Unit::TestCase
5
+ test "retrieve" do
6
+ stub_request(:post, "https://getpocket.com/v3/get")
7
+ .with(
8
+ body: "{\"detailType\":\"complete\",\"count\":1,\"consumer_key\":null,\"access_token\":\"access_token\"}",
9
+ headers: {
10
+ "Content-Type" => "application/json",
11
+ "User-Agent" => "Pocket Ruby Gem #{Pocket::VERSION}"
12
+ }
13
+ )
14
+ .to_return(status: 200, body: "body response", headers: {})
15
+ client = Pocket.client(access_token: "access_token")
16
+
17
+ result = client.retrieve(detailType: :complete, count: 1)
18
+
19
+ assert_equal "body response", result
20
+ end
21
+
22
+ test "favorite" do
23
+ success_response = '{"action_results":[true],"status":1}'
24
+
25
+ stub_request(:post, "https://getpocket.com/v3/send")
26
+ .with(
27
+ body: "{\"actions\":[{\"action\":\"favorite\",\"item_id\":\"123456\"}],\"consumer_key\":null,\"access_token\":\"access_token\"}",
28
+ headers: {
29
+ "Content-Type" => "application/json",
30
+ "User-Agent" => "Pocket Ruby Gem #{Pocket::VERSION}"
31
+ }
32
+ )
33
+ .to_return(status: 200, body: success_response, headers: {})
34
+ client = Pocket.client(access_token: "access_token")
35
+
36
+ result = client.favorite("123456")
37
+
38
+ assert_equal success_response, result
39
+ end
40
+
41
+ test "unfavorite" do
42
+ success_response = '{"action_results":[true],"status":1}'
43
+
44
+ stub_request(:post, "https://getpocket.com/v3/send")
45
+ .with(
46
+ body: "{\"actions\":[{\"action\":\"unfavorite\",\"item_id\":\"123456\"}],\"consumer_key\":null,\"access_token\":\"access_token\"}",
47
+ headers: {
48
+ "Content-Type" => "application/json",
49
+ "User-Agent" => "Pocket Ruby Gem #{Pocket::VERSION}"
50
+ }
51
+ )
52
+ .to_return(status: 200, body: success_response, headers: {})
53
+ client = Pocket.client(access_token: "access_token")
54
+
55
+ result = client.unfavorite("123456")
56
+
57
+ assert_equal success_response, result
58
+ end
59
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pocket-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Turadg Aleahmad
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-04-03 00:00:00.000000000 Z
13
+ date: 2021-05-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
@@ -18,14 +18,14 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: 1.3.3
21
+ version: '2'
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: 1.3.3
28
+ version: '2'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: multi_xml
31
31
  requirement: !ruby/object:Gem::Requirement
@@ -96,20 +96,48 @@ dependencies:
96
96
  - - ">="
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: webmock
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: yard
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
99
127
  - !ruby/object:Gem::Dependency
100
128
  name: faraday
101
129
  requirement: !ruby/object:Gem::Requirement
102
130
  requirements:
103
131
  - - ">="
104
132
  - !ruby/object:Gem::Version
105
- version: '0.7'
133
+ version: '1.0'
106
134
  type: :runtime
107
135
  prerelease: false
108
136
  version_requirements: !ruby/object:Gem::Requirement
109
137
  requirements:
110
138
  - - ">="
111
139
  - !ruby/object:Gem::Version
112
- version: '0.7'
140
+ version: '1.0'
113
141
  - !ruby/object:Gem::Dependency
114
142
  name: faraday_middleware
115
143
  requirement: !ruby/object:Gem::Requirement
@@ -128,22 +156,22 @@ dependencies:
128
156
  name: multi_json
129
157
  requirement: !ruby/object:Gem::Requirement
130
158
  requirements:
131
- - - "~>"
132
- - !ruby/object:Gem::Version
133
- version: '1.0'
134
159
  - - ">="
135
160
  - !ruby/object:Gem::Version
136
161
  version: 1.0.3
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '1.0'
137
165
  type: :runtime
138
166
  prerelease: false
139
167
  version_requirements: !ruby/object:Gem::Requirement
140
168
  requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '1.0'
144
169
  - - ">="
145
170
  - !ruby/object:Gem::Version
146
171
  version: 1.0.3
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '1.0'
147
175
  description: A Ruby wrapper for the Pocket API v3 (Add, Modify and Retrieve)
148
176
  email:
149
177
  - turadg@aleahmad.net
@@ -168,18 +196,19 @@ files:
168
196
  - lib/pocket-ruby.rb
169
197
  - lib/pocket/api.rb
170
198
  - lib/pocket/article.rb
199
+ - lib/pocket/author.rb
171
200
  - lib/pocket/client.rb
172
- - lib/pocket/client/add.rb
173
- - lib/pocket/client/modify.rb
174
- - lib/pocket/client/retrieve.rb
175
201
  - lib/pocket/configuration.rb
176
202
  - lib/pocket/connection.rb
203
+ - lib/pocket/domain_metadata.rb
177
204
  - lib/pocket/error.rb
205
+ - lib/pocket/image.rb
178
206
  - lib/pocket/oauth.rb
179
207
  - lib/pocket/version.rb
180
208
  - pocket-ruby.gemspec
181
209
  - test/fixtures/retreive.json
182
210
  - test/pocket/article_test.rb
211
+ - test/pocket/client_test.rb
183
212
  - test/pocket/version_test.rb
184
213
  - test/test_helper.rb
185
214
  homepage: https://github.com/turadg/pocket-ruby
@@ -200,12 +229,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
229
  - !ruby/object:Gem::Version
201
230
  version: 1.3.6
202
231
  requirements: []
203
- rubygems_version: 3.0.3
232
+ rubygems_version: 3.1.6
204
233
  signing_key:
205
234
  specification_version: 4
206
235
  summary: Ruby wrapper for the Pocket API v3
207
236
  test_files:
208
237
  - test/fixtures/retreive.json
209
238
  - test/pocket/article_test.rb
239
+ - test/pocket/client_test.rb
210
240
  - test/pocket/version_test.rb
211
241
  - test/test_helper.rb
@@ -1,12 +0,0 @@
1
- module Pocket
2
- class Client
3
- # http://getpocket.com/developer/docs/v3/add
4
- module Add
5
- # required params: url, consumer_key, access_token
6
- def add params
7
- response = connection.post("/v3/add", params)
8
- response.body
9
- end
10
- end
11
- end
12
- end
@@ -1,12 +0,0 @@
1
- module Pocket
2
- class Client
3
- # http://getpocket.com/developer/docs/v3/modify
4
- module Modify
5
- # required params: actions, consumer_key, access_token
6
- def modify actions
7
- response = connection.post("/v3/send", {actions: actions})
8
- response.body
9
- end
10
- end
11
- end
12
- end
@@ -1,12 +0,0 @@
1
- module Pocket
2
- class Client
3
- # http://getpocket.com/developer/docs/v3/retrieve
4
- module Retrieve
5
- # required params: consumer_key, access_token
6
- def retrieve params = {}
7
- response = connection.post("/v3/get", params)
8
- response.body
9
- end
10
- end
11
- end
12
- end