rbitter 0.0.8

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +65 -0
  8. data/Rakefile +8 -0
  9. data/XMLRPC.md +19 -0
  10. data/bin/rbitter +6 -0
  11. data/config.json.example +30 -0
  12. data/lib/rbitter/arcserver.rb +97 -0
  13. data/lib/rbitter/console.rb +61 -0
  14. data/lib/rbitter/default/config_json.rb +37 -0
  15. data/lib/rbitter/dlthread.rb +66 -0
  16. data/lib/rbitter/env.rb +59 -0
  17. data/lib/rbitter/libtwitter_connection_override.rb +46 -0
  18. data/lib/rbitter/records.rb +109 -0
  19. data/lib/rbitter/records_migrate/.keep +0 -0
  20. data/lib/rbitter/records_migrate/20150327_add_index.rb +8 -0
  21. data/lib/rbitter/streaming.rb +76 -0
  22. data/lib/rbitter/version.rb +3 -0
  23. data/lib/rbitter/xmlrpc.rb +4 -0
  24. data/lib/rbitter/xmlrpcd/base.rb +25 -0
  25. data/lib/rbitter/xmlrpcd/rpchandles.rb +12 -0
  26. data/lib/rbitter/xmlrpcd/xmlrpc_auth_server.rb +84 -0
  27. data/lib/rbitter/xmlrpcd/xmlrpcd.rb +63 -0
  28. data/lib/rbitter.rb +92 -0
  29. data/rbitter.gemspec +42 -0
  30. data/spec/config/.keep +0 -0
  31. data/spec/config/default.json +33 -0
  32. data/spec/rbitter/arcserver_spec.rb +9 -0
  33. data/spec/rbitter/console_spec.rb +9 -0
  34. data/spec/rbitter/default/config_json_spec.rb +3 -0
  35. data/spec/rbitter/dlthread_spec.rb +9 -0
  36. data/spec/rbitter/env_spec.rb +56 -0
  37. data/spec/rbitter/libtwitter_connection_override_spec.rb +8 -0
  38. data/spec/rbitter/records_spec.rb +13 -0
  39. data/spec/rbitter/streaming_spec.rb +9 -0
  40. data/spec/rbitter/version_spec.rb +8 -0
  41. data/spec/rbitter/xmlrpc_spec.rb +8 -0
  42. data/spec/rbitter/xmlrpcd/base_spec.rb +29 -0
  43. data/spec/rbitter/xmlrpcd/rpchandles_spec.rb +10 -0
  44. data/spec/rbitter/xmlrpcd/xmlrpc_auth_server_spec.rb +8 -0
  45. data/spec/rbitter/xmlrpcd/xmlrpcd_spec.rb +9 -0
  46. data/spec/rbitter_spec.rb +46 -0
  47. data/spec/sample_data/.keep +0 -0
  48. data/spec/spec_helper.rb +36 -0
  49. metadata +238 -0
