ideaoforder-acts_as_disqusable 0.4.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.
@@ -0,0 +1,27 @@
1
+ module Disqus
2
+
3
+ class BaseAuthor
4
+ attr_reader :url, :email_hash
5
+ end
6
+
7
+ class Author < BaseAuthor
8
+ attr_reader :id, :username, :display_name, :has_avatar
9
+ def initialize(id, username, display_name, url, email_hash, has_avatar)
10
+ @id, @username, @display_name, @url, @email_hash, @has_avatar = id, username, display_name, url, email_hash, has_avatar
11
+ end
12
+
13
+ # Returns the user's <tt>display_name</tt> or <tt>username</tt> if <tt>display_name</tt> is blank.
14
+ def name
15
+ @display_name.blank? ? @username : @display_name
16
+ end
17
+
18
+ end
19
+
20
+ class AnonymousAuthor < BaseAuthor
21
+ attr_reader :name
22
+ def initialize(name, url, email_hash)
23
+ @name, @url, @email_hash = name, url, email_hash
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,118 @@
1
+ module Disqus
2
+ class Forum
3
+
4
+ attr_accessor :id, :shortname, :name, :created_at, :description
5
+ def initialize(data)
6
+ data.each { |k, v| send(:"#{k}=", v) }
7
+ end
8
+
9
+ def self.all
10
+ @@all ||= begin
11
+ response = get('/get_forum_list')
12
+ response["succeeded"] ? response["message"].map { |data| Disqus::Forum.new(data) } : nil
13
+ end
14
+ end
15
+
16
+ def self.find(id)
17
+ id = id.to_s if !id.is_a? String
18
+ grouped = self.all.group_by(&:id)
19
+ grouped[id].first if grouped[id]
20
+ end
21
+
22
+ # Returns the forum API Key for this forum.
23
+ def key(user_api_key = nil)
24
+ @key ||= begin
25
+ response = self.class.get('/get_forum_api_key', :query => {
26
+ :api_key => user_api_key,
27
+ :forum_id => id
28
+ })
29
+ response["succeeded"] ? response["message"] : nil
30
+ end
31
+ end
32
+
33
+ # Returns an array of threads belonging to this forum.
34
+ def self.threads(id, key)
35
+ response = self.get('/get_thread_list', :query => {
36
+ :forum_api_key => key,
37
+ :forum_id => id
38
+ })
39
+ response["succeeded"] ? response["message"].map { |data| Disqus::Thread.new(data) } : nil
40
+ end
41
+
42
+ def threads
43
+ self.class.threads(self.id, self.key)
44
+ end
45
+
46
+ # Returns a thread associated with the given URL.
47
+ #
48
+ # A thread will only have an associated URL if it was automatically
49
+ # created by Disqus javascript embedded on that page.
50
+ def self.get_thread_by_url(url, key)
51
+ response = self.get('/get_thread_by_url', :query => { :url => url, :forum_api_key => key })
52
+ response["succeeded"] ? Thread.new(response["message"]) : nil
53
+ end
54
+
55
+ def get_thread_by_url(url)
56
+ self.class.get_thread_by_url(url, self.key)
57
+ end
58
+
59
+ def self.thread_by_identifier(identifier, title, key)
60
+ response = self.post('/thread_by_identifier', :query => {
61
+ :forum_api_key => key,
62
+ :identifier => identifier,
63
+ :title => title
64
+ })
65
+
66
+ response["succeeded"] ? Thread.new(response["message"]["thread"]) : nil
67
+ end
68
+
69
+ def thread_by_identifier(identifier, title)
70
+ self.class.thread_by_identifier(identifier, title, self.key)
71
+ end
72
+
73
+ # Sets the provided values on the thread object.
74
+ #
75
+ # Returns an empty success message.
76
+ #
77
+ # Options:
78
+ #
79
+ # * <tt>:title</tt> - the title of the thread
80
+ # * <tt>:slug</tt> - the per-forum-unique string used for identifying this thread in disqus.com URL's relating to this thread. Composed of underscore-separated alphanumeric strings.
81
+ # * <tt>:url</tt> - the URL this thread is on, if known.
82
+ # * <tt>:allow_comment</tt> - whether this thread is open to new comments
83
+ def self.update_thread(thread_id, key, opts = {})
84
+ response = self.post('/update_thread', :query => opts.merge(:forum_api_key => key))
85
+ response["succeeded"]
86
+ end
87
+
88
+ def update_thread(thread_id, opts = {})
89
+ self.class.update_thread(thread_id, self.key, opts = {})
90
+ end
91
+
92
+ def self.posts_count(thread_ids, key)
93
+ response = self.get('/get_num_posts', :query => { :thread_ids => thread_ids, :forum_api_key => key })
94
+ out = Hash.new
95
+ response["message"].each { |id, data| out[id] = data.first }
96
+ if out.length == 1
97
+ return out.values.first
98
+ else
99
+ return out
100
+ end
101
+ end
102
+
103
+ def posts_count(thread_ids)
104
+ self.class.posts_count(thread_ids, self.key)
105
+ end
106
+
107
+ # Returns an array of posts belonging to this thread.
108
+ def self.posts(key, opts={:exclude => 'spam'})
109
+ response = self.get('/get_forum_posts', :query => opts.merge(:forum_api_key => key ))
110
+ out = Hash.new
111
+ response["message"].map { |data| Disqus::Post.new(data) }
112
+ end
113
+
114
+ def posts(opts={:exclude => 'spam'})
115
+ self.class.posts(self.key)
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,31 @@
1
+ module Disqus
2
+ class Post
3
+ attr_accessor :id, :forum, :thread, :created_at, :message, :parent_post, :shown, :is_anonymous, :anonymous_author, :author, :points, :status, :has_been_moderated, :ip_address
4
+ def initialize(data)
5
+ data.each { |k, v| send(:"#{k}=", v) }
6
+ end
7
+
8
+ def author_name
9
+ if is_anonymous
10
+ anonymous_author["name"]
11
+ else
12
+ author["display_name"] || author["username"]
13
+ end
14
+ end
15
+
16
+ def linked_author(opts={})
17
+ "<a href=\"#{author['url']}\" target=\"#{opts[:target]}\" class=\"#{opts[:class]}\">#{self.author_name}</a>"
18
+ end
19
+
20
+ def self.create(opts={})
21
+ response = self.class.post('/create_post', :query => opts)
22
+ if response["success"]
23
+ Disqus::Post.new(response["message"])
24
+ else
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+
@@ -0,0 +1,38 @@
1
+ module Disqus
2
+ class Thread
3
+ attr_accessor :id, :forum, :slug, :title, :created_at, :allow_comments, :url, :identifier, :hidden, :category
4
+ def initialize(data)
5
+ data.each { |k, v| send(:"#{k}=", v) }
6
+ end
7
+
8
+ def self.find_or_create(title, identifier)
9
+ response = self.post('/thread_by_identifier', :body => { :title => title, :identifier => identifier }.merge(self.default_params))
10
+ Disqus::Thread.new(response["message"]["thread"])
11
+ end
12
+
13
+ def posts_count
14
+ response = self.class.get('/get_num_posts', :query => { :thread_ids => id })
15
+ response["message"][id].first.to_i
16
+ end
17
+
18
+ # Returns an array of posts belonging to this thread.
19
+ # limit — Number of entries that should be included in the response. Default is 25.
20
+ # start — Starting point for the query. Default is 0.
21
+ # filter — Type of entries that should be returned (new, spam or killed).
22
+ # exclude — Type of entries that should be excluded from the response (new, spam or killed).
23
+ def self.posts(thread_id, opts={:exclude => 'spam'})
24
+ response = self.get('/get_thread_posts', :query => opts.merge(:thread_id => thread_id ))
25
+ response["message"].map { |data| Disqus::Post.new(data) }
26
+ end
27
+
28
+ def posts(opts={:exclude => 'spam'})
29
+ self.class.posts(self.id)
30
+ end
31
+
32
+ # Sets the provided values on the thread object.
33
+ def update(opts = {})
34
+ result = self.class.post('/update_thread', :query => opts.merge(:forum_api_key => forum.key))
35
+ return result["succeeded"]
36
+ end
37
+ end
38
+ end
data/lib/disqus.rb ADDED
@@ -0,0 +1,52 @@
1
+ # == From the {Disqus Website}[http://disqus.com]:
2
+
3
+ # "Disqus, pronounced "discuss", is a service and tool for web comments and
4
+ # discussions. The Disqus comment system can be plugged into any website, blog,
5
+ # or application. Disqus makes commenting easier and more interactive, while
6
+ # connecting websites and commenters across a thriving discussion community."
7
+ #
8
+ # "Disqus is a free service to the general public with absolutely no inline
9
+ # advertisements."
10
+
11
+ # The Disqus gem helps you quickly and easily integrate Disqus's Javascript
12
+ # widgets into your Ruby-based website. Adding Disqus to your site literally
13
+ # takes only a few minutes. The Disqus gem also provides a complete
14
+ # implementation of the Disqus API for more complex applications.
15
+
16
+ # To use this code, please first create an account on Disqus[http://disqus.com].
17
+ require 'rubygems'
18
+ require 'httparty'
19
+
20
+ require 'acts_as_disqusable/forum'
21
+ require 'acts_as_disqusable/thread'
22
+ require 'acts_as_disqusable/post'
23
+ require 'acts_as_disqusable/author'
24
+
25
+ module Disqus
26
+ @defaults = {
27
+ :api_key => "",
28
+ :account => "",
29
+ :developer => false,
30
+ :api_version => '1.1',
31
+ :container_id => 'disqus_thread',
32
+ :avatar_size => 48,
33
+ :num_items => 5,
34
+ :forum_api_key => '', # optional--if you're just mapping one forum to your app, this is convenient
35
+ :forum_shortname => '', # ditto
36
+ :forum_id => '' # ditto
37
+ }
38
+
39
+ def self.defaults
40
+ @config = @defaults.merge(YAML::load(File.open("#{RAILS_ROOT}/config/disqus.yml")))
41
+ end
42
+
43
+ [Author, Forum, Post, Thread].each do |klass|
44
+ klass.class_eval "include HTTParty"
45
+ klass.class_eval "base_uri 'http://disqus.com/api'"
46
+ klass.class_eval "format :json"
47
+ klass.class_eval "default_params :user_api_key => '#{self.defaults[:api_key]}'"
48
+ klass.class_eval "default_params :forum_api_key => '#{self.defaults[:forum_api_key]}'"
49
+ klass.class_eval "default_params :forum_id => '#{self.defaults[:forum_id]}'"
50
+ klass.class_eval "default_params :api_version => '#{self.defaults[:api_version]}'"
51
+ end
52
+ end
data/tasks/rcov.rake ADDED
@@ -0,0 +1,23 @@
1
+ desc "Run RCov"
2
+ task :rcov do
3
+ run_coverage Dir["test/**/*_test.rb"]
4
+ end
5
+
6
+ def run_coverage(files)
7
+ rm_f "coverage"
8
+ rm_f "coverage.data"
9
+ if files.length == 0
10
+ puts "No files were specified for testing"
11
+ return
12
+ end
13
+ files = files.join(" ")
14
+ if PLATFORM =~ /darwin/
15
+ exclude = '--exclude "gems/"'
16
+ else
17
+ exclude = '--exclude "rubygems"'
18
+ end
19
+ rcov = "rcov -Ilib:test --sort coverage --text-report #{exclude} --no-validator-links"
20
+ cmd = "#{rcov} #{files}"
21
+ puts cmd
22
+ sh cmd
23
+ end
data/test/api_test.rb ADDED
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ApiTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ require 'disqus'
7
+ Disqus.defaults[:api_key] = DISQUS_TEST["api_key"]
8
+ end
9
+
10
+ def test_create_post
11
+ mock_post_response('create_post.json')
12
+ the_post = Disqus::Api::create_post()
13
+ assert_equal "This is a mock post", the_post["message"]["message"]
14
+ end
15
+
16
+ def test_get_forum_list
17
+ mock_get_response('get_forum_list.json')
18
+ forum_list = Disqus::Api::get_forum_list
19
+ assert_equal "Disqus Test", forum_list["message"][0]["name"]
20
+ end
21
+
22
+ def test_get_forum_api_key
23
+ mock_get_response('get_forum_api_key.json')
24
+ forum_api_key = Disqus::Api::get_forum_api_key(:forum_id => 1234, :user_api_key=>"FAKE_KEY")
25
+ assert_equal "FAKE_FORUM_API_KEY", forum_api_key["message"]
26
+ end
27
+
28
+ def test_get_thread_list
29
+ mock_get_response('get_thread_list.json')
30
+ thread_list = Disqus::Api::get_thread_list(:forum_api_key=>"FAKE_KEY")
31
+ assert_equal "this_is_the_thread_identifier", thread_list["message"].first["identifier"]
32
+ end
33
+
34
+ def test_get_num_posts
35
+ mock_get_response('get_num_posts.json')
36
+ nums = Disqus::Api::get_num_posts(:thread_ids => [123,456], :forum_api_key=>"FAKE_KEY")
37
+ assert_equal [10,12], nums["message"][nums["message"].keys.first]
38
+ end
39
+
40
+ def test_get_thread_by_url
41
+ mock_get_response('get_thread_by_url.json')
42
+ thread = Disqus::Api::get_thread_by_url(:url => "FAKE_URL", :forum_api_key=>"FAKE_KEY")
43
+ assert_equal "test_thread", thread["message"]["slug"]
44
+ end
45
+
46
+ def test_get_thread_posts
47
+ mock_get_response('get_thread_posts.json')
48
+ thread_posts = Disqus::Api::get_thread_posts(:thread_id =>1234, :forum_api_key => "FAKE_KEY")
49
+ assert_equal "This is a mock post", thread_posts["message"].first["message"]
50
+ end
51
+
52
+ def test_thread_by_identifier
53
+ mock_post_response('thread_by_identifier.json')
54
+ thread = Disqus::Api::thread_by_identifier(:identifier =>'foo_bar', :title => "Foo Bar", :forum_api_key => "FAKE_KEY")
55
+ assert_equal "Test thread", thread["message"]["thread"]["title"]
56
+ end
57
+
58
+ def test_update_thread
59
+ mock_post_response('update_thread.json')
60
+ result = Disqus::Api::thread_by_identifier(:thread_id =>123, :title => "Foo Bar", :forum_api_key => "FAKE_KEY")
61
+ assert result["succeeded"]
62
+ end
63
+
64
+ def test_comment_form
65
+ c = Disqus::Api::comment_form("myforum", "mythread")
66
+ assert_match(/myforum/, c)
67
+ assert_match(/mythread/, c)
68
+ end
69
+
70
+ private
71
+
72
+ def mock_get_response(file)
73
+ Disqus::Api.expects(:get).returns(File.read(File.dirname(__FILE__) + "/responses/#{file}"))
74
+ end
75
+
76
+ def mock_post_response(file)
77
+ Disqus::Api.expects(:post).returns(File.read(File.dirname(__FILE__) + "/responses/#{file}"))
78
+ end
79
+
80
+ end
@@ -0,0 +1,3 @@
1
+ # This can be used to do actual calls to the API rather than use mocks during
2
+ # testing. This can be useful to verify tests against API changes.
3
+ api_key: 'YOUR DISQUS USER API KEY GOES HERE'
@@ -0,0 +1,70 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class ForumTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ require 'disqus'
7
+ Disqus.defaults[:api_key] = DISQUS_TEST["api_key"]
8
+ stub_api_call(:get_forum_api_key).returns("FAKE_FORUM_API_KEY")
9
+ end
10
+
11
+ def test_forum_list
12
+ mock_api_call(:get_forum_list)
13
+ list = Disqus::Forum.list
14
+ expected = [create_forum]
15
+ assert_equal 1, list.size
16
+ assert_equal expected, list
17
+ end
18
+
19
+ def test_forum_find
20
+ mock_api_call(:get_forum_list)
21
+ forum = Disqus::Forum.find(1234)
22
+ assert_equal "disqus-test", forum.shortname
23
+ end
24
+
25
+ def test_forum_find_bad_id
26
+ mock_api_call(:get_forum_list)
27
+ forum = Disqus::Forum.find(666)
28
+ assert_equal nil, forum
29
+ end
30
+
31
+ def test_forum_find_no_forums
32
+ Disqus::Api.expects(:get_forum_list).returns({"succeeded"=>true, "code"=>"", "message" => []})
33
+ forum = Disqus::Forum.find(1234)
34
+ assert_equal nil, forum
35
+ end
36
+
37
+ def test_key
38
+ mock_api_call(:get_forum_api_key)
39
+ forum = Disqus::Forum.new(1234, "disqus-test", "Disqus Test", "2008-01-03 14:44:07.627492")
40
+ assert_equal "FAKE_FORUM_API_KEY", forum.key
41
+ end
42
+
43
+ def test_forum_threads
44
+ forum = create_forum
45
+ Disqus::Thread.expects(:list).with(forum).returns([thread = mock()])
46
+ assert_equal [thread], forum.forum_threads
47
+ end
48
+
49
+ def test_get_thread_by_url
50
+ mock_api_call(:get_thread_by_url)
51
+ forum = create_forum
52
+ thread = forum.get_thread_by_url("http://www.example.com")
53
+ expected = Disqus::Thread.new("7651269", forum, "test_thread", "Test thread", "2008-11-28T01:47", true, "FAKE_URL", nil)
54
+ assert_equal expected, thread
55
+ end
56
+
57
+ def test_thread_by_identifier
58
+ mock_api_call(:thread_by_identifier)
59
+ forum = create_forum
60
+ thread = forum.thread_by_identifier("FAKE_IDENTIFIER", "")
61
+ expected = Disqus::Thread.new("7651269", forum, "test_thread", "Test thread", "2008-11-28T01:47", true, "FAKE_URL", "FAKE_IDENTIFIER")
62
+ assert_equal expected, thread
63
+ end
64
+
65
+ def test_update_thread
66
+ Disqus::Api.expects(:update_thread).with({:thread_id => 1234, :forum_api_key => "FAKE_FORUM_API_KEY", :title => 'Title', :slug => "a_slug", :url => "http://www.example.com", :allow_comments => true}).returns({"succeeded" => true})
67
+ forum = create_forum
68
+ forum.update_thread(1234, :title => 'Title', :slug => "a_slug", :url => "http://www.example.com", :allow_comments => true)
69
+ end
70
+ end