croudia 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +29 -0
  5. data/Rakefile +2 -0
  6. data/croudia.gemspec +21 -0
  7. data/lib/croudia/api.rb +5 -0
  8. data/lib/croudia/identity.rb +39 -0
  9. data/lib/croudia/scraper/friendships.rb +33 -0
  10. data/lib/croudia/scraper/login.rb +40 -0
  11. data/lib/croudia/scraper/parser/users.rb +53 -0
  12. data/lib/croudia/scraper/parser/voices.rb +32 -0
  13. data/lib/croudia/scraper/parser.rb +13 -0
  14. data/lib/croudia/scraper/users.rb +20 -0
  15. data/lib/croudia/scraper/voices.rb +27 -0
  16. data/lib/croudia/scraper.rb +62 -0
  17. data/lib/croudia/user.rb +43 -0
  18. data/lib/croudia/version.rb +3 -0
  19. data/lib/croudia/voice.rb +21 -0
  20. data/lib/croudia.rb +23 -0
  21. data/spec/croudia/api_spec.rb +7 -0
  22. data/spec/croudia/identity_spec.rb +65 -0
  23. data/spec/croudia/scraper/friendships_spec.rb +61 -0
  24. data/spec/croudia/scraper/login_spec.rb +135 -0
  25. data/spec/croudia/scraper/parser/users_spec.rb +256 -0
  26. data/spec/croudia/scraper/parser/voices_spec.rb +119 -0
  27. data/spec/croudia/scraper/users_spec.rb +74 -0
  28. data/spec/croudia/scraper/voices_spec.rb +92 -0
  29. data/spec/croudia/scraper_spec.rb +120 -0
  30. data/spec/croudia/user_spec.rb +43 -0
  31. data/spec/croudia/version_spec.rb +7 -0
  32. data/spec/croudia/voice_spec.rb +16 -0
  33. data/spec/croudia_spec.rb +49 -0
  34. data/spec/fixtures/follower_wktk.html +89 -0
  35. data/spec/fixtures/following_wktk.html +89 -0
  36. data/spec/fixtures/user_wktk1.html +72 -0
  37. data/spec/fixtures/user_wktk2.html +75 -0
  38. data/spec/fixtures/user_wktk3.html +83 -0
  39. data/spec/fixtures/voices_reply_list.html +55 -0
  40. data/spec/fixtures/voices_timeline.html +60 -0
  41. data/spec/fixtures/voices_written.html +20 -0
  42. data/spec/helper.rb +32 -0
  43. metadata +157 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in croudia.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 wktk
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Croudia
2
+
3
+ A Mechanize-based Ruby scraper for [Croudia](https://croudia.com)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'croudia'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install croudia
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/croudia.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/croudia/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['wktk']
6
+ gem.email = ['wktk@wktk.in']
7
+ gem.description = 'A Mechanize-based Ruby scraper for Croudia'
8
+ gem.summary = gem.description
9
+ gem.homepage = 'https://github.com/wktk/croudia-gem'
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = 'croudia'
15
+ gem.require_paths = ['lib']
16
+ gem.version = Croudia::VERSION
17
+
18
+ gem.add_dependency 'mechanize', '~> 2.5.1'
19
+ gem.add_development_dependency 'rspec', '~> 2.10.1'
20
+ gem.add_development_dependency 'webmock', '~> 1.8.7'
21
+ end
@@ -0,0 +1,5 @@
1
+ module Croudia
2
+ module API
3
+ # Fingers crossed they will soon release their own ( '-^)b
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ module Croudia
2
+ class Identity
3
+ attr_reader :id, :time
4
+ alias id_str id
5
+ alias created_at time
6
+
7
+ def initialize(attrs)
8
+ attrs.keys.each do |key|
9
+ if 'time' == key.to_s && !attrs[key].is_a?(Time)
10
+ if /^\d+$/ =~ attrs[key]
11
+ attrs[key] = Time.at(attrs[key].to_i)
12
+ else
13
+ attrs[key] = Time.new(*attrs[key].split(/\D/))
14
+ end
15
+ elsif /_count$/ =~ key.to_s
16
+ attrs[key] = attrs[key].to_i
17
+ end
18
+
19
+ instance_variable_set(:"@#{key}", attrs[key])
20
+ end
21
+ end
22
+
23
+ def ==(other)
24
+ super || self.class == other.class && @id == other.id
25
+ end
26
+
27
+ def [](name)
28
+ instance_variable_get(:"@#{name}")
29
+ end
30
+
31
+ def id
32
+ @id
33
+ end
34
+
35
+ def method_missing(name, *args)
36
+ self[name]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Friendships
4
+ def follow(username)
5
+ require_login
6
+ post('/follows/target_follow',
7
+ :target_user_name => username,
8
+ :follow_action => 'enable',
9
+ )
10
+ end
11
+
12
+ def unfollow(username)
13
+ require_login
14
+ post('/follows/target_follow',
15
+ :target_user_name => username,
16
+ :follow_action => 'diable', # Yes, it is!
17
+ )
18
+ end
19
+
20
+ def following(username=nil, params={})
21
+ username = @current_user.username unless username
22
+ Parser.user_list(get("/follows/following/#{username}", params))
23
+ end
24
+ alias followings following
25
+
26
+ def follower(username=nil, params={})
27
+ username = @current_user.username unless username
28
+ Parser.user_list(get("/follows/follower/#{username}", params))
29
+ end
30
+ alias followers follower
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Login
4
+ def login(username, password)
5
+ get('/')
6
+ params = {
7
+ :username => username,
8
+ :password => password,
9
+ :auto_login => 'on',
10
+ }
11
+ post('/', params)
12
+ raise ArgumentError, 'Wrong ID or password' if not logged_in?
13
+ end
14
+ alias login! login
15
+
16
+ def logout
17
+ require_login
18
+ post('/login/logout', :method_name => 'logout')
19
+ @current_user = nil
20
+ @logged_in = false
21
+ end
22
+ alias logout! logout
23
+
24
+ def logged_in?(force=false)
25
+ @logged_in = nil if force
26
+ @logged_in = @logged_in.nil? ? '/' != get('/').uri.path : @logged_in
27
+ end
28
+ alias logged_in logged_in?
29
+
30
+ def logged_out?(force=false)
31
+ !logged_in?(force)
32
+ end
33
+ alias logged_out logged_out?
34
+
35
+ def require_login
36
+ raise 'Not logged in' if logged_out?
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,53 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Parser
4
+ module Users
5
+ def user_page(page)
6
+ return nil if /on Croudia$/ !~ page.title
7
+ doc = page.parser
8
+ attrs = {
9
+ :username => doc.xpath('//a[contains(@href, "/voices/user/")]').first.attribute('href').content.sub(%r{^/voices/user/}, ''),
10
+ :nickname => doc.css('.avatar_l').first.attribute('alt').content,
11
+ :avatar => "#{page.uri.scheme}://#{page.uri.host}" + doc.css('.avatar_l').first.attribute('src').content,
12
+ :self_introduction => doc.css('.fontg').first.content.strip,
13
+ :voices_count => doc.xpath('//span[preceding-sibling::a[contains(@href,"/voices/user/")]]').first.content,
14
+ :following_count => doc.xpath('//span[preceding-sibling::a[contains(@href,"/following/")]]').first.content,
15
+ :followers_count => doc.xpath('//span[preceding-sibling::a[contains(@href,"/follower/")]]').first.content,
16
+ :album_count => doc.xpath('//span[preceding-sibling::a[contains(@href,"/album")]]').first.content,
17
+ :spreadia => doc.xpath('//span[preceding-sibling::a[contains(@href,"/spreadia/")]]').first.content,
18
+ :favodia => doc.xpath('//span[preceding-sibling::a[contains(@href,"/favodia/")]]').first.content,
19
+ }
20
+ if (location = doc.xpath('//a[contains(@href, "/users/google_maps")]')).size.nonzero?
21
+ attrs[:position] = location.first.content
22
+ end
23
+ if (url = doc.xpath('//a[@target="_blank"][name(..)="li"]')).size.nonzero?
24
+ attrs[:user_url] = url.first.content
25
+ end
26
+ if (friendships = doc.css('.font1')).size.nonzero?
27
+ attrs[:following] = /#e/i !~ friendships[0].attribute('style').value
28
+ attrs[:followed_by] = /#e/i !~ friendships[1].attribute('style').value
29
+ end
30
+ Croudia::User.new(attrs)
31
+ end
32
+
33
+ def user_list(page, klass=Croudia::User)
34
+ user_nodes = page.parser.xpath('//div[@data-role="content"]/ul[@data-role="listview"]/li[child::a]')
35
+ users = []
36
+ user_nodes.map do |user_node|
37
+ attrs = {
38
+ :username => user_node.css('a').first.attribute('href').value.sub(%r{^/}, ''),
39
+ :nickname => user_node.css('.bord').first.content,
40
+ :avatar => "#{page.uri.scheme}://#{page.uri.host}" + user_node.css('img').first.attribute('src').value,
41
+ :self_introduction => user_node.css('.fontg').first.content.strip,
42
+ }
43
+ if (following = user_node.css('.font1')).size.nonzero?
44
+ attrs[:following] = /#e/i !~ following.first.attribute('style').value
45
+ end
46
+ users << Croudia::User.new(attrs)
47
+ end
48
+ users
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Parser
4
+ module Voices
5
+ def voices(page)
6
+ voice_nodes = page.parser.xpath('//div[@data-role="content"]/ul[@data-role="listview"]/li[child::a]')
7
+ voices = []
8
+ voice_nodes.each do |voice|
9
+ user = Croudia::User.new(
10
+ :username => voice.xpath('//a[parent::span[@class="test_span"]]').first.attribute('href').value.gsub(/\W/, ''),
11
+ :nickname => voice.xpath('//span[@class="bord"][parent::p]').first.content,
12
+ :avatar => "#{page.uri.scheme}://#{page.uri.host}" + voice.xpath('//img[@class="avatar"]').attribute('src').value,
13
+ )
14
+ attrs = {
15
+ :id => voice.xpath('//a[contains(@href,"/voices/show/")]').first.attribute('href').value.gsub(/\D/, ''),
16
+ :user => user,
17
+ :voice_desc => voice.css('.voice_desc').first.content,
18
+ :spreaded_count => voice.xpath('//span[contains(@style,"#396")]').first.content.gsub(/\D/, ''),
19
+ :favorited_count => voice.xpath('//span[contains(@style,"520")]').first.content.gsub(/\D/, ''),
20
+ }
21
+ if (time = voice.xpath('//p[@data-time]')).size.nonzero?
22
+ # For timeline
23
+ attrs[:time] = time.first.attribute('data-time').value
24
+ end
25
+ voices << Croudia::Voice.new(attrs)
26
+ end
27
+ voices
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,13 @@
1
+ require 'croudia/scraper/parser/users'
2
+ require 'croudia/scraper/parser/voices'
3
+
4
+ module Croudia
5
+ class Scraper
6
+ module Parser
7
+ class << self
8
+ include Croudia::Scraper::Parser::Users
9
+ include Croudia::Scraper::Parser::Voices
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Users
4
+ def current_user(force=false)
5
+ require_login
6
+ @current_user = nil if force
7
+ @current_user ||= Parser.user_page(get('/users/redirect_user'))
8
+ end
9
+ alias verify_credentials current_user
10
+
11
+ def user(username=nil, params={})
12
+ if username
13
+ Parser.user_page(get("/#{username}", params))
14
+ else
15
+ current_user
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module Croudia
2
+ class Scraper
3
+ module Voices
4
+ def timeline(params={})
5
+ require_login
6
+ Parser.voices(get('/voices/timeline', params))
7
+ end
8
+ alias home_timeline timeline
9
+
10
+ def reply_list(params={})
11
+ require_login
12
+ Parser.voices(get('/voices/reply_list', params))
13
+ end
14
+ alias mentions reply_list
15
+ alias mentions_timeline reply_list
16
+
17
+ def update(text)
18
+ require_login
19
+ page = get('/voices/written')
20
+ form = page.form_with(:action => '/voices/write')
21
+ form['voice[tweet]'] = text
22
+ result = form.submit
23
+ raise 'Update failed' if result.body.include? 'error_popup'
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,62 @@
1
+ require 'croudia/scraper/friendships'
2
+ require 'croudia/scraper/login'
3
+ require 'croudia/scraper/parser'
4
+ require 'croudia/scraper/users'
5
+ require 'croudia/scraper/voices'
6
+ require 'croudia/user'
7
+ require 'croudia/version'
8
+ require 'croudia/voice'
9
+ require 'mechanize'
10
+
11
+ module Croudia
12
+ class Scraper
13
+ include Croudia::Scraper::Friendships
14
+ include Croudia::Scraper::Login
15
+ include Croudia::Scraper::Users
16
+ include Croudia::Scraper::Voices
17
+
18
+ attr_accessor :agent, :endpoint
19
+
20
+ def initialize(username=nil, password=nil)
21
+ yield self if block_given?
22
+
23
+ @endpoint ||= 'https://croudia.com'
24
+ @user_agent ||= "The Croudia Gem/#{Croudia::VERSION} (https://github.com/wktk/croudia-gem)"
25
+ @agent ||= Mechanize.new do |s|
26
+ s.verify_mode = OpenSSL::SSL::VERIFY_NONE
27
+ end
28
+ self.user_agent = @user_agent
29
+
30
+ username && password && login(username, password)
31
+ end
32
+
33
+ def user_agent
34
+ @agent.user_agent
35
+ end
36
+
37
+ def user_agent=(ua)
38
+ unless @agent
39
+ @user_agent = ua
40
+ else
41
+ @agent.user_agent = ua
42
+ end
43
+ end
44
+
45
+ def get(path, params={})
46
+ pick_token(@agent.get(@endpoint + path, params))
47
+ end
48
+
49
+ def post(path, params={})
50
+ params = { :authenticity_token => @authenticity_token }.merge(params)
51
+ pick_token(@agent.post(@endpoint + path, params))
52
+ end
53
+
54
+ private
55
+ def pick_token(page)
56
+ page.respond_to?('parser') &&
57
+ (token = page.parser.xpath('//meta[@name="csrf-token"]')).size.nonzero? &&
58
+ @authenticity_token = token.first.attribute('content').content
59
+ page
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,43 @@
1
+ require 'croudia/identity'
2
+
3
+ module Croudia
4
+ class User < Croudia::Identity
5
+ attr_reader :username, :nickname, :avatar, :self_introduction,
6
+ :voices_count, :following_count, :followers_count, :album_count,
7
+ :position, :user_url, :spreadia, :favodia,
8
+ :following, :followed_by
9
+ alias handle username
10
+ alias screen_name username
11
+ alias user_name username
12
+ alias name nickname
13
+ alias profile_image avatar
14
+ alias description self_introduction
15
+ alias voice_count voices_count
16
+ alias statuses_count voices_count
17
+ alias status_count voices_count
18
+ alias updates_count voices_count
19
+ alias update_count voices_count
20
+ alias followings_count following_count
21
+ alias friends_count following_count
22
+ alias friend_count following_count
23
+ alias follower_count followers_count
24
+ alias location position
25
+ alias url user_url
26
+ alias favorited_count favodia
27
+ alias favourited_count favodia
28
+ alias spreaded_count spreadia
29
+ alias following? following
30
+ alias followed_by? followed_by
31
+
32
+ def initialize(*args)
33
+ super
34
+ @id = @username
35
+ @spreadia = @spreadia.to_i if @spreadia
36
+ @favodia = @favodia.to_i if @favodia
37
+ end
38
+
39
+ def to_s
40
+ @username
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,3 @@
1
+ module Croudia
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,21 @@
1
+ require 'croudia/identity'
2
+
3
+ module Croudia
4
+ class Voice < Croudia::Identity
5
+ attr_reader :user, :voice_desc, :spreaded_count, :favorited_count, :time
6
+ alias from_user user
7
+ alias text voice_desc
8
+ alias description voice_desc
9
+ alias desc voice_desc
10
+ alias spread_count spreaded_count
11
+ alias favorite_count favorited_count
12
+
13
+ def to_s
14
+ "@#{@user.username}: #{@desc}"
15
+ end
16
+
17
+ def to_i
18
+ @id.to_i
19
+ end
20
+ end
21
+ end
data/lib/croudia.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'croudia/scraper'
2
+
3
+ module Croudia
4
+ class << self
5
+ # Delegate to Croudia::Scraper.new
6
+ #
7
+ # @return [Croudia::Scraper]
8
+ def scraper(*args, &block)
9
+ Croudia::Scraper.new(*args, &block)
10
+ end
11
+ alias new scraper
12
+ alias client scraper
13
+
14
+ def method_missing(name, *args, &block)
15
+ return super unless scraper.respond_to?(name)
16
+ scraper.send(name, *args, &block)
17
+ end
18
+
19
+ def respond_to?(name)
20
+ scraper.respond_to?(name) || super
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ require 'croudia/api'
2
+
3
+ describe Croudia::API do
4
+ it 'is a Module' do
5
+ Croudia::API.should be_a Module
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Identity do
4
+ describe '#initialize' do
5
+ it 'sets arguments as instance variables' do
6
+ Croudia::Identity.new(:hello => 'hi').instance_variable_get('@hello').should eq 'hi'
7
+ end
8
+
9
+ it 'converts a Unix time attribution named time to a Time object' do
10
+ Croudia::Identity.new(:time => '1234567890').time.should be_a Time
11
+ end
12
+
13
+ it 'converts a date string named time to a Time object' do
14
+ Croudia::Identity.new(:time => '2013-01-01 11:55').time.should be_a Time
15
+ end
16
+
17
+ it 'converts *_count into an Integer' do
18
+ Croudia::Identity.new(:foo_count => '2012').foo_count.should eq 2012
19
+ end
20
+ end
21
+
22
+ describe '#==' do
23
+ it 'returns true when IDs match' do
24
+ obj1 = Croudia::Identity.new(:id => '1', :username => 'wktk')
25
+ obj2 = Croudia::Identity.new(:id => '1', :username => 'croudia')
26
+ (obj1 == obj2).should be_true
27
+ end
28
+
29
+ it 'returns false when IDs do not match' do
30
+ obj1 = Croudia::Identity.new(:id => '1', :username => 'wktk')
31
+ obj2 = Croudia::Identity.new(:id => '2', :username => 'wktk')
32
+ (obj1 == obj2).should be_false
33
+ end
34
+
35
+ it 'returns false when classes do not match' do
36
+ obj1 = Croudia::Identity.new(:id => '1')
37
+ obj2 = { :id => '1' }
38
+ (obj1 == obj2).should be_false
39
+ end
40
+ end
41
+
42
+ describe '#[]' do
43
+ it 'returns the same name instance variable' do
44
+ Croudia::Identity.new(:foo => 'bar')[:foo].should eq 'bar'
45
+ end
46
+ end
47
+
48
+ describe '#id' do
49
+ it 'returns @id, not object_id' do
50
+ identity = Croudia::Identity.new(:id => '1')
51
+ identity.id.should_not eq identity.object_id
52
+ identity.id.should eq identity.instance_variable_get('@id')
53
+ end
54
+ end
55
+
56
+ describe '#method_missing' do
57
+ it 'returns the same name instance variable if set' do
58
+ Croudia::Identity.new(:foo => 'bar').foo.should eq 'bar'
59
+ end
60
+
61
+ it 'returns nil if not set' do
62
+ Croudia::Identity.new(:foo => 'bar').bar.should be_nil
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,61 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Friendships do
4
+ context 'when logged in' do
5
+ before do
6
+ @croudia = Croudia::Scraper.new
7
+ @croudia.instance_variable_set('@logged_in', true)
8
+ end
9
+
10
+ describe '#follow' do
11
+ it 'posts to the correct resource' do
12
+ stub_post('/follows/target_follow').to_return(:headers => {:content_type => 'text/html'})
13
+ @croudia.follow('wktk')
14
+ a_post('/follows/target_follow').with(:body => /target_user_name=wktk/).should have_been_made
15
+ end
16
+ end
17
+
18
+ describe '#unfollow' do
19
+ it 'posts to the correct resource' do
20
+ stub_post('/follows/target_follow').to_return(:headers => {:content_type => 'text/html'})
21
+ @croudia.follow('wktk')
22
+ a_post('/follows/target_follow').with(:body => /target_user_name=wktk/).should have_been_made
23
+ end
24
+ end
25
+ end
26
+
27
+ context 'when not logged in' do
28
+ before do
29
+ @croudia = Croudia::Scraper.new
30
+ @croudia.instance_variable_set('@logged_in', true)
31
+ end
32
+
33
+ describe '#follow' do
34
+ it 'should raise error' do
35
+ expect{ @croudia.follow('wktk') }.to raise_error
36
+ end
37
+ end
38
+
39
+ describe '#unfollow' do
40
+ it 'should raise error' do
41
+ expect{ @croudia.follow('wktk') }.to raise_error
42
+ end
43
+ end
44
+ end
45
+
46
+ describe '#follower' do
47
+ it 'gets the correct resource' do
48
+ stub_get('/follows/follower/wktk').to_return(:headers => {:content_type => 'text/html'})
49
+ Croudia.follower('wktk')
50
+ a_get('/follows/follower/wktk').should have_been_made
51
+ end
52
+ end
53
+
54
+ describe '#following' do
55
+ it 'gets the correct resource' do
56
+ stub_get('/follows/following/wktk').to_return(:headers => {:content_type => 'text/html'})
57
+ Croudia.following('wktk')
58
+ a_get('/follows/following/wktk').should have_been_made
59
+ end
60
+ end
61
+ end