File without changes
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ class AddIndex < ActiveRecord::Migration
5
+ def self.change
6
+ add_index :records, :tweetid
7
+ end
8
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+
3
+ require 'twitter'
4
+
5
+ module Rbitter
6
+ class StreamClient
7
+ def initialize(tokens)
8
+ @t = Twitter::Streaming::Client.new do |object|
9
+ object.consumer_key = tokens['consumer_key']
10
+ object.consumer_secret = tokens['consumer_secret']
11
+ object.access_token = tokens['access_token']
12
+ object.access_token_secret = tokens['access_token_secret']
13
+ end
14
+ end
15
+
16
+ def run(&operation_block)
17
+ begin
18
+ internal(&operation_block)
19
+ rescue EOFError => e
20
+ puts "Network unreachable. Retry in 3 seconds..."
21
+ sleep 3
22
+ retry
23
+ end
24
+ end
25
+
26
+ private
27
+ def internal(&operation_block)
28
+ @t.user do |tweet|
29
+ if tweet.is_a?(Twitter::Tweet)
30
+ if tweet.retweet?
31
+ tweet = tweet.retweeted_tweet
32
+ end
33
+
34
+ text = tweet.full_text.gsub(/(\r\n|\n)/, '')
35
+
36
+ # unpack uris and media links
37
+ media_urls = Array.new
38
+ web_urls = Array.new
39
+
40
+ if tweet.entities?
41
+ if tweet.media?
42
+ tweet.media.each { |media|
43
+ media_urls.push("#{media.media_uri_https}")
44
+ text.gsub!("#{media.url}", "#{media.display_url}")
45
+ }
46
+ end
47
+
48
+ text += " "
49
+ text += media_urls.join(" ")
50
+
51
+ if tweet.uris?
52
+ tweet.uris.each { |uri|
53
+ web_urls.push("#{uri.expanded_url}")
54
+ text.gsub!("#{uri.url}", "#{uri.expanded_url}")
55
+ }
56
+ end
57
+ end
58
+
59
+ res = {
60
+ "tweetid" => tweet.id,
61
+ "userid" => tweet.user.id,
62
+ "tweet" => text,
63
+ "rt_count" => tweet.retweet_count,
64
+ "fav_count" => tweet.favorite_count,
65
+ "screen_name" => tweet.user.screen_name,
66
+ "date" => tweet.created_at,
67
+ "media_urls" => media_urls,
68
+ "web_urls" => web_urls
69
+ }
70
+
71
+ yield res
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ module Rbitter
2
+ VERSION = "0.0.8"
3
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require "rbitter/xmlrpcd/xmlrpcd"
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module RPCHandles
4
+ RH_INFO = Struct.new("RPCHANDLE_INFO", :name, :version, :author, :description) {
5
+ def digest
6
+ "<rpchandle: #{name}-#{version} (written by #{author}, #{description})>"
7
+ end
8
+ }
9
+
10
+ module BaseHandle
11
+ # If a handler doesn't require an authorization, please inherit below class
12
+ class NoAuth < Object
13
+ def self.auth?
14
+ false
15
+ end
16
+ end
17
+
18
+ # If a handler does require an authorization, please inherit below class
19
+ class Auth < Object
20
+ def self.auth?
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ module RPCHandles
4
+ # Override this function will activate authentication feature.
5
+ # You can write and add RPCHandle. See 'rpc' folder.
6
+
7
+ @@auth_pool = nil
8
+ module_function
9
+ def auth
10
+ @@auth_pool
11
+ end
12
+ end
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require "rbitter/xmlrpcd/rpchandles"
5
+ require "rbitter/xmlrpcd/base"
6
+ require "xmlrpc/server"
7
+ require "webrick"
8
+
9
+ module XMLRPC
10
+ class HTTPAuthXMLRPCServer < XMLRPC::WEBrickServlet
11
+ def extract_method(methodname, *args)
12
+ for name, obj in @handler
13
+ if obj.kind_of? Proc
14
+ next unless methodname == name
15
+ else
16
+ next unless methodname =~ /^#{name}(.+)$/
17
+ next unless obj.respond_to? $1
18
+ return obj.method($1)
19
+ end
20
+ end
21
+ nil
22
+ end
23
+
24
+ def service(request, response)
25
+ # Taken from xmlrpc/server.rb
26
+ if @valid_ip
27
+ raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
28
+ end
29
+
30
+ if request.request_method != "POST"
31
+ raise WEBrick::HTTPStatus::MethodNotAllowed,
32
+ "unsupported method `#{request.request_method}'."
33
+ end
34
+
35
+ if parse_content_type(request['Content-type']).first != "text/xml"
36
+ raise WEBrick::HTTPStatus::BadRequest
37
+ end
38
+
39
+ length = (request['Content-length'] || 0).to_i
40
+
41
+ raise WEBrick::HTTPStatus::LengthRequired unless length > 0
42
+
43
+ data = request.body
44
+
45
+ if data.nil? or data.bytesize != length
46
+ raise WEBrick::HTTPStatus::BadRequest
47
+ end
48
+
49
+ # Originally, process(data) was here.
50
+ # We need to check whether a method requires authorization.
51
+ rpc_method_name, rpc_params = parser().parseMethodCall(data)
52
+ rpc_method = extract_method(rpc_method_name)
53
+
54
+ if RPCHandles.auth.nil?
55
+ resp = handle(rpc_method_name, *rpc_params)
56
+ else
57
+ if rpc_method.owner.ancestors.include?(RPCHandles::BaseHandle::Auth)
58
+ # Check cookie and check it's valid
59
+ if request.cookies.size == 1 \
60
+ and request.cookies[0].name == "auth_key" \
61
+ and RPCHandles.auth.include?(request.cookies[0].value)
62
+ resp = handle(rpc_method_name, *rpc_params)
63
+ else
64
+ # Permission required
65
+ raise WEBrick::HTTPStatus::Forbidden
66
+ end
67
+ elsif rpc_method.owner.ancestors.include?(RPCHandles::BaseHandle::NoAuth)
68
+ resp = handle(rpc_method_name, *rpc_params)
69
+ else
70
+ raise WEBrick::HTTPStatus::Forbidden
71
+ end
72
+ end
73
+
74
+ if resp.nil? or resp.bytesize <= 0
75
+ raise WEBrick::HTTPStatus::InternalServerError
76
+ end
77
+
78
+ response.status = 200
79
+ response['Content-Length'] = resp.bytesize
80
+ response['Content-Type'] = "text/xml; charset=utf-8"
81
+ response.body = resp
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/xmlrpcd/rpchandles"
4
+ require "rbitter/xmlrpcd/xmlrpc_auth_server"
5
+ require "webrick"
6
+
7
+ module Rbitter
8
+ RPC_PREFIX="rbitter"
9
+
10
+ class RPCServer
11
+ def initialize bind_host, bind_port
12
+ @server = WEBrick::HTTPServer.new(:Port => bind_port.to_i, :BindAddress => bind_host.to_s, :MaxClients => 4, :Logger => WEBrick::Log.new($stdout))
13
+ @core = XMLRPC::HTTPAuthXMLRPCServer.new
14
+ load_all_handles
15
+ @core.set_default_handler { |name, *args|
16
+ "NO_COMMAND: #{name} with args #{args.inspect}"
17
+ }
18
+ end
19
+
20
+ def load_all_handles
21
+ Rbitter.env["xmlrpc"]["handles"].each { |path|
22
+ puts "[xmlrpc] Scanning handles from (#{path})"
23
+ Dir.entries(path).each { |fname|
24
+ fname = File.join(path, fname)
25
+ if File.exist?(fname) and File.file?(fname)
26
+ if fname.match(/rh_\w+\.rb$/)
27
+ begin
28
+ load fname
29
+ rescue Exception => e
30
+ # stub
31
+ puts "Exception while loading #{fname}"
32
+ puts e.inspect
33
+ end
34
+ else
35
+ puts "Ignored: #{fname}"
36
+ end
37
+ end
38
+ }
39
+ }
40
+
41
+ puts "[xmlrpc] found #{RPCHandles.constants.length} constants."
42
+ RPCHandles.constants.each { |handler|
43
+ if RPCHandles.const_get(handler).is_a?(Class)
44
+ @core.add_handler(RPC_PREFIX, RPCHandles.const_get(handler).new)
45
+ end
46
+ }
47
+ end
48
+
49
+ def main_loop
50
+ puts "RPCServer starts"
51
+ @server.mount("/", @core)
52
+ @server.start
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ if __FILE__ == $0
59
+ puts "Local testing server starts..."
60
+ rpcd = Rbitter::RPCServer.new('127.0.0.1', 1300)
61
+ rpcd.main_loop
62
+ end
63
+
data/lib/rbitter.rb ADDED
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require "rbitter/version"
5
+ require "rbitter/arcserver"
6
+ require "rbitter/env"
7
+ require "rbitter/console"
8
+ require "rbitter/xmlrpc"
9
+
10
+ module Rbitter
11
+ def self.rbitter_header
12
+ puts "Rbitter #{VERSION} on Ruby-#{RUBY_VERSION} (#{RUBY_PLATFORM})"
13
+ end
14
+
15
+ def self.rbitter_help_msg
16
+ puts "Rbitter is a Twitter streaming archiver, with XMLRPC access."
17
+ puts "-------"
18
+ puts "Usage: rbitter (application-mode)"
19
+ puts "application-mode's are:"
20
+ puts "|- serve : Launch Rbitter full system (Streaming + Database + XMLRPC)"
21
+ puts "|- console : Launch console application utilizing XMLRPC"
22
+ puts "|- configure: Write default configuration file 'config.json' in current folder"
23
+ puts "|- help : Show this message"
24
+ puts "`- logs : Show Rbitter internal logs"
25
+ end
26
+
27
+ def self.prebootstrap
28
+ # Due to stalled socket problem, If unpatched twitter gem is installed.
29
+ # Twitter::Streaming::Connection will be monkey-patched.
30
+ patch_required = false
31
+
32
+ if Twitter::Version.const_defined?(:MAJOR)
33
+ b5_version = Twitter::Version::MAJOR * 10000
34
+ + Twitter::Version::MINOR * 100 + Twitter::Version::PATCH
35
+ if b5_version <= 51400
36
+ warn "[rbitter] Monkey-patching Twitter::Streaming::Connection..."
37
+ warn "[rbitter] Gem installed on here seemed that it doesn't handle socket read timeout."
38
+ warn "[rbitter] Please upgrade twitter gem"
39
+ patch_required = true
40
+ end
41
+ else
42
+ b6_version = Twitter::Version.to_a
43
+ if b6_version[0] <= 6 and b6_version[1] <= 0 and b6_version[2] <= 0
44
+ patch_required = true
45
+ end
46
+ end
47
+
48
+ require "rbitter/libtwitter_connection_override" if patch_required
49
+ end
50
+
51
+ def self.bootstrap args=[]
52
+ prebootstrap
53
+
54
+ if args.length == 0
55
+ rbitter_header
56
+ elsif args[0] == "serve"
57
+ Rbitter.config_initialize
58
+
59
+ main = Rbitter::ArcServer.new
60
+ if env['xmlrpc']['enable']
61
+ $rpc_service_thread = Thread.new {
62
+ rpc_server = Rbitter::RPCServer.new(env['xmlrpc']['bind_host'], env['xmlrpc']['bind_port'])
63
+ rpc_server.main_loop
64
+ }
65
+ $rpc_service_thread.run
66
+ end
67
+ main.main_loop
68
+ elsif args[0] == "configure"
69
+ require "rbitter/default/config_json"
70
+
71
+ puts "Writing config.json now"
72
+ open(File.join(Dir.pwd, "config.json"), "w") { |io|
73
+ io.write(DEFAULT_CONFIG_JSON)
74
+ }
75
+ puts "Writing finished"
76
+ puts "You can put config.json one of these locations:"
77
+ puts "[1] config.json (current folder)"
78
+ puts "[2] .rbitter/config.json (current folder)"
79
+ elsif args[0] == "console"
80
+ Rbitter.config_initialize
81
+
82
+ con = Rbitter::Console.new
83
+ con.start
84
+ elsif args[0] == "logs"
85
+ # show log in stdout
86
+ puts "This feature is in heavy development. Sorry."
87
+ else
88
+ rbitter_header
89
+ rbitter_help_msg
90
+ end
91
+ end
92
+ end
data/rbitter.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'rbitter/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "rbitter"
9
+ spec.version = Rbitter::VERSION
10
+ spec.authors = ["Nidev Plontra"]
11
+ spec.email = ["nidev.plontra@gmail.com"]
12
+ spec.summary = %q{Rbitter is a Twitter client specialized in archiving}
13
+ spec.description = %q{Rbitter archives all tweets appeared on user streaming using ActiveRecord. XMLRPC is used to serve archived tweets and useful features}
14
+ spec.homepage = "https://github.com/nidev/rbitter"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+
23
+ spec.add_dependency 'twitter', '~> 5.14'
24
+ spec.add_dependency 'json', '~> 1.7'
25
+ spec.add_dependency 'ripl', '~> 0'
26
+ spec.add_dependency 'activerecord', '~> 4.0'
27
+
28
+ if RUBY_PLATFORM == 'java'
29
+ spec.add_dependency 'activerecord-jdbc-adapter', '~> 1.3'
30
+ spec.add_dependency 'jdbc-sqlite3', '~> 3.8'
31
+ spec.add_dependency 'jdbc-mysql', '~> 5.1'
32
+ spec.add_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3'
33
+ spec.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3'
34
+ else
35
+ spec.add_dependency 'sqlite3', '~> 1.3'
36
+ spec.add_dependency 'mysql2', '~> 0.3'
37
+ spec.add_dependency 'activerecord-mysql2-adapter', '~> 0.0.3'
38
+ end
39
+
40
+ spec.add_development_dependency "bundler", "~> 1.6"
41
+ spec.add_development_dependency "rake", "~> 10.0"
42
+ end
data/spec/config/.keep ADDED
File without changes
@@ -0,0 +1,33 @@
1
+ {
2
+ "twitter": {
3
+ "consumer_key": "",
4
+ "consumer_secret": "",
5
+ "access_token": "",
6
+ "access_token_secret": ""
7
+ },
8
+ "activerecord": "sqlite3",
9
+ "sqlite3": {
10
+ "dbfile": "rbitter.sqlite"
11
+ },
12
+ "mysql2": {
13
+ "host": "localhost",
14
+ "port": 3306,
15
+ "dbname": "archive",
16
+ "username": "",
17
+ "password": ""
18
+ },
19
+ "media_downloader": {
20
+ "cacert_path": "/cacerts/cacert.pem",
21
+ "download_dir": "imgs/"
22
+ },
23
+ "xmlrpc": {
24
+ "enable": true,
25
+ "bind_host": "0.0.0.0",
26
+ "bind_port": 1400,
27
+ "auth": {
28
+ "username": "username",
29
+ "password": "password"
30
+ },
31
+ "handles": ["/path/to/handles"]
32
+ }
33
+ }
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/arcserver"
3
+
4
+ describe Rbitter::ArcServer do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::ArcServer).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/console"
3
+
4
+ describe Rbitter::Console do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::Console).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/default/config_json"
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/dlthread"
3
+
4
+ describe Rbitter::DLThread do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::DLThread).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter"
4
+
5
+ describe Rbitter do
6
+ it 'has env_reset function and clears Rbitter.env,' do
7
+ Rbitter.env_reset
8
+ expect(Rbitter.env).to be_a(Hash)
9
+ expect(Rbitter.env.length).to be(0)
10
+ end
11
+
12
+ context 'when config.json is not installed,' do
13
+ it 'fails on loading' do
14
+ expect{Rbitter.config_initialize}.to raise_error(Rbitter::ConfigurationFileError)
15
+ end
16
+ end
17
+
18
+ context 'when path to config.json is invalid,' do
19
+ it 'fals on loading' do
20
+ expect{Rbitter.config_initialize("/silly/dummy/.")}.to raise_error(Rbitter::ConfigurationFileError)
21
+ end
22
+ end
23
+
24
+
25
+ context 'when default config.json is installed,' do
26
+ before(:all) do
27
+ Rbitter.bootstrap(['configure'])
28
+ expect(File.file?('config.json')).to be(true)
29
+ end
30
+
31
+ it 'loads configuration successfully with autodetection' do
32
+ expect{Rbitter.config_initialize}.to_not raise_error
33
+ expect(Rbitter.env.length > 0).to be(true)
34
+ end
35
+
36
+ it 'loads configuration successfully with given config.json path' do
37
+ expect{Rbitter.config_initialize('config.json')}.to_not raise_error
38
+ expect(Rbitter.env.length > 0).to be(true)
39
+ end
40
+
41
+ it 'checks that Rbitter.env returns Hash' do
42
+ expect(Rbitter.env).to be_a(Hash)
43
+ end
44
+
45
+ after(:all) do
46
+ File.delete('config.json')
47
+ end
48
+ end
49
+
50
+ context 'when config.json is corrupted' do
51
+ # TODO: Perform test with spec/config/default.json
52
+ # TODO: Adding configuration validator on env.rb
53
+ end
54
+
55
+ # TODO: Perform test with spec/config/default.json
56
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/libtwitter_connection_override"
3
+
4
+ describe Rbitter do
5
+ it 'overrides twitter gem' do
6
+ expect(Twitter::Streaming::Connection::MODIFIED).to be(true)
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ require "rbitter/records"
3
+
4
+ describe Rbitter::Record do
5
+ # TODO: Perform test...
6
+ it 'has ActiveRecord class named Record' do
7
+ expect(Rbitter::Record).to be_a(Class)
8
+ end
9
+
10
+ it 'has supportive module of ActiveRecord' do
11
+ expect(ARSupport).to be_a(Module)
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/streaming"
3
+
4
+ describe Rbitter::StreamClient do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::StreamClient).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/version"
3
+
4
+ describe Rbitter do
5
+ it 'has version string' do
6
+ expect(Rbitter::VERSION).to be_a(String)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/xmlrpc"
3
+
4
+ describe Rbitter do
5
+ it 'Rbitter is a module' do
6
+ expect(Rbitter.class === Module).to be(true)
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/xmlrpcd/base"
4
+
5
+ describe RPCHandles do
6
+ context 'when RH_INFO Struct is served as RPCHandle information,' do
7
+ it 'structs corrct Struct::RPCHANDLE_INFO' do
8
+ # String comparison: use eq(==), not be(===)
9
+ expect(RPCHandles::RH_INFO.to_s).to eq("Struct::RPCHANDLE_INFO")
10
+ end
11
+
12
+ it 'provides correct information when #digest is called' do
13
+ digest_string = RPCHandles::RH_INFO.new('test', 0.1, 'test', 'test').digest
14
+ expect(digest_string).to eq("<rpchandle: test-0.1 (written by test, test)>")
15
+ end
16
+ end
17
+ end
18
+
19
+ describe RPCHandles::BaseHandle do
20
+ context 'when an RPCHandle inherits one of classes Auth and NoAuth' do
21
+ it 'returns false on #auth? when an RPCHandle class inherits NoAuth' do
22
+ expect(RPCHandles::BaseHandle::NoAuth.auth?).to be(false)
23
+ end
24
+
25
+ it 'returns true on #auth? when an RPCHandle class inherits Auth' do
26
+ expect(RPCHandles::BaseHandle::Auth.auth?).to be(true)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ require "rbitter/xmlrpcd/rpchandles"
3
+
4
+ describe RPCHandles do
5
+ context 'When features related to authentication needs ::auth method,'
6
+ it 'responds to ::auth' do
7
+ expect(RPCHandles.respond_to?(:auth)).to be(true)
8
+ expect(RPCHandles.auth).to be_a(NilClass)
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/xmlrpcd/xmlrpc_auth_server"
3
+
4
+ describe Rbitter do
5
+ it 'Rbitter is a module' do
6
+ expect(Rbitter.class === Module).to be(true)
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/xmlrpcd/xmlrpcd"
4
+
5
+ describe Rbitter do
6
+ it 'Rbitter is a module' do
7
+ expect(Rbitter.class === Module).to be(true)
8
+ end
9
+ end