disqus_api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ .yardoc
3
+ rdoc
4
+ coverage
5
+ .bundle
6
+ .ruby-version
7
+ .rvmrc
8
+ .idea
9
+ Gemfile.lock
10
+ spec/config/disqus.yml
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "rspec"
7
+ end
@@ -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.
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new :spec
5
+ task default: :spec
6
+
@@ -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
+
@@ -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
@@ -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,3 @@
1
+ api_secret: ''
2
+ api_key: ''
3
+ access_token: ''
@@ -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
@@ -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: []