john_stamos 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +132 -0
- data/Rakefile +1 -0
- data/john_stamos.gemspec +32 -0
- data/lib/john_stamos/client.rb +57 -0
- data/lib/john_stamos/pin.rb +78 -0
- data/lib/john_stamos/pin_search.rb +150 -0
- data/lib/john_stamos/pinner.rb +81 -0
- data/lib/john_stamos/version.rb +3 -0
- data/lib/john_stamos.rb +20 -0
- data/spec/lib/john_stamos/client_spec.rb +147 -0
- data/spec/lib/john_stamos/pin_search_spec.rb +298 -0
- data/spec/lib/john_stamos/pin_spec.rb +100 -0
- data/spec/lib/john_stamos/pinner_spec.rb +123 -0
- data/spec/lib/john_stamos_spec.rb +8 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/vcr_cassettes/JohnStamos_Client/_page_content/returns_a_Mechanize_Page.yml +221 -0
- data/spec/support/vcr_cassettes/JohnStamos_Client/_search_pins/returns_the_correct_number_of_pins.yml +1022 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/_pinner/returns_a_Pinner_object.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/_pinner/shows_my_fake_account_as_the_owning_Pinner.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/belongs_to_the_correct_board.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_description.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_image.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_like_count.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_repin_count.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/has_the_correct_source_url.yml +330 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pin/scraped_data/is_not_a_video.yml +329 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_higher_than_the_default/collects_the_correct_number_of_pin_ids.yml +2732 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_lower_than_the_default/collects_the_correct_number_of_pin_ids.yml +1199 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_a_limit_lower_than_the_default/never_calls_subsequent_retrieval_.yml +1199 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_no_limit_specified/limits_the_pin_ids_collected_to_50.yml +1697 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_execute_/when_using_a_search_term_that_yields_thousands_of_pins/with_no_limit_specified/limits_to_50_the_default.yml +1697 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark.yml +1035 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_50_results.yml +1035 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/with_results_found/should_set_pin_ids.yml +1035 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/without_any_results_found/has_a_nil_next_bookmark.yml +253 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_first_retrieval_/without_any_results_found/leaves_the_pin_ids_array_empty.yml +254 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_next_bookmark_with_a_hash_for_the_next_50_results.yml +1772 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/sets_the_next_bookmark.yml +1772 -0
- data/spec/support/vcr_cassettes/JohnStamos_PinSearch/_subsequent_retrieval/with_results_found/should_append_the_new_pin_ids.yml +1772 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_about/returns_the_correct_about_text.yml +287 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_avatar/returns_the_correct_avatar_URL.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_board_count/returns_the_correct_number_of_boards.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_follower_count/returns_a_follower_count_of_0.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_location/returns_the_correct_location.yml +287 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_pin_count/returns_the_correct_number_of_pins.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/_website_url/returns_the_correct_website_url.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_first_name.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_full_name.yml +286 -0
- data/spec/support/vcr_cassettes/JohnStamos_Pinner/name_related_attributes/returns_the_correct_last_name.yml +286 -0
- metadata +279 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe JohnStamos::Client, :vcr do
|
|
4
|
+
subject(:client) { JohnStamos::Client.new }
|
|
5
|
+
let(:pinterest_url) { 'https://pinterest.com' }
|
|
6
|
+
|
|
7
|
+
describe '#search_pins' do
|
|
8
|
+
it 'responds to #search_pins' do
|
|
9
|
+
expect(client).to respond_to(:search_pins)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'returns the correct number of pins' do
|
|
13
|
+
expect(client.search_pins('uncle jesse')).to have_exactly(50).pins
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#pin' do
|
|
18
|
+
it 'responds to #pin' do
|
|
19
|
+
expect(client).to respond_to(:pin)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'returns a Pin' do
|
|
23
|
+
expect(client.pin(412149803369441273)).to be_a(JohnStamos::Pin)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#pinner' do
|
|
28
|
+
it 'responds to #pinner' do
|
|
29
|
+
expect(client).to respond_to(:pinner)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'returns a Pinner' do
|
|
33
|
+
expect(client.pinner('johnstamosgem')).to be_a(JohnStamos::Pinner)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe '#proxy' do
|
|
38
|
+
it 'responds to #proxy' do
|
|
39
|
+
expect(client).to respond_to(:proxy)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'initializes w/ a nil proxy by default' do
|
|
43
|
+
expect(client.proxy).to be_nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'initializes the proxy attribute when constructed' do
|
|
47
|
+
client = JohnStamos::Client.new(proxy: 'test')
|
|
48
|
+
expect(client.proxy).to eq('test')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe '#json_content' do
|
|
53
|
+
it 'responds to #json_content' do
|
|
54
|
+
expect(client).to respond_to(:json_content)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'returns a Hash' do
|
|
58
|
+
RestClient.stub(:get).and_return('{"json":"json"}')
|
|
59
|
+
|
|
60
|
+
expect(client.json_content('url', 'params')).to be_a(Hash)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe '#mechanize_agent' do
|
|
65
|
+
let(:agent) { client.send(:mechanize_agent) }
|
|
66
|
+
|
|
67
|
+
context 'when using a proxy' do
|
|
68
|
+
before(:each) do
|
|
69
|
+
client.proxy = 'http://proxy.com:4747'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'sets the correct hostname' do
|
|
73
|
+
expect(agent.proxy_addr).to eq('proxy.com')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'sets the correct port' do
|
|
77
|
+
expect(agent.proxy_port).to eq(4747)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context 'when not using a proxy' do
|
|
82
|
+
before(:each) do
|
|
83
|
+
client.proxy = nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'does not set a hostname' do
|
|
87
|
+
expect(agent.proxy_addr).to be_nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'does not set a port' do
|
|
91
|
+
expect(agent.proxy_port).to be_nil
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe '#page_content' do
|
|
97
|
+
it 'responds to #page_content' do
|
|
98
|
+
expect(client).to respond_to(:page_content)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'returns a Mechanize::Page' do
|
|
102
|
+
expect(client.page_content(pinterest_url)).to be_a(Mechanize::Page)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe '#json_content' do
|
|
107
|
+
let(:fake_json) { '{"json":"json"}' }
|
|
108
|
+
|
|
109
|
+
it 'responds to #json_content' do
|
|
110
|
+
expect(client).to respond_to(:json_content)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'when not using a proxy' do
|
|
114
|
+
before(:each) do
|
|
115
|
+
allow(RestClient).to receive(:get).and_return(fake_json)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
let(:json_content) { client.json_content('url', 'params') }
|
|
119
|
+
|
|
120
|
+
it 'returns a Hash representation of the JSON' do
|
|
121
|
+
expect(json_content).to be_a(Hash)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'does not set RestClient proxy properties' do
|
|
125
|
+
json_content
|
|
126
|
+
expect(RestClient.proxy).to be_nil
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
context 'when using a proxy' do
|
|
131
|
+
let(:proxy) { 'http://proxy.com:31337' }
|
|
132
|
+
let(:proxy_client) { JohnStamos::Client.new({ proxy: proxy }) }
|
|
133
|
+
|
|
134
|
+
before(:each) do
|
|
135
|
+
allow(proxy_client).to receive(:proxy).and_return(proxy)
|
|
136
|
+
allow(RestClient).to receive(:get).and_return(fake_json)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'sets RestClient proxy properties' do
|
|
140
|
+
proxy_client.json_content('url', 'params')
|
|
141
|
+
expect(RestClient.proxy).to eq(proxy_client.proxy)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
describe JohnStamos::PinSearch, :vcr do
|
|
5
|
+
subject(:scraper) { JohnStamos::PinSearch.new(client) }
|
|
6
|
+
|
|
7
|
+
let(:client) { JohnStamos::Client.new }
|
|
8
|
+
let(:search_text) { "coffee roasting" }
|
|
9
|
+
|
|
10
|
+
it 'responds to #search_text' do
|
|
11
|
+
expect(scraper).to respond_to(:search_text)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'responds to #next_bookmark' do
|
|
15
|
+
expect(scraper).to respond_to(:next_bookmark)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'responds to #pin_ids' do
|
|
19
|
+
expect(scraper).to respond_to(:pin_ids)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'responds to #limit' do
|
|
23
|
+
expect(scraper).to respond_to(:limit)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'responds to #pins' do
|
|
27
|
+
expect(scraper).to respond_to(:pins)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'responds to #execute!' do
|
|
31
|
+
expect(scraper).to respond_to(:execute!)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'responds to #first_retrieval_url' do
|
|
35
|
+
expect(scraper).to respond_to(:first_retrieval_url)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'responds to #subsequent_retrieval_url' do
|
|
39
|
+
expect(scraper).to respond_to(:subsequent_retrieval_url)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'responds to #first_retrieval!' do
|
|
43
|
+
expect(scraper).to respond_to(:first_retrieval!)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'responds to #subsequent_retrieval!' do
|
|
47
|
+
expect(scraper).to respond_to(:subsequent_retrieval!)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'responds to #more_results?' do
|
|
51
|
+
expect(scraper).to respond_to(:more_results?)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'responds to #limit_reached?' do
|
|
55
|
+
expect(scraper).to respond_to(:limit_reached?)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
describe 'when initialized' do
|
|
60
|
+
it 'has no search query' do
|
|
61
|
+
expect(scraper.search_text).to be_nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'has no pin ids' do
|
|
65
|
+
expect(scraper.pin_ids).to be_empty
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'has no pins' do
|
|
69
|
+
expect(scraper.pins).to be_empty
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'has a nil next bookmark' do
|
|
73
|
+
expect(scraper.next_bookmark).to be_nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'has a limit of 50 by default' do
|
|
77
|
+
expect(scraper.limit).to eq(50)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '#first_retrieval_url' do
|
|
82
|
+
context 'search query not set' do
|
|
83
|
+
it 'raises an error' do
|
|
84
|
+
expect {
|
|
85
|
+
scraper.first_retrieval_url
|
|
86
|
+
}.to raise_error(JohnStamos::MissingSearchText)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'returns the correct URL with the search text URL encoded' do
|
|
91
|
+
scraper.search_text = search_text
|
|
92
|
+
expect(scraper.first_retrieval_url).to eq('http://pinterest.com/search/pins/?q=coffee%20roasting')
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe '#first_retrieval!' do
|
|
97
|
+
|
|
98
|
+
context 'with results found' do
|
|
99
|
+
before(:each){ scraper.search_text = search_text }
|
|
100
|
+
|
|
101
|
+
it 'sets next_bookmark' do
|
|
102
|
+
expect { scraper.first_retrieval! }.to change{ scraper.next_bookmark }.from(nil)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'sets next_bookmark with a hash for the next 50 results' do
|
|
106
|
+
scraper.first_retrieval!
|
|
107
|
+
decrypted_hash = Base64.strict_decode64(scraper.next_bookmark)
|
|
108
|
+
next_page_results_start_position = decrypted_hash.split('|')[0]
|
|
109
|
+
next_page_results_start_position.should eq("oo50")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'should set pin_ids' do
|
|
113
|
+
expect { scraper.first_retrieval! }.to change{ scraper.pin_ids.length }.from(0).to(50)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context 'without any results found' do
|
|
118
|
+
before(:each) do
|
|
119
|
+
scraper.search_text = "ThisWillNeverBeFoundLOLAmIRiteYeahYoureRite"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'has a nil next_bookmark' do
|
|
123
|
+
scraper.first_retrieval!
|
|
124
|
+
expect(scraper.next_bookmark).to eq('-end-')
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'leaves the pin_ids array empty' do
|
|
128
|
+
scraper.first_retrieval!
|
|
129
|
+
expect(scraper.pin_ids).to be_empty
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
describe '#subsequent_retrieval_url' do
|
|
135
|
+
it 'returns the correct "resource" url' do
|
|
136
|
+
expect(scraper.subsequent_retrieval_url).to eq('http://pinterest.com/resource/SearchResource/get/')
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
describe '#subsequent_retrieval' do
|
|
141
|
+
it 'raises an error if there next_bookmark is not set' do
|
|
142
|
+
expect {
|
|
143
|
+
scraper.search_text = "bogus search text"
|
|
144
|
+
scraper.subsequent_retrieval!
|
|
145
|
+
}.to raise_error(JohnStamos::MissingNextBookmark)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'raises an error if search_text is not set' do
|
|
149
|
+
expect {
|
|
150
|
+
scraper.next_bookmark = "bogus next bookmark"
|
|
151
|
+
scraper.subsequent_retrieval!
|
|
152
|
+
}.to raise_error(JohnStamos::MissingSearchText)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
context 'with results found' do
|
|
156
|
+
before(:each) do
|
|
157
|
+
scraper.search_text = 'coffee'
|
|
158
|
+
scraper.limit = 100
|
|
159
|
+
scraper.first_retrieval!
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'sets the next_bookmark' do
|
|
163
|
+
expect { scraper.subsequent_retrieval! }.to change{ scraper.next_bookmark }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'sets next_bookmark with a hash for the next 50 results' do
|
|
167
|
+
scraper.subsequent_retrieval!
|
|
168
|
+
decrypted_hash = Base64.strict_decode64(scraper.next_bookmark)
|
|
169
|
+
next_page_results_start_position = decrypted_hash.split('|')[0]
|
|
170
|
+
expect(next_page_results_start_position).to eq("oo100")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it 'should append the new pin_ids' do
|
|
174
|
+
# The expected count can change based on Pinterest. Sometimes they give 99, sometimes 100.
|
|
175
|
+
# When you update the VCR cassettes it may cause this test to fail... please update it.
|
|
176
|
+
scraper.subsequent_retrieval!
|
|
177
|
+
expect(scraper.pin_ids.length).to eq(100)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe '#more_results?' do
|
|
183
|
+
context 'when there are more results' do
|
|
184
|
+
before(:each) { scraper.next_bookmark = "some bogus bookmark" }
|
|
185
|
+
|
|
186
|
+
it 'returns true' do
|
|
187
|
+
expect(scraper.more_results?).to be_true
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
context 'when there are no more results' do
|
|
192
|
+
before(:each) { scraper.next_bookmark = "-end-" }
|
|
193
|
+
|
|
194
|
+
it 'returns false' do
|
|
195
|
+
expect(scraper.more_results?).to be_false
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context 'when next_bookmark is nil' do
|
|
200
|
+
it 'raises a MissingNextBookmark error' do
|
|
201
|
+
expect {
|
|
202
|
+
scraper.more_results?
|
|
203
|
+
}.to raise_error(JohnStamos::MissingNextBookmark)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe '#limit_reached?' do
|
|
209
|
+
context 'when the default limit of 50 has not been reached' do
|
|
210
|
+
before(:each) { scraper.pin_ids = Array.new(49) }
|
|
211
|
+
|
|
212
|
+
it 'returns false' do
|
|
213
|
+
expect(scraper.limit_reached?).to be_false
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
context 'when default limit of 50 has been reached' do
|
|
218
|
+
before(:each) { scraper.pin_ids = Array.new(50) }
|
|
219
|
+
|
|
220
|
+
it 'returns true' do
|
|
221
|
+
expect(scraper.limit_reached?).to be_true
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
describe '#execute!' do
|
|
227
|
+
|
|
228
|
+
context 'search query not set' do
|
|
229
|
+
it 'raises an error' do
|
|
230
|
+
expect {
|
|
231
|
+
scraper.execute!
|
|
232
|
+
}.to raise_error(JohnStamos::MissingSearchText)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
context 'when using a search term that yields thousands of pins' do
|
|
237
|
+
let(:big_search_term) { "funny" }
|
|
238
|
+
|
|
239
|
+
context 'with no limit specified' do
|
|
240
|
+
subject(:big_scraper) { JohnStamos::PinSearch.new(client, big_search_term) }
|
|
241
|
+
|
|
242
|
+
it 'limits to 50, the default' do
|
|
243
|
+
big_scraper.execute!
|
|
244
|
+
expect(big_scraper.limit).to eq(50)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it 'limits the pin_ids collected to 50' do
|
|
248
|
+
big_scraper.execute!
|
|
249
|
+
expect(big_scraper.pin_ids.length).to eq(50)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
context 'with a limit lower than the default' do
|
|
254
|
+
subject(:big_scraper_with_small_limit) { JohnStamos::PinSearch.new(client, big_search_term, { limit: 10 }) }
|
|
255
|
+
|
|
256
|
+
it 'limits to 10' do
|
|
257
|
+
expect(big_scraper_with_small_limit.limit).to eq(10)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it 'never calls #subsequent_retrieval!' do
|
|
261
|
+
expect(big_scraper_with_small_limit).to_not receive(:subsequent_retrieval!).with()
|
|
262
|
+
big_scraper_with_small_limit.execute!
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it 'collects the correct number of pin_ids' do
|
|
266
|
+
big_scraper_with_small_limit.execute!
|
|
267
|
+
expect(big_scraper_with_small_limit.pin_ids.length).to eq(10)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
context 'with a limit higher than the default' do
|
|
272
|
+
subject(:big_scraper_with_limit) { JohnStamos::PinSearch.new(client, big_search_term, { limit: 147 }) }
|
|
273
|
+
|
|
274
|
+
it 'limits to 147' do
|
|
275
|
+
expect(big_scraper_with_limit.limit).to eq(147)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'collects the correct number of pin_ids' do
|
|
279
|
+
expect{ big_scraper_with_limit.execute! }.to change{ big_scraper_with_limit.pin_ids.length }.from(0).to(147)
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
describe '#pins' do
|
|
287
|
+
let(:bogus_pinterest_ids) { [1,2] }
|
|
288
|
+
before(:each) { scraper.pin_ids = bogus_pinterest_ids }
|
|
289
|
+
|
|
290
|
+
it 'returns an Array' do
|
|
291
|
+
expect(scraper.pins).to be_a(Array)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it 'contains 50 pins' do
|
|
295
|
+
expect(scraper.pins).to have_exactly(bogus_pinterest_ids.length).pins
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe JohnStamos::Pin do
|
|
4
|
+
subject(:pin) do
|
|
5
|
+
# Test pin from here: http://pinterest.com/pin/412149803369441273/
|
|
6
|
+
JohnStamos::Pin.new(client, pinterest_pin_id)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
let(:pinterest_pin_id) { 412149803369441273 }
|
|
10
|
+
let(:client) { JohnStamos::Client.new }
|
|
11
|
+
|
|
12
|
+
it 'responds to #id' do
|
|
13
|
+
expect(pin).to respond_to(:id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'has the correct id' do
|
|
17
|
+
expect(pin.id).to eq(pinterest_pin_id)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'responds to #image' do
|
|
21
|
+
expect(pin).to respond_to(:image)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'responds to #description' do
|
|
25
|
+
expect(pin).to respond_to(:description)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'responds to #pinner' do
|
|
29
|
+
expect(pin).to respond_to(:pinner)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'responds to #board' do
|
|
33
|
+
expect(pin).to respond_to(:board)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'responds to #like_count' do
|
|
37
|
+
expect(pin).to respond_to(:like_count)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'responds to #repin_count' do
|
|
41
|
+
expect(pin).to respond_to(:repin_count)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'responds to #source_url' do
|
|
45
|
+
expect(pin).to respond_to(:source_url)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'responds to #url' do
|
|
49
|
+
expect(pin).to respond_to(:url)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'has the correct url' do
|
|
53
|
+
expect(pin.url).to eq("http://pinterest.com/pin/#{pinterest_pin_id}/")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'responds to #video?' do
|
|
57
|
+
expect(pin).to respond_to(:video?)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe 'scraped data', :vcr do
|
|
61
|
+
it 'has the correct image' do
|
|
62
|
+
expect(pin.image).to eq('http://media-cache-ak0.pinimg.com/originals/ee/39/6e/ee396ebad5cffd3f8f6e83b5fd9f07cb.jpg')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'has the correct description' do
|
|
66
|
+
expect(pin.description).to eq('JohnStamosgemPin description')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'belongs to the correct board' do
|
|
70
|
+
expect(pin.board).to eq('/johnstamosgem/johnstamosgemboard/')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'has the correct like_count' do
|
|
74
|
+
expect(pin.like_count).to eq(1)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'has the correct repin_count' do
|
|
78
|
+
expect(pin.repin_count).to eq(0)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'has the correct source_url' do
|
|
82
|
+
expect(pin.source_url).to eq('http://johnstamosgem.com/')
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'is not a video' do
|
|
86
|
+
expect(pin.video?).to be_false
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe '#pinner' do
|
|
90
|
+
it 'returns a Pinner object' do
|
|
91
|
+
expect(pin.pinner).to be_a(JohnStamos::Pinner)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'shows my fake account as the owning Pinner' do
|
|
95
|
+
expect(pin.pinner.username).to eq('johnstamosgem')
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe JohnStamos::Pinner, :vcr do
|
|
4
|
+
let(:client) { JohnStamos::Client.new }
|
|
5
|
+
let(:pinterest_user) { 'johnstamosgem' } # Test user account from here: http://pinterest.com/johnstamosgem/
|
|
6
|
+
|
|
7
|
+
subject(:pinner) { JohnStamos::Pinner.new(client, pinterest_user) }
|
|
8
|
+
|
|
9
|
+
describe '#username' do
|
|
10
|
+
it 'responds to #username' do
|
|
11
|
+
expect(pinner).to respond_to(:username)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'returns the correct pinterest username' do
|
|
15
|
+
expect(pinner.username).to eq(pinterest_user)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#url' do
|
|
20
|
+
it 'responds to #url' do
|
|
21
|
+
expect(pinner).to respond_to(:url)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'returns the correct url for the pinner' do
|
|
25
|
+
expect(pinner.url).to eq("http://pinterest.com/#{pinterest_user}/")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#pin_count' do
|
|
30
|
+
it 'responds to #pin_count' do
|
|
31
|
+
expect(pinner).to respond_to(:pin_count)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'returns the correct number of pins' do
|
|
35
|
+
expect(pinner.pin_count).to eq(1)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe '#about' do
|
|
40
|
+
it 'responds to #about' do
|
|
41
|
+
expect(pinner).to respond_to(:about)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'returns the correct about text' do
|
|
45
|
+
expect(pinner.about).to eq('This is the johnstamos about content.')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe '#follower_count' do
|
|
50
|
+
it 'responds to #follower_count' do
|
|
51
|
+
expect(pinner).to respond_to(:follower_count)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'returns a follower count of 0' do
|
|
55
|
+
expect(pinner.follower_count).to eq(0) # :( I have no friends.
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#avatar' do
|
|
60
|
+
it 'responds to #avatar' do
|
|
61
|
+
expect(pinner).to respond_to(:avatar)
|
|
62
|
+
end
|
|
63
|
+
it 'returns the correct avatar URL' do
|
|
64
|
+
expect(pinner.avatar).to eq('http://media-cache-ec0.pinimg.com/avatars/johnstamosgem_1375988759_140.jpg')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe 'name related attributes' do
|
|
69
|
+
it 'responds to #first_name' do
|
|
70
|
+
expect(pinner).to respond_to(:first_name)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'responds to #last_name' do
|
|
74
|
+
expect(pinner).to respond_to(:last_name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'responds to #full_name' do
|
|
78
|
+
expect(pinner).to respond_to(:full_name)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'returns the correct first name' do
|
|
82
|
+
expect(pinner.first_name).to eq('John')
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'returns the correct last name' do
|
|
86
|
+
expect(pinner.last_name).to eq('Stamosgem')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'returns the correct full name' do
|
|
90
|
+
expect(pinner.full_name).to eq('John Stamosgem')
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe '#board_count' do
|
|
95
|
+
it 'responds to #board_count' do
|
|
96
|
+
expect(pinner).to respond_to(:board_count)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'returns the correct number of boards' do
|
|
100
|
+
expect(pinner.board_count).to eq(1)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe '#website_url' do
|
|
105
|
+
it 'responds to #website_url' do
|
|
106
|
+
expect(pinner).to respond_to(:website_url)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'returns the correct website url' do
|
|
110
|
+
expect(pinner.website_url).to eq('http://johnstamos.com/')
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe '#location' do
|
|
115
|
+
it 'responds to #location' do
|
|
116
|
+
expect(pinner).to respond_to(:location)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'returns the correct location' do
|
|
120
|
+
expect(pinner.location).to eq('California')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'john_stamos'
|
|
2
|
+
require 'john_stamos/pin_search'
|
|
3
|
+
require 'john_stamos/pin'
|
|
4
|
+
require 'john_stamos/pinner'
|
|
5
|
+
require 'john_stamos/client'
|
|
6
|
+
require 'vcr'
|
|
7
|
+
|
|
8
|
+
VCR.configure do |c|
|
|
9
|
+
c.cassette_library_dir = 'spec/support/vcr_cassettes'
|
|
10
|
+
c.hook_into :webmock
|
|
11
|
+
c.default_cassette_options = { :record => :new_episodes }
|
|
12
|
+
c.configure_rspec_metadata!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
RSpec.configure do |config|
|
|
16
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
17
|
+
config.run_all_when_everything_filtered = true
|
|
18
|
+
config.order = 'random'
|
|
19
|
+
|
|
20
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
|
21
|
+
end
|