disqus_api 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +4 -0
- data/Gemfile +7 -0
- data/README.md +113 -0
- data/Rakefile +6 -0
- data/disqus_api.gemspec +26 -0
- data/lib/apis/3.0.yml +79 -0
- data/lib/disqus_api.rb +46 -0
- data/lib/disqus_api/api.rb +80 -0
- data/lib/disqus_api/namespace.rb +44 -0
- data/lib/disqus_api/request.rb +50 -0
- data/lib/disqus_api/response.rb +55 -0
- data/spec/config/disqus.yml.example +3 -0
- data/spec/disqus_api/api_spec.rb +68 -0
- data/spec/disqus_api/namespace_spec.rb +53 -0
- data/spec/disqus_api/request_spec.rb +45 -0
- data/spec/disqus_api/response_spec.rb +82 -0
- data/spec/disqus_api_spec.rb +24 -0
- data/spec/spec_helper.rb +42 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 133d31109b75e6a7a8a3948ae883667b419c9d41
|
4
|
+
data.tar.gz: 2316f34bd676de9379991a8f5f260db9fe17307b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7c188e126d73f1f8b4a4b2f7b07fbd872ce6552d0f26b55d5ae2349b86906c54bbb7dfd06b3737380a7b695e862a8f7dd416b6dcba7db499312ff3dabc57ab0
|
7
|
+
data.tar.gz: 4b45529a2925f8cfd95e82b8e760c5d03ec4036995af60d06aaf999eb6613fe2825077e40301a6b7861fb9de31972d2de7c02194fd9bd1dabf2e301bea83dcd7
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# Disqus API for Ruby
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/disqus_api.png)](http://badge.fury.io/rb/disqus_api)
|
3
|
+
[![Build Status](https://travis-ci.org/einzige/disqus_api.png?branch=master)](https://travis-ci.org/einzige/disqus_api)
|
4
|
+
|
5
|
+
Provides clean Disqus REST API for your Ruby app. Currently supported API version: 3.0.
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install disqus_api
|
11
|
+
```
|
12
|
+
|
13
|
+
## Configure
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
DisqusApi.config = {api_secret: 'secret key',
|
17
|
+
api_key: 'public key',
|
18
|
+
access_token: 'token from app settings'}
|
19
|
+
```
|
20
|
+
|
21
|
+
## Enjoy
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
DisqusApi.v3.users.details
|
25
|
+
# => {"code" => 0, "response" => {
|
26
|
+
# "isFollowing"=>false,
|
27
|
+
# "isFollowedBy"=>false, "connections"=>{}, "isPrimary"=>true, "id"=>"84792962"
|
28
|
+
# ...
|
29
|
+
# }
|
30
|
+
```
|
31
|
+
|
32
|
+
Use response to get response body
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
DisqusApi.v3.users.details.response
|
36
|
+
# => {
|
37
|
+
# "isFollowing"=>false,
|
38
|
+
# "isFollowedBy"=>false, "connections"=>{}, "isPrimary"=>true, "id"=>"84792962"
|
39
|
+
# ...
|
40
|
+
# }
|
41
|
+
```
|
42
|
+
|
43
|
+
Alias `#body` for response body
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
DisqusApi.v3.users.details.body
|
47
|
+
# => {
|
48
|
+
# "isFollowing"=>false,
|
49
|
+
# "isFollowedBy"=>false, "connections"=>{}, "isPrimary"=>true, "id"=>"84792962"
|
50
|
+
# # ...
|
51
|
+
# }
|
52
|
+
```
|
53
|
+
|
54
|
+
Setting additional parameters to a query
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
DisqusApi.v3.posts.list(forum: 'my_form')
|
58
|
+
```
|
59
|
+
|
60
|
+
### Fetching full collections
|
61
|
+
|
62
|
+
By default Disqus API limits returning collections by 25 records per requests. The maximum limit you can set is 100.
|
63
|
+
In order to fetch **all records** from a collection use `#all` method:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
DisqusApi.v3.posts.list(forum: 'my_form').all
|
67
|
+
```
|
68
|
+
|
69
|
+
### Pagination
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
first_page = DisqusApi.v3.posts.list(forum: 'my_forum', limit: 10)
|
73
|
+
|
74
|
+
second_page = first_page.next
|
75
|
+
third_page = second_page.next
|
76
|
+
# ...
|
77
|
+
```
|
78
|
+
|
79
|
+
### Performing custom requests
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
DisqusApi.v3.get('posts/list.json', forum: 'my_forum')
|
83
|
+
DisqusApi.v3.post('posts/create.json', forum: 'my_forum')
|
84
|
+
```
|
85
|
+
|
86
|
+
### Using in test environment
|
87
|
+
|
88
|
+
Disqus API uses Faraday gem, refer to its documentation for details.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
before :all do
|
92
|
+
# You can move this block in RSpec initializer or `spec_helper.rb`
|
93
|
+
|
94
|
+
stubbed_request = Faraday::Adapter::Test::Stubs.new do |stub|
|
95
|
+
stub.get('/api/3.0/users/details.json') { [200, {}, {code: 0, body: {response: :whatever}}.to_json] }
|
96
|
+
end
|
97
|
+
DisqusApi.adapter = [:test, stubbed_requests]
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'performs requests' do
|
101
|
+
DisqusApi.v3.users.details['code'].should == 0
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
## Contributing to disqus_api
|
106
|
+
|
107
|
+
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
108
|
+
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
109
|
+
- Fork the project
|
110
|
+
- Start a feature/bugfix branch
|
111
|
+
- Commit and push until you are happy with your contribution
|
112
|
+
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
113
|
+
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
data/Rakefile
ADDED
data/disqus_api.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{disqus_api}
|
5
|
+
s.version = "0.0.2"
|
6
|
+
|
7
|
+
s.date = %q{2013-12-09}
|
8
|
+
s.authors = ["Sergei Zinin"]
|
9
|
+
s.email = %q{szinin@gmail.com}
|
10
|
+
s.homepage = %q{http://github.com/einzige/disqus_api}
|
11
|
+
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.extra_rdoc_files = ["README.md"]
|
17
|
+
|
18
|
+
s.description = %q{Provides clean Disqus API for your Ruby app with a nice interface.}
|
19
|
+
s.summary = %q{Disqus API for Ruby}
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'activesupport', ">= 3.0.0"
|
22
|
+
s.add_runtime_dependency 'faraday', ">= 0.8"
|
23
|
+
s.add_runtime_dependency 'faraday_middleware', ">= 0.9"
|
24
|
+
s.add_development_dependency 'bundler'
|
25
|
+
end
|
26
|
+
|
data/lib/apis/3.0.yml
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
exports:
|
2
|
+
exportForum: post
|
3
|
+
users:
|
4
|
+
listActiveForums: get
|
5
|
+
listActiveThreads: get
|
6
|
+
listFollowing: get
|
7
|
+
listForums: get
|
8
|
+
unfollow: post
|
9
|
+
listPosts: get
|
10
|
+
details: get
|
11
|
+
listFollowers: get
|
12
|
+
follow: post
|
13
|
+
listActivity: get
|
14
|
+
listMostActiveForums: get
|
15
|
+
imports:
|
16
|
+
list: get
|
17
|
+
details: get
|
18
|
+
posts:
|
19
|
+
restore: post
|
20
|
+
spam: post
|
21
|
+
unhighlight: post
|
22
|
+
listPopular: get
|
23
|
+
create: post
|
24
|
+
list: get
|
25
|
+
remove: post
|
26
|
+
getContext: get
|
27
|
+
vote: post
|
28
|
+
details: get
|
29
|
+
report: post
|
30
|
+
highlight: post
|
31
|
+
approve: post
|
32
|
+
blacklists:
|
33
|
+
add: post
|
34
|
+
list: get
|
35
|
+
remove: post
|
36
|
+
reports:
|
37
|
+
domains: get
|
38
|
+
ips: get
|
39
|
+
threads: get
|
40
|
+
users: get
|
41
|
+
whitelists:
|
42
|
+
add: post
|
43
|
+
list: get
|
44
|
+
remove: post
|
45
|
+
applications:
|
46
|
+
listUsage: get
|
47
|
+
trends:
|
48
|
+
listThreads: get
|
49
|
+
threads:
|
50
|
+
restore: post
|
51
|
+
vote: post
|
52
|
+
open: post
|
53
|
+
create: post
|
54
|
+
list: get
|
55
|
+
listMostLiked: get
|
56
|
+
listHot: get
|
57
|
+
update: post
|
58
|
+
listSimilar: get
|
59
|
+
details: get
|
60
|
+
listByDate: get
|
61
|
+
listPosts: get
|
62
|
+
close: post
|
63
|
+
remove: post
|
64
|
+
listPopular: get
|
65
|
+
forums:
|
66
|
+
create: post
|
67
|
+
listCategories: get
|
68
|
+
listThreads: get
|
69
|
+
listUsers: get
|
70
|
+
listMostLikedUsers: get
|
71
|
+
details: get
|
72
|
+
listPosts: get
|
73
|
+
listModerators: get
|
74
|
+
categories:
|
75
|
+
listPosts: get
|
76
|
+
listThreads: get
|
77
|
+
create: post
|
78
|
+
list: get
|
79
|
+
details: get
|
data/lib/disqus_api.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
require 'active_support/core_ext/object/try'
|
3
|
+
require 'yaml'
|
4
|
+
require 'json'
|
5
|
+
require 'faraday'
|
6
|
+
require 'faraday_middleware'
|
7
|
+
|
8
|
+
require 'disqus_api/api'
|
9
|
+
require 'disqus_api/namespace'
|
10
|
+
require 'disqus_api/request'
|
11
|
+
require 'disqus_api/response'
|
12
|
+
|
13
|
+
module DisqusApi
|
14
|
+
|
15
|
+
def self.adapter
|
16
|
+
@adapter || Faraday.default_adapter
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.adapter=(value)
|
20
|
+
@adapter = value
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [ActiveSupport::HashWithIndifferentAccess]
|
24
|
+
def self.config
|
25
|
+
@config || raise("No configuration specified for Disqus")
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param [Hash] config
|
29
|
+
# @option config [String] :api_secret
|
30
|
+
# @option config [String] :api_key
|
31
|
+
# @option config [String] :access_token
|
32
|
+
def self.config=(config)
|
33
|
+
@config = ActiveSupport::HashWithIndifferentAccess.new(config)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [String] version
|
37
|
+
# @return [Api]
|
38
|
+
def self.init(version)
|
39
|
+
Api.new(version, YAML.load_file(File.join(File.dirname(__FILE__), "apis/#{version}.yml")))
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Api]
|
43
|
+
def self.v3
|
44
|
+
@v3 ||= init('3.0')
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module DisqusApi
|
2
|
+
class InvalidApiRequestError < Exception
|
3
|
+
def initialize(response, message = response.inspect)
|
4
|
+
super(response)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Api
|
9
|
+
DEFAULT_VERSION = '3.0'
|
10
|
+
attr_reader :version, :endpoint, :specifications, :namespaces
|
11
|
+
|
12
|
+
# @param [String] version
|
13
|
+
# @param [Hash] specifications API specifications
|
14
|
+
def initialize(version = DEFAULT_VERSION, specifications = {})
|
15
|
+
@version = version
|
16
|
+
@endpoint = "https://disqus.com/api/#@version/".freeze
|
17
|
+
@specifications = ActiveSupport::HashWithIndifferentAccess.new(specifications)
|
18
|
+
|
19
|
+
@namespaces = ActiveSupport::HashWithIndifferentAccess.new
|
20
|
+
@specifications.keys.each do |namespace|
|
21
|
+
@namespaces[namespace] = Namespace.new(self, namespace)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Hash]
|
26
|
+
def connection_options
|
27
|
+
{
|
28
|
+
headers: { 'Accept' => "application/json", 'User-Agent' => "DisqusAgent"},
|
29
|
+
ssl: { verify: false },
|
30
|
+
url: @endpoint
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Faraday::Connection]
|
35
|
+
def connection
|
36
|
+
Faraday.new(connection_options) do |builder|
|
37
|
+
builder.use Faraday::Request::Multipart
|
38
|
+
builder.use Faraday::Request::UrlEncoded
|
39
|
+
builder.use Faraday::Response::ParseJson
|
40
|
+
|
41
|
+
builder.params.merge!(DisqusApi.config)
|
42
|
+
|
43
|
+
builder.adapter(*DisqusApi.adapter)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Performs custom GET request
|
48
|
+
# @param [String] path
|
49
|
+
# @param [Hash] arguments
|
50
|
+
def get(path, arguments = {})
|
51
|
+
perform_request { connection.get(path, arguments).body }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Performs custom POST request
|
55
|
+
# @param [String] path
|
56
|
+
# @param [Hash] arguments
|
57
|
+
def post(path, arguments = {})
|
58
|
+
perform_request { connection.post(path, arguments).body }
|
59
|
+
end
|
60
|
+
|
61
|
+
# DisqusApi.v3.---->>[users]<<-----.details
|
62
|
+
#
|
63
|
+
# Forwards calls to API declared in YAML
|
64
|
+
def method_missing(method_name, *args)
|
65
|
+
namespaces[method_name] or raise(ArgumentError, "No such namespace #{method_name}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def respond_to?(method_name, include_private = false)
|
69
|
+
namespaces[method_name] || super
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def perform_request
|
75
|
+
yield.tap do |response|
|
76
|
+
raise InvalidApiRequestError.new(response) if response['code'] != 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module DisqusApi
|
2
|
+
class Namespace
|
3
|
+
attr_reader :api, :name, :specification
|
4
|
+
|
5
|
+
# @param [Api] api
|
6
|
+
# @param [String, Symbol] name
|
7
|
+
def initialize(api, name)
|
8
|
+
@api = api
|
9
|
+
@name = name
|
10
|
+
@specification = @api.specifications[@name]
|
11
|
+
@specification or raise(ArgumentError, "No such namespace <#@name>")
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [String, Symbol] action
|
15
|
+
# @param [Hash] arguments Action params
|
16
|
+
# @return [Request]
|
17
|
+
def build_action_request(action, arguments = {})
|
18
|
+
Request.new(api, name, action, arguments)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param [String, Symbol, Hash] action
|
22
|
+
# @param [Hash] arguments
|
23
|
+
# @return [Hash] response
|
24
|
+
def request_action(action, arguments = {})
|
25
|
+
build_action_request(action, arguments).response
|
26
|
+
end
|
27
|
+
alias_method :perform_action, :request_action
|
28
|
+
|
29
|
+
# DisqusApi.v3.users.---->>[details]<<-----
|
30
|
+
#
|
31
|
+
# Forwards all API calls under a specific namespace
|
32
|
+
def method_missing(method_name, *args)
|
33
|
+
if specification.has_key?(method_name.to_s)
|
34
|
+
request_action(method_name, *args)
|
35
|
+
else
|
36
|
+
raise NoMethodError, "No action #{method_name} registered for #@name namespace"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def respond_to?(method_name, include_private = false)
|
41
|
+
specification[method_name.to_s] || super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module DisqusApi
|
2
|
+
class Request
|
3
|
+
attr_reader :api, :path, :namespace, :action, :arguments, :type
|
4
|
+
|
5
|
+
# @param [Class<DisqusApi::Api>] api
|
6
|
+
# @param [String] namespace
|
7
|
+
# @param [String] action
|
8
|
+
# @param [Hash] arguments Request parameters
|
9
|
+
def initialize(api, namespace, action, arguments = {})
|
10
|
+
@api = api
|
11
|
+
@namespace = namespace.to_s
|
12
|
+
@action = action.to_s
|
13
|
+
@path = "#@namespace/#@action.json"
|
14
|
+
|
15
|
+
# Request type GET or POST
|
16
|
+
namespace_specification = @api.specifications[@namespace] or raise(ArgumentError, "No such namespace: #@namespace")
|
17
|
+
@type = namespace_specification[@action].try(:to_sym) or raise(ArgumentError, "No such API path: #@path")
|
18
|
+
|
19
|
+
# Set request parameters
|
20
|
+
@arguments = arguments
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns Disqus API response proxy
|
24
|
+
# @param [Symbol] request_type
|
25
|
+
# @param [Hash] arguments
|
26
|
+
# @return [String]
|
27
|
+
def response(arguments = {})
|
28
|
+
Response.new(self, arguments)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns plain JSON response received from Disqus
|
32
|
+
# @param [Hash] arguments
|
33
|
+
# @return [String]
|
34
|
+
def perform(arguments = {})
|
35
|
+
case type.to_sym
|
36
|
+
when :post, :get
|
37
|
+
api.public_send(type, path, @arguments.merge(arguments))
|
38
|
+
else
|
39
|
+
raise ArgumentError, "Unregistered request type #{request_type}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @see #initialize
|
44
|
+
# @param [String, Symbol] request_type
|
45
|
+
# @return [Hash]
|
46
|
+
def self.perform(*args)
|
47
|
+
self.new(*args).perform
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DisqusApi
|
2
|
+
class Response < ActiveSupport::HashWithIndifferentAccess
|
3
|
+
attr_reader :request, :arguments, :content
|
4
|
+
|
5
|
+
# @param [Request] request
|
6
|
+
# @param [Hash] arguments
|
7
|
+
def initialize(request, arguments = {})
|
8
|
+
@request = request
|
9
|
+
@arguments = arguments
|
10
|
+
@content = request.perform(@arguments)
|
11
|
+
|
12
|
+
super(@content)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Fetches all records going through pagination
|
16
|
+
# @return [Array<Hash>]
|
17
|
+
def all
|
18
|
+
[].tap do |result|
|
19
|
+
next_response = self
|
20
|
+
|
21
|
+
while next_response
|
22
|
+
result.concat(next_response.body)
|
23
|
+
next_response = next_response.next
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Response, nil]
|
29
|
+
def next
|
30
|
+
if has_next?
|
31
|
+
request.response(arguments.merge(cursor: next_cursor))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_next?
|
36
|
+
self['cursor']['hasNext']
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String]
|
40
|
+
def next_cursor
|
41
|
+
self['cursor']['next']
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Hash]
|
45
|
+
def body
|
46
|
+
self['response']
|
47
|
+
end
|
48
|
+
alias_method :response, :body
|
49
|
+
|
50
|
+
# @return [Integer]
|
51
|
+
def code
|
52
|
+
self['code']
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DisqusApi::Api do
|
4
|
+
subject(:api) { described_class.new(version, specifications) }
|
5
|
+
|
6
|
+
let(:version) { '3.0' }
|
7
|
+
let(:specifications) { {'users' => 'details'} }
|
8
|
+
|
9
|
+
its(:version) { should == version }
|
10
|
+
its(:specifications) { should == specifications }
|
11
|
+
its(:namespaces) { should have_key(:users) }
|
12
|
+
its(:endpoint) { should == 'https://disqus.com/api/3.0/' }
|
13
|
+
it { should respond_to(:users) }
|
14
|
+
its(:users) { should be_a(DisqusApi::Namespace) }
|
15
|
+
its(:connection_options) { should == {headers: {"Accept"=>"application/json", "User-Agent"=>"DisqusAgent"},
|
16
|
+
ssl: {verify: false},
|
17
|
+
url: "https://disqus.com/api/3.0/"} }
|
18
|
+
|
19
|
+
describe "unregistered namespace metacalls" do
|
20
|
+
it { should_not respond_to(:foo) }
|
21
|
+
specify { expect { api.foo }.to raise_error(ArgumentError) }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#connection" do
|
25
|
+
subject { api.connection }
|
26
|
+
it { should be_a(Faraday::Connection) }
|
27
|
+
its(:params) { should have_key('api_key') }
|
28
|
+
its(:params) { should have_key('api_secret') }
|
29
|
+
its(:params) { should have_key('access_token') }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#get", perform_requests: true do
|
33
|
+
let(:request_path) { '/api/3.0/users/details.json' }
|
34
|
+
|
35
|
+
it 'performs GET request' do
|
36
|
+
api.get(request_path)['code'].should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
context "invalid request" do
|
40
|
+
let(:request_path) { '/api/3.0/invalid/request.json' }
|
41
|
+
let(:response_code) { 1 }
|
42
|
+
|
43
|
+
specify do
|
44
|
+
expect { api.get(request_path) }.to raise_error(DisqusApi::InvalidApiRequestError, /"code"=>1/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#post", perform_requests: true do
|
50
|
+
let(:request_type) { :post }
|
51
|
+
let(:request_path) { '/api/3.0/forums/create.json' }
|
52
|
+
|
53
|
+
context local: true do
|
54
|
+
it 'performs POST request' do
|
55
|
+
api.post(request_path)['code'].should == 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "invalid request" do
|
60
|
+
let(:request_path) { '/api/3.0/invalid/request.json' }
|
61
|
+
let(:response_code) { 1 }
|
62
|
+
|
63
|
+
specify do
|
64
|
+
expect { api.post(request_path) }.to raise_error(DisqusApi::InvalidApiRequestError, /"code"=>1/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DisqusApi::Namespace do
|
4
|
+
let(:api) { DisqusApi::Api.new(version, specifications) }
|
5
|
+
let(:version) { '3.0' }
|
6
|
+
let(:specifications) { {'users' => {'details' => 'get'}} }
|
7
|
+
|
8
|
+
let(:namespace_name) { 'users' }
|
9
|
+
subject(:namespace) { described_class.new(api, namespace_name) }
|
10
|
+
|
11
|
+
its(:api) { should == api }
|
12
|
+
its(:specification) { should == {'details' => 'get'} }
|
13
|
+
its(:name) { should == namespace_name }
|
14
|
+
|
15
|
+
it { should respond_to :details }
|
16
|
+
|
17
|
+
describe "#initialize" do
|
18
|
+
let(:namespace_name) { 'foos' }
|
19
|
+
it { expect { subject }.to raise_error(ArgumentError, "No such namespace <foos>") }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#build_action_request" do
|
23
|
+
subject(:request) { namespace.build_action_request('details', {args: true}) }
|
24
|
+
its(:path) { should == 'users/details.json' }
|
25
|
+
its(:api) { should == api }
|
26
|
+
its(:arguments) { should == {args: true} }
|
27
|
+
end
|
28
|
+
|
29
|
+
context perform_requests: true do
|
30
|
+
let(:request_path) { '/api/3.0/users/details.json' }
|
31
|
+
|
32
|
+
its(:details) { should be_a(Hash) }
|
33
|
+
its(:details) { should be_a(::DisqusApi::Response) }
|
34
|
+
|
35
|
+
it 'performs requests' do
|
36
|
+
namespace.details['code'].should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#request_action" do
|
40
|
+
let(:response) { namespace.request_action('details') }
|
41
|
+
|
42
|
+
it 'performs action request' do
|
43
|
+
response['code'].should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
context "invalid request" do
|
47
|
+
let(:response) { namespace.request_action('foos') }
|
48
|
+
specify { expect { response }.to raise_error(ArgumentError) }
|
49
|
+
specify { expect { namespace.foos }.to raise_error(NoMethodError) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DisqusApi::Request do
|
4
|
+
subject(:request) { described_class.new(api, namespace, action, arguments) }
|
5
|
+
let(:api) { DisqusApi::Api.new(version, specifications) }
|
6
|
+
let(:version) { '3.0' }
|
7
|
+
let(:specifications) { {'users' => {'details' => 'get'}} }
|
8
|
+
let(:namespace) { 'users' }
|
9
|
+
let(:action) { 'details' }
|
10
|
+
let(:arguments) { {} }
|
11
|
+
|
12
|
+
its(:api) { should == api }
|
13
|
+
its(:namespace) { should == namespace }
|
14
|
+
its(:action) { should == action }
|
15
|
+
its(:path) { should == 'users/details.json' }
|
16
|
+
its(:type) { should == :get }
|
17
|
+
its(:arguments) { should == arguments }
|
18
|
+
its(:response) { should be_a(Hash) }
|
19
|
+
its(:response) { should be_a(::DisqusApi::Response) }
|
20
|
+
its(:response) { should have_key('code') }
|
21
|
+
|
22
|
+
describe "#initialize" do
|
23
|
+
context "invalid namespace" do
|
24
|
+
let(:namespace) { 'foo' }
|
25
|
+
specify { expect { subject }.to raise_error(ArgumentError) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "invalid action" do
|
29
|
+
let(:action) { 'foo' }
|
30
|
+
specify { expect { subject }.to raise_error(ArgumentError) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#perform" do
|
35
|
+
it 'sends request through API' do
|
36
|
+
request.perform['code'].should == 0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".perform" do
|
41
|
+
it 'sends request through API' do
|
42
|
+
described_class.perform(api, namespace, action, arguments)['code'].should == 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DisqusApi::Response do
|
4
|
+
let(:request) { DisqusApi::Request.new(api, namespace, action, request_arguments) }
|
5
|
+
let(:api) { DisqusApi::Api.new(version, specifications) }
|
6
|
+
let(:version) { '3.0' }
|
7
|
+
let(:specifications) { {'posts' => {'list' => 'get'}} }
|
8
|
+
let(:namespace) { 'posts' }
|
9
|
+
let(:action) { 'list' }
|
10
|
+
let(:request_arguments) { {forum: 'my_forum'} }
|
11
|
+
|
12
|
+
subject(:response) { described_class.new(request, arguments) }
|
13
|
+
let(:arguments) { {limit: 1} }
|
14
|
+
let(:response_body) { {} }
|
15
|
+
|
16
|
+
before do
|
17
|
+
request.should_receive(:perform).with(arguments).and_return(response_body)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#has_next?" do
|
21
|
+
context "has" do
|
22
|
+
let(:response_body) { {'cursor' => {'hasNext' => true}} }
|
23
|
+
its(:has_next?) { should be_true }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'has not' do
|
27
|
+
let(:response_body) { {'cursor' => {'hasNext' => false}} }
|
28
|
+
its(:has_next?) { should be_false }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#next_cursor" do
|
33
|
+
let(:response_body) { {'cursor' => {'next' => 'next identifier'}} }
|
34
|
+
its(:next_cursor) { should == 'next identifier' }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#body" do
|
38
|
+
let(:response_body) { {'response' => {'received' => true}} }
|
39
|
+
its(:body) { should == {'received' => true} }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#code" do
|
43
|
+
let(:response_body) { {'code' => 0} }
|
44
|
+
its(:code) { should == 0}
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#next" do
|
48
|
+
context "has next page" do
|
49
|
+
let(:response_body) { {'cursor' => {'hasNext' => true, 'next' => 'Next:2'}} }
|
50
|
+
let(:next_page_response) { double('next_page_response') }
|
51
|
+
|
52
|
+
before do
|
53
|
+
request.should_receive(:response).with({limit: 1, cursor: 'Next:2'}).and_return(next_page_response)
|
54
|
+
end
|
55
|
+
|
56
|
+
its(:next) { should == next_page_response }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'has no next page' do
|
60
|
+
let(:response_body) { {'cursor' => {'hasNext' => false, 'next' => 'Next:2'}} }
|
61
|
+
its(:next) { should be_nil }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#all" do
|
66
|
+
let(:response_body) { {'cursor' => {'hasNext' => false, 'next' => 'Next:2'}, 'response' => ['page_1_elem_1']} }
|
67
|
+
its(:all) { should == ['page_1_elem_1'] }
|
68
|
+
|
69
|
+
context "many pages" do
|
70
|
+
let(:response_body) { {'cursor' => {'hasNext' => true, 'next' => 'Next:2'}, 'response' => ['page_1_elem_1']} }
|
71
|
+
let(:next_page_response) { double('next_page_response') }
|
72
|
+
|
73
|
+
before do
|
74
|
+
request.should_receive(:response).with({limit: 1, cursor: 'Next:2'}).and_return(next_page_response)
|
75
|
+
next_page_response.should_receive(:body).and_return(['page_2_elem_1'])
|
76
|
+
next_page_response.should_receive(:next).and_return(nil)
|
77
|
+
end
|
78
|
+
|
79
|
+
its(:all) { should == ['page_1_elem_1', 'page_2_elem_1'] }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DisqusApi, perform_requests: true do
|
4
|
+
describe "user details" do
|
5
|
+
let(:request_path) { '/api/3.0/users/details.json' }
|
6
|
+
|
7
|
+
it 'performs requests' do
|
8
|
+
DisqusApi.v3.users.details['code'].should == 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "posts list", local: true do
|
13
|
+
before :each do
|
14
|
+
stubbed_requests.get("/api/3.0/posts/list.json?forum=my_forum&access_token=&api_key=&api_secret=&limit=1") { [200, {}, {code: 0, response: ['first_one'], cursor: {hasNext: true, next: 1}}.to_json] }
|
15
|
+
stubbed_requests.get("/api/3.0/posts/list.json?cursor=1&forum=my_forum&access_token=&api_key=&api_secret=&limit=1") { [200, {}, {code: 0, response: ['second_one'], cursor: {hasNext: true, next: 2}}.to_json] }
|
16
|
+
stubbed_requests.get("/api/3.0/posts/list.json?cursor=2&forum=my_forum&access_token=&api_key=&api_secret=&limit=1") { [200, {}, {code: 0, response: ['third_one'], cursor: {hasNext: false, next: 3}}.to_json] }
|
17
|
+
stubbed_requests.get("/api/3.0/posts/list.json?cursor=3&forum=my_forum&access_token=&api_key=&api_secret=&limit=1") { [200, {}, {code: 0, response: ['fourth_one'], cursor: {hasNext: false }}.to_json] }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'fetches all comments' do
|
21
|
+
DisqusApi.v3.posts.list(forum: 'my_forum', limit: 1).all.should == %w{first_one second_one third_one}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'disqus_api'
|
2
|
+
|
3
|
+
def load_disqus_config(fname)
|
4
|
+
DisqusApi.config = YAML.load_file(File.join(File.dirname(__FILE__), "config/#{fname}"))
|
5
|
+
end
|
6
|
+
|
7
|
+
if ENV['USE_DISQUS_ACCOUNT']
|
8
|
+
load_disqus_config("disqus.yml")
|
9
|
+
else
|
10
|
+
load_disqus_config("disqus.yml.example")
|
11
|
+
|
12
|
+
shared_context "perform requests", perform_requests: true do
|
13
|
+
before do
|
14
|
+
@all_requests_local = true
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:request_path) { '' }
|
18
|
+
let(:response_body) { nil }
|
19
|
+
let(:response_code) { 0 }
|
20
|
+
let(:request_type) { :get }
|
21
|
+
|
22
|
+
let(:stubbed_requests) do
|
23
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
24
|
+
stub.public_send(request_type, request_path) { [200, {}, {code: response_code, body: response_body}.to_json] }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before :each do
|
29
|
+
DisqusApi.adapter = [:test, stubbed_requests]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
config.mock_with :rspec
|
36
|
+
config.color_enabled = true
|
37
|
+
config.formatter = :documentation
|
38
|
+
|
39
|
+
if ENV['USE_DISQUS_ACCOUNT']
|
40
|
+
config.filter_run_excluding local: true
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: disqus_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergei Zinin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday_middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Provides clean Disqus API for your Ruby app with a nice interface.
|
70
|
+
email: szinin@gmail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- README.md
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
|
+
- Gemfile
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- disqus_api.gemspec
|
82
|
+
- lib/apis/3.0.yml
|
83
|
+
- lib/disqus_api.rb
|
84
|
+
- lib/disqus_api/api.rb
|
85
|
+
- lib/disqus_api/namespace.rb
|
86
|
+
- lib/disqus_api/request.rb
|
87
|
+
- lib/disqus_api/response.rb
|
88
|
+
- spec/config/disqus.yml.example
|
89
|
+
- spec/disqus_api/api_spec.rb
|
90
|
+
- spec/disqus_api/namespace_spec.rb
|
91
|
+
- spec/disqus_api/request_spec.rb
|
92
|
+
- spec/disqus_api/response_spec.rb
|
93
|
+
- spec/disqus_api_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
homepage: http://github.com/einzige/disqus_api
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.1.5
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: Disqus API for Ruby
|
119
|
+
test_files: []
|