torrents 1.0.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,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Container::Shared do
4
+ before(:each) do
5
+ @shared = Container::Shared.new
6
+ end
7
+ context "the download method" do
8
+ it "should return an empty string when trying to download an empty or non valid URL" do
9
+ @shared.download("non_working_url").should be_empty
10
+ @shared.download(nil).should be_empty
11
+ end
12
+
13
+ it "should return the content of the site if called with the right url" do
14
+ RestClient.should_receive(:get).with("http://example.com", {:timeout => 10, :cookies => nil}).exactly(1).times.and_return("123")
15
+ @shared.download("http://example.com").should eq("123")
16
+ end
17
+ end
18
+
19
+ context "the error method" do
20
+ it "should have a error method" do
21
+ lambda {
22
+ @shared.error("some message")
23
+ @shared.error("some message", "other")
24
+ }.should_not raise_error(Exception)
25
+ end
26
+ end
27
+
28
+ context "the inner_call" do
29
+ before(:each) do
30
+ @load = mock(Object)
31
+ end
32
+
33
+ it "should call an example method with no arguments" do
34
+ @shared.should_receive(:load).and_return(@load)
35
+ @load.should_receive(:example).with.and_return("value") # No arguments
36
+ @shared.inner_call(:example).should eq("value")
37
+ end
38
+
39
+ it "should call an example method with arguments" do
40
+ @shared.should_receive(:load).and_return(@load)
41
+ @load.should_receive(:example).with("abc").and_return("value") # No arguments
42
+ @shared.inner_call(:example, "abc").should eq("value")
43
+ end
44
+
45
+ it "should call an example and rescue an exception" do
46
+ @shared.should_receive(:load).and_return(lambda{
47
+ raise NoMethodError.new
48
+ })
49
+
50
+ @shared.should_receive(:error)
51
+ @shared.should_receive(:default_values).with(:call).and_return("error")
52
+ @shared.inner_call(:call).should eq("error")
53
+ end
54
+
55
+ it "should only catch NoMethodError exception" do
56
+ lambda {
57
+ @shared.should_receive(:load).and_return(lambda{
58
+ raise Exception.new
59
+ })
60
+
61
+ @shared.inner_call(:call).should eq("error")
62
+ }.should raise_error(Exception)
63
+ end
64
+ end
65
+
66
+ context "the default_values method" do
67
+ it "should return the right value" do
68
+ {torrent: "", torrents: [], seeders: 1, title: "", details: ""}.each do |method, value|
69
+ @shared.default_values(method).should eq(value)
70
+ end
71
+ end
72
+
73
+ it "should return an empty string if the value isn't in the hash" do
74
+ @shared.default_values(:random).should eq("")
75
+ end
76
+ end
77
+
78
+ context "the load method" do
79
+ before(:all) do
80
+ class Test < Container::Shared
81
+ def initialize
82
+ @tracker = "the_pirate_bay"
83
+ end
84
+ end
85
+ end
86
+ it "should create a new instance of any string" do
87
+ Test.new.load.should be_instance_of(Trackers::ThePirateBay)
88
+ end
89
+ end
90
+
91
+ context "the url_cleaner method" do
92
+ # Read more about the cleaner here
93
+ # http://stackoverflow.com/questions/4999322/escape-and-download-url-using-ruby
94
+ it "should be able to clean urls" do
95
+ list = {}
96
+ ["{", "}", "|", "\\", "^", "[", "]", "`", " a"].each do |c|
97
+ list.merge!("http://google.com/#{c}" => "http://google.com/#{CGI::escape(c)}")
98
+ end
99
+
100
+ list.each do |url, clean|
101
+ lambda {
102
+ URI.parse(url)
103
+ }.should raise_error(URI::InvalidURIError)
104
+
105
+ lambda {
106
+ URI.parse(@shared.url_cleaner(url)).to_s.should eq(clean)
107
+ }.should_not raise_error(URI::InvalidURIError)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec'
2
+ require 'torrents'
3
+ require 'torrents/container'
4
+ require 'uri'
5
+ require 'yaml'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rspec
9
+ end
@@ -0,0 +1,186 @@
1
+ require 'spec_helper'
2
+
3
+ describe Container::Torrent do
4
+ def create_torrent(args = {details: "http://thepiratebay.org/torrent/6173093/", torrent: "http://torrents.thepiratebay.org/6173093/value.torrent", title: "The title", tracker: "the_pirate_bay"})
5
+ Container::Torrent.new(args)
6
+ end
7
+
8
+ def valid_url?(url)
9
+ !! url.match(/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/i)
10
+ end
11
+
12
+ def create_torrents(n)
13
+ torrents = []
14
+ n.times do |n|
15
+ torrents << create_torrent({
16
+ details: "http://thepiratebay.org/torrent/617#{n}093/",
17
+ torrent: "http://torrents.thepiratebay.org/617093/value.torrent",
18
+ title: "The title",
19
+ tracker: "the_pirate_bay"
20
+ })
21
+ end
22
+
23
+ torrents
24
+ end
25
+
26
+ def rest_client
27
+ RestClient.should_receive(:get).with("http://thepiratebay.org/torrent/6173093/", {:timeout => 10, :cookies => nil}).at_least(1).times.and_return(File.read('spec/data/the_pirate_bay/details.html'))
28
+ end
29
+
30
+ before(:all) do
31
+ @torrent = create_torrent
32
+ @methods = {:details => String, :torrent => String, :title => String, :seeders => Fixnum, :dead? => [TrueClass, FalseClass]}
33
+ end
34
+
35
+ it "should contain the right accessors" do
36
+ @methods.each do |method, _|
37
+ @torrent.methods.should include(method)
38
+ end
39
+ end
40
+
41
+ it "should have the right return type" do
42
+ rest_client
43
+ @methods.each do |method, type|
44
+ type.class == Array ? (type.should include(@torrent.send(method).class)) : (@torrent.send(method).should be_instance_of(type))
45
+ end
46
+ end
47
+
48
+ it "should have a working valid? method" do
49
+ [["a", "a", ""], ["a", "a", nil], ["a", "a", "<tag>"], ["a", "a", " a"], ["a", "http://google.com", "a"], ["a", "http://google.com.torrent", "a"], ["a", "http://google.com", "a.torrent"]].each do |option|
50
+ option.permutation.to_a.uniq.each do |invalid|
51
+ create_torrent({details: invalid[0], torrent: invalid[1], title: invalid[2], tracker: 'the_pirate_bay'}).should_not be_valid
52
+ end
53
+ end
54
+
55
+ create_torrent({details: "http://google.com/123/", torrent: "http://google.com.torrent", title: "a", tracker: "the_pirate_bay"}).should be_valid
56
+ create_torrent({details: "http://google.com/random/", torrent: "http://google.com.torrent", title: "a", tracker: "the_pirate_bay"}).id.should eq(0)
57
+ end
58
+
59
+ it "should be dead" do
60
+ torrent = create_torrent({details: "a", torrent: "a", title: "a", tracker: "a"})
61
+ torrent.should_receive(:seeders).and_return(0)
62
+ torrent.should be_dead
63
+ end
64
+
65
+ it "should not be dead" do
66
+ torrent = create_torrent
67
+ torrent.should_receive(:seeders).and_return(1)
68
+ torrent.should_not be_dead
69
+ end
70
+
71
+ it "should return the right amount of seeders if it's nil" do
72
+ torrent = create_torrent
73
+ torrent.should_receive(:valid_option?).and_return(false)
74
+ torrent.seeders.should eq(1)
75
+ end
76
+
77
+ it "should return the right amount of seeders if it's set" do
78
+ torrent = create_torrent
79
+ torrent.should_receive(:inner_call).and_return(50)
80
+ torrent.seeders.should eq(50)
81
+ end
82
+
83
+ it "should be able to cache requests" do
84
+ torrent = create_torrent
85
+ torrent.should_receive(:download).exactly(1).times.and_return("")
86
+ 10.times { torrent.seeders }
87
+ end
88
+
89
+ it "should have a id method" do
90
+ torrent = create_torrent
91
+ torrent.id.should eq(6173093)
92
+ end
93
+
94
+ it "should have an id 0 if the details url is invalid" do
95
+ torrent = create_torrent({
96
+ details: "http://thepiratebay.org/torrent/random/",
97
+ torrent: "http://torrents.thepiratebay.org/6173093/value.torrent",
98
+ title: "The title",
99
+ tracker: "the_pirate_bay"
100
+ })
101
+
102
+ torrent.id.should eq(0)
103
+ end
104
+
105
+ it "should have a unique tid (torrent id)" do
106
+ torrents = create_torrents(100)
107
+
108
+ torrents.map!(&:tid)
109
+ lambda do
110
+ torrents.uniq!
111
+ end.should_not change(torrents, :count)
112
+ end
113
+
114
+ it "should have a torrent id method that equals the tid method" do
115
+ create_torrents(100).each do |torrent|
116
+ torrent.torrent_id.should eq(torrent.tid)
117
+ end
118
+ end
119
+
120
+ it "should have a working imdb method" do
121
+ rest_client
122
+
123
+ valid_url?(create_torrent.imdb).should be_true
124
+ create_torrent.imdb.should eq("http://www.imdb.com/title/tt0990407")
125
+ end
126
+
127
+ it "should have a working imdb_id method" do
128
+ rest_client
129
+
130
+ create_torrent.imdb_id.should eq("tt0990407")
131
+ end
132
+
133
+ it "should call the find_movie_by_id if a movie if found" do
134
+ rest_client
135
+ MovieSearcher.should_receive(:find_movie_by_id).with("tt0990407").and_return("123")
136
+
137
+ create_torrent.movie.should eq("123")
138
+ end
139
+
140
+ it "should call the find_by_release_name if no movie was found" do
141
+ torrent = create_torrent
142
+ torrent.should_receive(:imdb_id).and_return(nil)
143
+ torrent.should_receive(:title).and_return("my title")
144
+ MovieSearcher.should_receive(:find_by_release_name).with("my title", :options => {:details => true}).and_return("456")
145
+
146
+ torrent.movie.should eq("456")
147
+ end
148
+
149
+ context "the subtitle method" do
150
+ it "should have a working subtitle method, when a imdb id exists" do
151
+ torrent = create_torrent
152
+ torrent.should_receive(:imdb_id).at_least(1).times.and_return("tt0990407")
153
+ torrent.should_receive(:title).and_return("a subtitle")
154
+ Undertexter.should_receive(:find).with("tt0990407", language: :english).and_return([Struct.new(:title).new("a subtitle")])
155
+
156
+ torrent.subtitle.title.should eq("a subtitle")
157
+ end
158
+
159
+ it "should also work when the imdb_id is nil" do
160
+ torrent = create_torrent
161
+ torrent.should_receive(:imdb_id).at_least(1).times.and_return(nil)
162
+ torrent.subtitle.should be_nil
163
+ end
164
+
165
+ it "should be possible to pass arguments to subtitle" do
166
+ torrent = create_torrent
167
+ torrent.should_receive(:imdb_id).at_least(1).times.and_return("tt0990407")
168
+ torrent.should_receive(:title).and_return("a subtitle")
169
+ Undertexter.should_receive(:find).with("tt0990407", language: :swedish).and_return([Struct.new(:title).new("a subtitle")])
170
+
171
+ torrent.subtitle(:swedish).title.should eq("a subtitle")
172
+ end
173
+ end
174
+
175
+
176
+ it "should have a working title, even when the title is empty from the beginning" do
177
+ torrent = create_torrent
178
+ torrent.title.should eq("The title")
179
+ end
180
+
181
+ it "should have a working torrent method, even when the torrent is empty from the beginning " do
182
+ torrent = create_torrent
183
+ valid_url?(torrent.torrent).should be_true
184
+ torrent.torrent.match(/\.torrent$/)
185
+ end
186
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ describe Torrents do
4
+ def rest_client(url, type)
5
+ RestClient.should_receive(:get).with(url, {:timeout => 10, :cookies => nil}).any_number_of_times.and_return(File.read("spec/data/the_pirate_bay/#{type}.html"))
6
+ end
7
+
8
+ before(:each) do
9
+ @torrents = Torrents.the_pirate_bay
10
+ end
11
+
12
+ context "the exists? method" do
13
+ it "should know if a tracker exists or not" do
14
+ @torrents.exists?("the_pirate_bay").should be_true
15
+ @torrents.exists?("random").should be_false
16
+ end
17
+ end
18
+
19
+ context "the content method" do
20
+ it "should return a nokogiri object" do
21
+ @torrents.should_receive(:url).and_return("data")
22
+ @torrents.should_receive(:download).with("data").and_return("more data")
23
+ @torrents.content.should be_instance_of(Nokogiri::HTML::Document)
24
+ end
25
+ end
26
+
27
+ context "the inner_page method" do
28
+ it "should not care about the order of the page, high" do
29
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(10)
30
+ @torrents.page(1)
31
+ @torrents.inner_page.should eq("10")
32
+ end
33
+
34
+ it "should return the pre defined value" do
35
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(99)
36
+ @torrents.inner_page.should eq("99")
37
+ end
38
+
39
+ it "should not care about the order of the page, low" do
40
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(0)
41
+ @torrents.page(1)
42
+ @torrents.inner_page.should eq("0")
43
+ end
44
+
45
+ it "should not care about the order of the page, low again" do
46
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(1)
47
+ @torrents.page(1)
48
+ @torrents.inner_page.should eq("1")
49
+ end
50
+
51
+ it "should not care about the order of the page, if the page isn't specified, one" do
52
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(1)
53
+ @torrents.inner_page.should eq("1")
54
+ end
55
+
56
+ it "should not care about the order of the page, if the page isn't specified, high" do
57
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(10)
58
+ @torrents.inner_page.should eq("10")
59
+ end
60
+
61
+ it "should not care about the order of the page, if the page isn't specified, zero" do
62
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(0)
63
+ @torrents.inner_page.should eq("0")
64
+ end
65
+
66
+ it "should raise an exception if the page number is lower then 0" do
67
+ @torrents.should_receive(:inner_start_page_index).any_number_of_times.and_return(0)
68
+ lambda {
69
+ @torrents.page(0)
70
+ }.should raise_error(ArgumentError, "To low page value, remember that the first page has the value 1")
71
+ end
72
+ end
73
+
74
+ context "the url method" do
75
+ it "should return the correct url when the searching" do
76
+ @torrents.should_receive(:inner_page).and_return("3")
77
+ @torrents.search("search")
78
+ @torrents.should_receive(:send).and_return("before_<SEARCH>_middle_<PAGE>_after")
79
+ @torrents.url.should eq("before_search_middle_3_after")
80
+ end
81
+
82
+ it "should work when not searching" do
83
+ @torrents.should_receive(:inner_page).and_return("3")
84
+ @torrents.should_receive(:send).and_return("before_middle_<PAGE>_after")
85
+ @torrents.url.should eq("before_middle_3_after")
86
+ end
87
+
88
+ it "should be possible to list torrents based on a category" do
89
+ @torrents.category(:movies).page(100).url.should eq("http://thepiratebay.org/browse/201/99/3")
90
+ end
91
+
92
+ it "should raise an exception if trying to fetch a non existing category" do
93
+ lambda {
94
+ @torrents.category(:random).page(100).url
95
+ }.should raise_error(NotImplementedError)
96
+ end
97
+ end
98
+
99
+ context "the add, page, debugger, search method" do
100
+ it "add" do
101
+ @torrents.add("random").should be_instance_of(Torrents)
102
+ end
103
+
104
+ it "page" do
105
+ @torrents.page(10).should be_instance_of(Torrents)
106
+ end
107
+
108
+ it "debugger" do
109
+ @torrents.debugger(true).should be_instance_of(Torrents)
110
+ end
111
+
112
+ it "search" do
113
+ @torrents.search("value").should be_instance_of(Torrents)
114
+ end
115
+ end
116
+
117
+ context "the method_missing missing" do
118
+ before(:each) do
119
+ @torrent = mock(Object)
120
+ end
121
+
122
+ it "should call inner_call when calling method_missing" do
123
+ @torrents.should_receive(:inner_call).with(:example, "a").and_return("b")
124
+ @torrents.method_missing(:inner_example, "a").should eq("b")
125
+ end
126
+
127
+ it "should raise an exception" do
128
+ lambda {
129
+ @torrents.method_missing(:example, "a")
130
+ }.should raise_error(NoMethodError)
131
+ end
132
+
133
+ it "should also work with the static method" do
134
+ Torrents.should_receive(:new).and_return(@torrent)
135
+ @torrent.should_receive(:exists?).and_return(true)
136
+ @torrent.should_receive(:add).and_return("some")
137
+ Torrents.a_random_method.should eq("some")
138
+ end
139
+
140
+ it "should also raise an exception" do
141
+ Torrents.should_receive(:new).and_return(@torrent)
142
+ @torrent.should_receive(:exists?).and_return(false)
143
+ lambda {
144
+ Torrents.a_random_method
145
+ }.should raise_error(Exception)
146
+ end
147
+ end
148
+
149
+ context "the results method" do
150
+ def inner_torrents(times)
151
+ list = []
152
+ times.times {list << 1}
153
+ @torrents.should_receive(:inner_torrents).exactly(1).times.and_return(list)
154
+ end
155
+
156
+ def prepare
157
+ torrent = mock(Object)
158
+ inner_torrents(50)
159
+ Container::Torrent.should_receive(:new).any_number_of_times.and_return(torrent)
160
+ torrent.should_receive(:valid?).any_number_of_times.and_return(true)
161
+ end
162
+
163
+ before(:each) do
164
+ @torrents.should_receive(:content).and_return("")
165
+ end
166
+
167
+ it "should return an empty list" do
168
+ inner_torrents(0)
169
+ @torrents.results.should be_empty
170
+ end
171
+
172
+ it "should return a list with items" do
173
+ prepare
174
+ @torrents.should have(50).results
175
+ end
176
+
177
+ it "should be able to cache torrents" do
178
+ prepare
179
+ 5.times { @torrents.should have(50).results }
180
+ end
181
+ end
182
+
183
+ context "the cookies method" do
184
+ it "should be possible to pass some cookies" do
185
+ RestClient.should_receive(:get).with("http://thepiratebay.org/recent/0", {:timeout => 10, :cookies => {:session_id => "1234"}}).exactly(1).times.and_return("")
186
+ @torrents.cookies(:session_id => "1234").content
187
+ end
188
+ end
189
+
190
+ context "the find_by_details method" do
191
+ it "should be possible to add a details link and get appropriate data" do
192
+ rest_client("http://thepiratebay.org/torrent/6173093/", "details")
193
+ torrent = Torrents.the_pirate_bay.find_by_details("http://thepiratebay.org/torrent/6173093/")
194
+
195
+ # Makes sure that all methods returnes something
196
+ [:seeders, :title, :dead?, :imdb, :imdb_id, :domain, :id].each do |method|
197
+ torrent.send(method).to_s.should_not be_empty
198
+ end
199
+
200
+ torrent.should_not be_dead
201
+ torrent.seeders.should eq(9383)
202
+ torrent.tid.should_not be_empty
203
+ torrent.domain.should eq("thepiratebay.org")
204
+ end
205
+ end
206
+
207
+ context "the errors method" do
208
+ before(:each) do
209
+ rest_client("http://thepiratebay.org/recent/0", "recent")
210
+ end
211
+
212
+ it "should return the right error messages" do
213
+ errors = @torrents.errors
214
+
215
+ [
216
+ "An error occurred in the the_pirate_bay class at the details method.\n#<NoMethodError: undefined method `attr' for nil:NilClass>",
217
+ "An error occurred in the the_pirate_bay class at the title method.\n#<NoMethodError: undefined method `content' for nil:NilClass>",
218
+ "32 torrents where found, 2 where not valid"
219
+ ].each do |error|
220
+ errors.should include(error)
221
+ end
222
+ end
223
+
224
+ it "should not return any duplicates" do
225
+ errors = @torrents.errors
226
+ lambda do
227
+ errors.uniq!
228
+ end.should_not change(errors, :count)
229
+ end
230
+ end
231
+ end