t 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,136 +0,0 @@
1
- require 'active_support/core_ext/array/grouping'
2
- require 'retryable'
3
- require 't/core_ext/enumerable'
4
- require 't/core_ext/string'
5
- require 't/collectable'
6
- require 't/rcfile'
7
- require 't/requestable'
8
- require 'thor'
9
-
10
- module T
11
- class CLI
12
- class List
13
- class Remove < Thor
14
- include T::Collectable
15
- include T::Requestable
16
-
17
- MAX_USERS_PER_REQUEST = 100
18
-
19
- check_unknown_options!
20
-
21
- def initialize(*)
22
- super
23
- @rcfile = RCFile.instance
24
- end
25
-
26
- desc "friends LIST_NAME", "Remove all friends from a list."
27
- def friends(list_name)
28
- list_member_ids = collect_with_cursor do |cursor|
29
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
30
- end
31
- friend_ids = collect_with_cursor do |cursor|
32
- client.friend_ids(:cursor => cursor)
33
- end
34
- list_member_ids_to_remove = (friend_ids - list_member_ids)
35
- number = list_member_ids_to_remove.length
36
- if number.zero?
37
- return say "None of @#{@rcfile.default_profile[0]}'s friends are members of the list \"#{list_name}\"."
38
- else
39
- return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'friend' : 'friends'} from the list \"#{list_name}\"?"
40
- end
41
- list_member_ids_to_remove.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
42
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
43
- client.list_remove_members(list_name, user_id_group)
44
- end
45
- end
46
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'friend' : 'friends'} from the list \"#{list_name}\"."
47
- say
48
- say "Run `#{File.basename($0)} list add all friends #{list_name}` to undo."
49
- end
50
-
51
- desc "followers LIST_NAME", "Remove all followers from a list."
52
- def followers(list_name)
53
- list_member_ids = collect_with_cursor do |cursor|
54
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
55
- end
56
- follower_ids = collect_with_cursor do |cursor|
57
- client.follower_ids(:cursor => cursor)
58
- end
59
- list_member_ids_to_remove = (follower_ids - list_member_ids)
60
- number = list_member_ids_to_remove.length
61
- if number.zero?
62
- return say "None of @#{@rcfile.default_profile[0]}'s followers are members of the list \"#{list_name}\"."
63
- else
64
- return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'follower' : 'followers'} from the list \"#{list_name}\"?"
65
- end
66
- list_member_ids_to_remove.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
67
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
68
- client.list_remove_members(list_name, user_id_group)
69
- end
70
- end
71
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'follower' : 'followers'} from the list \"#{list_name}\"."
72
- say
73
- say "Run `#{File.basename($0)} list add all followers #{list_name}` to undo."
74
- end
75
-
76
- desc "listed FROM_LIST_NAME TO_LIST_NAME", "Remove all list members from a list."
77
- def listed(from_list_name, to_list_name)
78
- to_list_members = collect_with_cursor do |cursor|
79
- client.list_members(to_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
80
- end
81
- from_list_members = collect_with_cursor do |cursor|
82
- client.list_members(from_list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
83
- end
84
- list_member_ids_to_remove = (from_list_members.collect(&:id) - to_list_members.collect(&:id))
85
- number = list_member_ids_to_remove.length
86
- if number.zero?
87
- return say "None of the members of the list \"#{from_list_name}\" are members of the list \"#{to_list_name}\"."
88
- else
89
- return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{to_list_name}\"?"
90
- end
91
- list_member_ids_to_remove.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
92
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
93
- client.list_remove_members(to_list_name, user_id_group)
94
- end
95
- end
96
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{to_list_name}\"."
97
- say
98
- say "Run `#{File.basename($0)} list add all listed #{from_list_name} #{to_list_name}` to undo."
99
- end
100
-
101
- desc "members LIST_NAME", "Remove all members from a list."
102
- def members(list_name)
103
- list_members = collect_with_cursor do |cursor|
104
- client.list_members(list_name, :cursor => cursor, :skip_status => true, :include_entities => false)
105
- end
106
- number = list_members.length
107
- return say "The list \"#{list_name}\" doesn't have any members." if number.zero?
108
- return unless yes? "Are you sure you want to remove #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"?"
109
- list_members.collect(&:id).in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
110
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
111
- client.list_remove_members(list_name, user_id_group)
112
- end
113
- end
114
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'member' : 'members'} from the list \"#{list_name}\"."
115
- end
116
- map %w(all) => :members
117
-
118
- desc "users LIST_NAME SCREEN_NAME [SCREEN_NAME...]", "Remove users from a list."
119
- def users(list_name, screen_name, *screen_names)
120
- screen_names.unshift(screen_name)
121
- screen_names.map!(&:strip_at)
122
- screen_names.in_groups_of(MAX_USERS_PER_REQUEST, false).threaded_each do |user_id_group|
123
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
124
- client.list_remove_members(list_name, user_id_group)
125
- end
126
- end
127
- number = screen_names.length
128
- say "@#{@rcfile.default_profile[0]} removed #{number} #{number == 1 ? 'user' : 'users'} from the list \"#{list_name}\"."
129
- say
130
- say "Run `#{File.basename($0)} list add users #{list_name} #{screen_names.join(' ')}` to undo."
131
- end
132
-
133
- end
134
- end
135
- end
136
- end
data/lib/t/cli/search.rb DELETED
@@ -1,124 +0,0 @@
1
- require 'action_view'
2
- require 'pager'
3
- require 'retryable'
4
- require 't/core_ext/enumerable'
5
- require 't/rcfile'
6
- require 't/requestable'
7
- require 'thor'
8
-
9
- module T
10
- class CLI
11
- class Search < Thor
12
- include ActionView::Helpers::DateHelper
13
- include Pager
14
- include T::Requestable
15
-
16
- DEFAULT_NUM_RESULTS = 20
17
- MAX_PAGES = 16
18
- MAX_NUM_RESULTS = 200
19
- MAX_SCREEN_NAME_SIZE = 20
20
-
21
- check_unknown_options!
22
-
23
- def initialize(*)
24
- super
25
- @rcfile = RCFile.instance
26
- end
27
-
28
- desc "all QUERY", "Returns the #{DEFAULT_NUM_RESULTS} most recent Tweets that match a specified query."
29
- method_option :number, :aliases => "-n", :type => :numeric, :default => DEFAULT_NUM_RESULTS
30
- method_option :reverse, :aliases => "-r", :type => :boolean, :default => false
31
- def all(query)
32
- defaults = {:include_entities => false}
33
- defaults.merge!(:rpp => options['number']) if options['number']
34
- timeline = client.search(query, defaults)
35
- timeline.reverse! if options['reverse']
36
- page unless T.env.test?
37
- timeline.each do |status|
38
- say "#{status.from_user.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
39
- end
40
- end
41
-
42
- desc "favorites QUERY", "Returns Tweets you've favorited that mach a specified query."
43
- def favorites(query)
44
- timeline = 1.upto(MAX_PAGES).threaded_map do |page|
45
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
46
- client.favorites(:page => page, :count => MAX_NUM_RESULTS).select do |status|
47
- /#{query}/i.match(status.text)
48
- end
49
- end
50
- end
51
- page unless T.env.test?
52
- timeline.flatten.compact.each do |status|
53
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
54
- end
55
- end
56
- map %w(faves) => :favorites
57
-
58
- desc "mentions QUERY", "Returns Tweets mentioning you that mach a specified query."
59
- def mentions(query)
60
- timeline = 1.upto(MAX_PAGES).threaded_map do |page|
61
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
62
- client.mentions(:page => page, :count => MAX_NUM_RESULTS).select do |status|
63
- /#{query}/i.match(status.text)
64
- end
65
- end
66
- end
67
- page unless T.env.test?
68
- timeline.flatten.compact.each do |status|
69
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
70
- end
71
- end
72
- map %w(replies) => :mentions
73
-
74
- desc "retweets QUERY", "Returns Tweets you've retweeted that mach a specified query."
75
- def retweets(query)
76
- timeline = 1.upto(MAX_PAGES).threaded_map do |page|
77
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
78
- client.retweeted_by(:page => page, :count => MAX_NUM_RESULTS).select do |status|
79
- /#{query}/i.match(status.text)
80
- end
81
- end
82
- end
83
- page unless T.env.test?
84
- timeline.flatten.compact.each do |status|
85
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
86
- end
87
- end
88
- map %w(rts) => :retweets
89
-
90
- desc "timeline QUERY", "Returns Tweets in your timeline that match a specified query."
91
- def timeline(query)
92
- timeline = 1.upto(MAX_PAGES).threaded_map do |page|
93
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
94
- client.home_timeline(:page => page, :count => MAX_NUM_RESULTS).select do |status|
95
- /#{query}/i.match(status.text)
96
- end
97
- end
98
- end
99
- page unless T.env.test?
100
- timeline.flatten.compact.each do |status|
101
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
102
- end
103
- end
104
- map %w(tl) => :timeline
105
-
106
- desc "user SCREEN_NAME QUERY", "Returns Tweets in a user's timeline that match a specified query."
107
- def user(screen_name, query)
108
- screen_name = screen_name.strip_at
109
- timeline = 1.upto(MAX_PAGES).threaded_map do |page|
110
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
111
- client.user_timeline(screen_name, :page => page, :count => MAX_NUM_RESULTS).select do |status|
112
- /#{query}/i.match(status.text)
113
- end
114
- end
115
- end
116
- page unless T.env.test?
117
- timeline.flatten.compact.each do |status|
118
- say "#{status.user.screen_name.rjust(MAX_SCREEN_NAME_SIZE)}: #{status.text} (#{time_ago_in_words(status.created_at)} ago)"
119
- end
120
- end
121
-
122
- end
123
- end
124
- end
data/lib/t/cli/set.rb DELETED
@@ -1,59 +0,0 @@
1
- require 't/core_ext/string'
2
- require 't/rcfile'
3
- require 't/requestable'
4
- require 'thor'
5
-
6
- module T
7
- class CLI
8
- class Set < Thor
9
- include T::Requestable
10
-
11
- check_unknown_options!
12
-
13
- def initialize(*)
14
- super
15
- @rcfile = RCFile.instance
16
- end
17
-
18
- desc "bio DESCRIPTION", "Edits your Bio information on your Twitter profile."
19
- def bio(description)
20
- client.update_profile(:description => description, :include_entities => false)
21
- say "@#{@rcfile.default_profile[0]}'s bio has been updated."
22
- end
23
-
24
- desc "default SCREEN_NAME [CONSUMER_KEY]", "Set your default account."
25
- def default(screen_name, consumer_key=nil)
26
- screen_name = screen_name.strip_at
27
- @rcfile.path = parent_options['profile'] if parent_options['profile']
28
- consumer_key = @rcfile[screen_name].keys.last if consumer_key.nil?
29
- @rcfile.default_profile = {'username' => screen_name, 'consumer_key' => consumer_key}
30
- say "Default account has been updated."
31
- end
32
-
33
- desc "language LANGUAGE_NAME", "Selects the language you'd like to receive notifications in."
34
- def language(language_name)
35
- client.settings(:lang => language_name)
36
- say "@#{@rcfile.default_profile[0]}'s language has been updated."
37
- end
38
-
39
- desc "location PLACE_NAME", "Updates the location field in your profile."
40
- def location(place_name)
41
- client.update_profile(:location => place_name, :include_entities => false)
42
- say "@#{@rcfile.default_profile[0]}'s location has been updated."
43
- end
44
-
45
- desc "name NAME", "Sets the name field on your Twitter profile."
46
- def name(name)
47
- client.update_profile(:name => name, :include_entities => false)
48
- say "@#{@rcfile.default_profile[0]}'s name has been updated."
49
- end
50
-
51
- desc "url URL", "Sets the URL field on your profile."
52
- def url(url)
53
- client.update_profile(:url => url, :include_entities => false)
54
- say "@#{@rcfile.default_profile[0]}'s URL has been updated."
55
- end
56
-
57
- end
58
- end
59
- end
@@ -1,121 +0,0 @@
1
- require 'retryable'
2
- require 't/core_ext/enumerable'
3
- require 't/core_ext/string'
4
- require 't/collectable'
5
- require 't/rcfile'
6
- require 't/requestable'
7
- require 'thor'
8
-
9
- module T
10
- class CLI
11
- class Unfollow < Thor
12
- include T::Collectable
13
- include T::Requestable
14
-
15
- check_unknown_options!
16
-
17
- def initialize(*)
18
- super
19
- @rcfile = RCFile.instance
20
- end
21
-
22
- desc "listed LIST_NAME", "Unfollow all members of a list."
23
- def listed(list_name)
24
- list_member_collection = collect_with_cursor do |cursor|
25
- client.list_members(list_name, :cursor => cursor, :include_entities => false, :skip_status => true)
26
- end
27
- number = list_member_collection.length
28
- return say "@#{@rcfile.default_profile[0]} is already not following any list members." if number.zero?
29
- return unless yes? "Are you sure you want to unfollow #{number} #{number == 1 ? 'user' : 'users'}?"
30
- list_member_collection.threaded_map do |list_member|
31
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
32
- client.unfollow(list_member.id, :include_entities => false)
33
- end
34
- end
35
- say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
36
- say
37
- say "Run `#{File.basename($0)} follow all listed #{list_name}` to follow again."
38
- end
39
-
40
- desc "followers", "Unfollow all followers."
41
- def followers
42
- follower_ids = collect_with_cursor do |cursor|
43
- client.follower_ids(:cursor => cursor)
44
- end
45
- friend_ids = collect_with_cursor do |cursor|
46
- friends = client.friend_ids(:cursor => cursor)
47
- end
48
- follow_ids = (follower_ids - friend_ids)
49
- number = follow_ids.length
50
- return say "@#{@rcfile.default_profile[0]} is already not following any followers." if number.zero?
51
- return unless yes? "Are you sure you want to unfollow #{number} #{number == 1 ? 'user' : 'users'}?"
52
- screen_names = follow_ids.threaded_map do |follow_id|
53
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
54
- client.unfollow(follow_id, :include_entities => false)
55
- end
56
- end
57
- say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
58
- say
59
- say "Run `#{File.basename($0)} follow all followers` to stop."
60
- end
61
-
62
- desc "friends", "Unfollow all friends."
63
- def friends
64
- friend_ids = collect_with_cursor do |cursor|
65
- client.friend_ids(:cursor => cursor)
66
- end
67
- number = friend_ids.length
68
- return say "@#{@rcfile.default_profile[0]} is already not following anyone." if number.zero?
69
- return unless yes? "Are you sure you want to unfollow #{number} #{number == 1 ? 'user' : 'users'}?"
70
- screen_names = friend_ids.threaded_map do |friend_id|
71
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
72
- user = client.unfollow(friend_id, :include_entities => false)
73
- user.screen_name
74
- end
75
- end
76
- say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
77
- say
78
- say "Run `#{File.basename($0)} follow users #{screen_names.join(' ')}` to follow again."
79
- end
80
- map %w(everyone everybody) => :friends
81
-
82
- desc "nonfollowers", "Unfollow all non-followers."
83
- def nonfollowers
84
- friend_ids = collect_with_cursor do |cursor|
85
- client.friend_ids(:cursor => cursor)
86
- end
87
- follower_ids = collect_with_cursor do |cursor|
88
- client.follower_ids(:cursor => cursor)
89
- end
90
- unfollow_ids = (friend_ids - follower_ids)
91
- number = unfollow_ids.length
92
- return say "@#{@rcfile.default_profile[0]} is already not following any non-followers." if number.zero?
93
- return unless yes? "Are you sure you want to unfollow #{number} #{number == 1 ? 'user' : 'users'}?"
94
- screen_names = unfollow_ids.threaded_map do |unfollow_id|
95
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
96
- user = client.unfollow(unfollow_id, :include_entities => false)
97
- user.screen_name
98
- end
99
- end
100
- say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
101
- say
102
- say "Run `#{File.basename($0)} follow users #{screen_names.join(' ')}` to follow again."
103
- end
104
-
105
- desc "users SCREEN_NAME [SCREEN_NAME...]", "Allows you to stop following users."
106
- def users(screen_name, *screen_names)
107
- screen_names.unshift(screen_name)
108
- screen_names.threaded_map do |screen_name|
109
- retryable(:tries => 3, :on => Twitter::Error::ServerError, :sleep => 0) do
110
- client.unfollow(screen_name, :include_entities => false)
111
- end
112
- end
113
- number = screen_names.length
114
- say "@#{@rcfile.default_profile[0]} is no longer following #{number} #{number == 1 ? 'user' : 'users'}."
115
- say
116
- say "Run `#{File.basename($0)} follow users #{screen_names.join(' ')}` to follow again."
117
- end
118
-
119
- end
120
- end
121
- end
@@ -1,240 +0,0 @@
1
- # encoding: utf-8
2
- require 'helper'
3
-
4
- describe T::CLI::Follow do
5
-
6
- before do
7
- rcfile = RCFile.instance
8
- rcfile.path = fixture_path + "/.trc"
9
- @t = T::CLI.new
10
- @old_stderr = $stderr
11
- $stderr = StringIO.new
12
- @old_stdout = $stdout
13
- $stdout = StringIO.new
14
- end
15
-
16
- after do
17
- $stderr = @old_stderr
18
- $stdout = @old_stdout
19
- end
20
-
21
- describe "#followers" do
22
- before do
23
- @t.options = @t.options.merge(:profile => fixture_path + "/.trc")
24
- end
25
- context "no followers" do
26
- before do
27
- stub_get("/1/followers/ids.json").
28
- with(:query => {:cursor => "-1"}).
29
- to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
30
- stub_get("/1/friends/ids.json").
31
- with(:query => {:cursor => "-1"}).
32
- to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
33
- end
34
- it "should request the correct resource" do
35
- @t.follow("followers")
36
- a_get("/1/followers/ids.json").
37
- with(:query => {:cursor => "-1"}).
38
- should have_been_made
39
- a_get("/1/friends/ids.json").
40
- with(:query => {:cursor => "-1"}).
41
- should have_been_made
42
- end
43
- it "should have the correct output" do
44
- @t.follow("followers")
45
- $stdout.string.chomp.should == "@testcli is already following all followers."
46
- end
47
- end
48
- context "one follower" do
49
- before do
50
- stub_get("/1/followers/ids.json").
51
- with(:query => {:cursor => "-1"}).
52
- to_return(:body => fixture("friends_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
53
- stub_get("/1/friends/ids.json").
54
- with(:query => {:cursor => "-1"}).
55
- to_return(:body => fixture("followers_ids.json"), :headers => {:content_type => "application/json; charset=utf-8"})
56
- end
57
- it "should request the correct resource" do
58
- stub_post("/1/friendships/create.json").
59
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
60
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
61
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
62
- $stdin.should_receive(:gets).and_return("yes")
63
- @t.follow("followers")
64
- a_get("/1/followers/ids.json").
65
- with(:query => {:cursor => "-1"}).
66
- should have_been_made
67
- a_get("/1/friends/ids.json").
68
- with(:query => {:cursor => "-1"}).
69
- should have_been_made
70
- a_post("/1/friendships/create.json").
71
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
72
- should have_been_made
73
- end
74
- context "yes" do
75
- it "should have the correct output" do
76
- stub_post("/1/friendships/create.json").
77
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
78
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
79
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
80
- $stdin.should_receive(:gets).and_return("yes")
81
- @t.follow("followers")
82
- $stdout.string.should =~ /^@testcli is now following 1 more user\.$/
83
- end
84
- end
85
- context "no" do
86
- it "should have the correct output" do
87
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
88
- $stdin.should_receive(:gets).and_return("no")
89
- @t.follow("followers")
90
- $stdout.string.chomp.should == ""
91
- end
92
- end
93
- context "Twitter is down" do
94
- it "should retry 3 times and then raise an error" do
95
- stub_post("/1/friendships/create.json").
96
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
97
- to_return(:status => 502)
98
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
99
- $stdin.should_receive(:gets).and_return("yes")
100
- lambda do
101
- @t.follow("followers")
102
- end.should raise_error("Twitter is down or being upgraded.")
103
- a_post("/1/friendships/create.json").
104
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
105
- should have_been_made.times(3)
106
- end
107
- end
108
- end
109
- end
110
-
111
- describe "#listed" do
112
- before do
113
- @t.options = @t.options.merge(:profile => fixture_path + "/.trc")
114
- stub_get("/1/account/verify_credentials.json").
115
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
116
- end
117
- context "no users" do
118
- before do
119
- stub_get("/1/lists/members.json").
120
- with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
121
- to_return(:body => fixture("empty_cursor.json"), :headers => {:content_type => "application/json; charset=utf-8"})
122
- end
123
- it "should request the correct resource" do
124
- @t.follow("listed", "presidents")
125
- a_get("/1/account/verify_credentials.json").
126
- should have_been_made
127
- a_get("/1/lists/members.json").
128
- with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
129
- should have_been_made
130
- end
131
- it "should have the correct output" do
132
- @t.follow("listed", "presidents")
133
- $stdout.string.chomp.should == "@testcli is already following all list members."
134
- end
135
- end
136
- context "one user" do
137
- before do
138
- @t.options = @t.options.merge(:profile => fixture_path + "/.trc")
139
- stub_get("/1/lists/members.json").
140
- with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
141
- to_return(:body => fixture("users_list.json"), :headers => {:content_type => "application/json; charset=utf-8"})
142
- end
143
- it "should request the correct resource" do
144
- stub_post("/1/friendships/create.json").
145
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
146
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
147
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
148
- $stdin.should_receive(:gets).and_return("yes")
149
- @t.follow("listed", "presidents")
150
- a_get("/1/account/verify_credentials.json").
151
- should have_been_made
152
- a_get("/1/lists/members.json").
153
- with(:query => {:cursor => "-1", :include_entities => "false", :owner_screen_name => "sferik", :skip_status => "true", :slug => "presidents"}).
154
- should have_been_made
155
- a_post("/1/friendships/create.json").
156
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
157
- should have_been_made
158
- end
159
- context "yes" do
160
- it "should have the correct output" do
161
- stub_post("/1/friendships/create.json").
162
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
163
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
164
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
165
- $stdin.should_receive(:gets).and_return("yes")
166
- @t.follow("listed", "presidents")
167
- $stdout.string.should =~ /^@testcli is now following 1 more user\.$/
168
- end
169
- end
170
- context "no" do
171
- it "should have the correct output" do
172
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
173
- $stdin.should_receive(:gets).and_return("no")
174
- @t.follow("listed", "presidents")
175
- $stdout.string.chomp.should == ""
176
- end
177
- end
178
- context "Twitter is down" do
179
- it "should retry 3 times and then raise an error" do
180
- stub_post("/1/friendships/create.json").
181
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
182
- to_return(:status => 502)
183
- $stdout.should_receive(:print).with("Are you sure you want to follow 1 user? ")
184
- $stdin.should_receive(:gets).and_return("yes")
185
- lambda do
186
- @t.follow("listed", "presidents")
187
- end.should raise_error("Twitter is down or being upgraded.")
188
- a_post("/1/friendships/create.json").
189
- with(:body => {:user_id => "7505382", :include_entities => "false"}).
190
- should have_been_made.times(3)
191
- end
192
- end
193
- end
194
- end
195
-
196
- describe "#users" do
197
- before do
198
- @t.options = @t.options.merge(:profile => fixture_path + "/.trc")
199
- end
200
- context "no users" do
201
- it "should exit" do
202
- lambda do
203
- @t.follow("users")
204
- end.should raise_error
205
- end
206
- end
207
- context "one user" do
208
- it "should request the correct resource" do
209
- stub_post("/1/friendships/create.json").
210
- with(:body => {:screen_name => "sferik", :include_entities => "false"}).
211
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
212
- @t.follow("users", "sferik")
213
- a_post("/1/friendships/create.json").
214
- with(:body => {:screen_name => "sferik", :include_entities => "false"}).
215
- should have_been_made
216
- end
217
- it "should have the correct output" do
218
- stub_post("/1/friendships/create.json").
219
- with(:body => {:screen_name => "sferik", :include_entities => "false"}).
220
- to_return(:body => fixture("sferik.json"), :headers => {:content_type => "application/json; charset=utf-8"})
221
- @t.follow("users", "sferik")
222
- $stdout.string.should =~ /^@testcli is now following 1 more user\.$/
223
- end
224
- context "Twitter is down" do
225
- it "should retry 3 times and then raise an error" do
226
- stub_post("/1/friendships/create.json").
227
- with(:body => {:screen_name => "sferik", :include_entities => "false"}).
228
- to_return(:status => 502)
229
- lambda do
230
- @t.follow("users", "sferik")
231
- end.should raise_error("Twitter is down or being upgraded.")
232
- a_post("/1/friendships/create.json").
233
- with(:body => {:screen_name => "sferik", :include_entities => "false"}).
234
- should have_been_made.times(3)
235
- end
236
- end
237
- end
238
- end
239
-
240
- end