croudia 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.
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
@@ -0,0 +1,135 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Login do
4
+ describe '#login' do
5
+ before do
6
+ stub_get('/').to_return do |request|
7
+ if /logged_in=yes/ =~ request.headers['Cookie']
8
+ {:status => 302, :headers => {:location => Croudia.endpoint + '/logged_in'}}
9
+ else
10
+ {:headers => {:content_type => 'text/html'}}
11
+ end
12
+ end
13
+ stub_post('/').to_return do |request|
14
+ headers = {:content_type => 'text/html'}
15
+ if /username=username/ =~ request.body
16
+ headers.merge!(:set_cookie => 'logged_in=yes')
17
+ end
18
+ {:headers => headers}
19
+ end
20
+ stub_get('/logged_in').to_return(:headers => {:content_type => 'text/html'})
21
+ end
22
+
23
+ it 'gets "/" before login' do
24
+ Croudia::Scraper.new.login('username', 'password')
25
+ a_get('/').should have_been_made.twice
26
+ end
27
+
28
+ it 'posts the provided username and password to "/"' do
29
+ Croudia::Scraper.new.login('username', 'password')
30
+ a_post('/').with(:body => /username=username/).should have_been_made
31
+ end
32
+
33
+ it 'checks if succeeded or not' do
34
+ Croudia::Scraper.new.login('username', 'password')
35
+ a_get('/').with(:headers => {:cookie => /logged_in=yes/}).should have_been_made
36
+ end
37
+
38
+ context 'when the provided username and password are correct' do
39
+ it 'does not raise an error' do
40
+ expect{ Croudia::Scraper.new.login('username', 'password') }.not_to raise_error
41
+ end
42
+
43
+ it 'sets @logged_in as true' do
44
+ @croudia = Croudia::Scraper.new
45
+ @croudia.login('username', 'password')
46
+ @croudia.instance_variable_get('@logged_in').should be_true
47
+ end
48
+ end
49
+
50
+ context 'when the provided username and password are incorrect' do
51
+ it 'raises an error' do
52
+ expect{ Croudia::Scraper.new.login('wrong', 'wrong') }.to raise_error ArgumentError
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '#logout' do
58
+ context 'when already logged out' do
59
+ it 'raises an error' do
60
+ @croudia = Croudia::Scraper.new
61
+ @croudia.instance_variable_set('@logged_in', false)
62
+ expect{ @croudia.logout }.to raise_error
63
+ end
64
+ end
65
+
66
+ context 'when logged in' do
67
+ before do
68
+ stub_post('/login/logout')
69
+ @croudia = Croudia::Scraper.new
70
+ @croudia.instance_variable_set('@logged_in', true)
71
+ end
72
+
73
+ it 'posts a request to the correct resource' do
74
+ @croudia.logout
75
+ a_post('/login/logout').should have_been_made
76
+ end
77
+
78
+ it 'sets @logged_in as false' do
79
+ @croudia.logout
80
+ @croudia.instance_variable_get('@logged_in').should be_false
81
+ end
82
+
83
+ it 'sets @current_user nil' do
84
+ @croudia.logout
85
+ @croudia.instance_variable_get('@current_user').should be_nil
86
+ end
87
+ end
88
+ end
89
+
90
+ describe '#logged_in?' do
91
+ context 'when @logged_in is set' do
92
+ it 'returns @logged_in' do
93
+ @croudia = Croudia::Scraper.new
94
+ @croudia.instance_variable_set('@logged_in', true)
95
+ @croudia.logged_in?.should be_true
96
+ @croudia.instance_variable_set('@logged_in', false)
97
+ @croudia.logged_in?.should be_false
98
+ end
99
+ end
100
+
101
+ context 'when @logged_in is not set' do
102
+ it 'gets "/" to confirm logged-in or not' do
103
+ stub_get('/')
104
+ Croudia::Scraper.new.logged_in?
105
+ a_get('/').should have_been_made
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#logged_out?' do
111
+ it 'returns !self.logged_in' do
112
+ @croudia = Croudia::Scraper.new
113
+ @croudia.instance_variable_set('@logged_in', true)
114
+ @croudia.logged_out?.should be_false
115
+ @croudia.instance_variable_set('@logged_in', false)
116
+ @croudia.logged_out?.should be_true
117
+ end
118
+ end
119
+
120
+ describe '#require_login' do
121
+ context 'when logged out' do
122
+ it 'raises an errror' do
123
+ expect{ Croudia::Scraper.new.require_login }.to raise_error
124
+ end
125
+ end
126
+
127
+ context 'when logged in' do
128
+ it 'does not raise an error' do
129
+ @croudia = Croudia::Scraper.new
130
+ @croudia.instance_variable_set('@logged_in', true)
131
+ expect{ @croudia.require_login }.not_to raise_error
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,256 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Parser::Users do
4
+ describe '#user_page' do
5
+ context 'when it does not look like a user page' do
6
+ it 'returns nil' do
7
+ stub_get('/blank').to_return(:headers => {:content_type => 'text/html'})
8
+ Croudia.user('blank').should be_nil
9
+ end
10
+ end
11
+
12
+ context 'when it looks a user page' do
13
+ before do
14
+ stub_get('/wktk1').to_return(:body => fixture('user_wktk1'), :headers => {:content_type => 'text/html'})
15
+ @user1 = Croudia.user('wktk1')
16
+ stub_get('/wktk2').to_return(:body => fixture('user_wktk2'), :headers => {:content_type => 'text/html'})
17
+ @user2 = Croudia.user('wktk2')
18
+ stub_get('/wktk3').to_return(:body => fixture('user_wktk3'), :headers => {:content_type => 'text/html'})
19
+ @user3 = Croudia.user('wktk3')
20
+ end
21
+
22
+ it 'gets username' do
23
+ @user1.username.should eq 'wktk'
24
+ end
25
+
26
+ it 'gets nickname' do
27
+ @user1.nickname.should eq 'wktk!'
28
+ end
29
+
30
+ it 'gets avatar url' do
31
+ @user1.avatar.should eq 'https://croudia.com/testimages/download/9423'
32
+ end
33
+
34
+ it 'gets description' do
35
+ @user1.description.should eq 'This is a dummy description for test.'
36
+ end
37
+
38
+ it 'trims description' do
39
+ @user1.description.should_not match /^\s|\s$/
40
+ end
41
+
42
+ it 'gets voices_count' do
43
+ @user1.voices_count.to_i.should eq 3381
44
+ end
45
+
46
+ it 'converts voices_count into an Integer' do
47
+ @user1.voices_count.should be_a Integer
48
+ end
49
+
50
+ it 'gets following_count' do
51
+ @user1.following_count.to_i.should eq 46
52
+ end
53
+
54
+ it 'converts following_count into an Integer' do
55
+ @user1.following_count.should be_a Integer
56
+ end
57
+
58
+ it 'gets followers_count' do
59
+ @user1.followers_count.to_i.should eq 468
60
+ end
61
+
62
+ it 'converts followers_count into an Integer' do
63
+ @user1.followers_count.should be_a Integer
64
+ end
65
+
66
+ it 'gets album_count' do
67
+ @user1.album_count.to_i.should eq 123
68
+ end
69
+
70
+ it 'converts album_count into an Integer' do
71
+ @user1.album_count.should be_a Integer
72
+ end
73
+
74
+ it 'gets spreadia' do
75
+ @user1.spreadia.to_i.should eq 2525
76
+ end
77
+
78
+ it 'converts spreadia into an Integer' do
79
+ @user1.spreadia.should be_a Integer
80
+ end
81
+
82
+ it 'gets favodia' do
83
+ @user1.favodia.to_i.should eq 4321
84
+ end
85
+
86
+ it 'converts favodia into an Integer' do
87
+ @user1.favodia.should be_a Integer
88
+ end
89
+
90
+ context 'when url is set' do
91
+ it 'gets url' do
92
+ @user1.url.should eq 'http://wktk.in'
93
+ end
94
+ end
95
+
96
+ context 'when url is not set' do
97
+ it 'leaves url nil' do
98
+ @user2.url.should be_nil
99
+ end
100
+ end
101
+
102
+ context 'when location is set' do
103
+ it 'gets location' do
104
+ @user1.location.should eq 'Tokyo, Japan'
105
+ end
106
+ end
107
+
108
+ context 'when location is not set' do
109
+ it 'leaves location blank' do
110
+ @user2.location.should be_nil
111
+ end
112
+ end
113
+
114
+ context 'when following info included' do
115
+ context 'when following' do
116
+ it 'makes following true' do
117
+ @user2.following.should be_true
118
+ end
119
+ end
120
+
121
+ context 'when not following' do
122
+ it 'makes following false' do
123
+ @user3.following.should be_false
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'when following info not included' do
129
+ it 'leaves following nil' do
130
+ @user1.following.should be_nil
131
+ end
132
+ end
133
+
134
+ context 'when followed_by info included' do
135
+ context 'when followed_by' do
136
+ it 'makes followed_by true' do
137
+ @user2.followed_by.should be_true
138
+ end
139
+ end
140
+
141
+ context 'when not followed_by' do
142
+ it 'makes followed_by false' do
143
+ @user3.followed_by.should be_false
144
+ end
145
+ end
146
+ end
147
+
148
+ context 'when followed_by info not included' do
149
+ it 'leaves followed_by nil' do
150
+ @user1.followed_by.should be_nil
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '#user_list' do
157
+ before do
158
+ stub_get('/follows/following/wktk').to_return(:body => fixture('following_wktk'), :headers => {:content_type => 'text/html'})
159
+ stub_get('/follows/follower/wktk').to_return(:body => fixture('follower_wktk'), :headers => {:content_type => 'text/html'})
160
+ @following = Croudia.following('wktk')
161
+ @followers = Croudia.followers('wktk')
162
+ end
163
+
164
+ context 'when following list provided' do
165
+ it 'gets all users in the page' do
166
+ @following.size.should eq 3
167
+ end
168
+
169
+ it 'gets username' do
170
+ @following[0].username.should eq 'following1'
171
+ end
172
+
173
+ it 'gets nickname' do
174
+ @following[0].nickname.should eq 'following 1'
175
+ end
176
+
177
+ it 'gets avatar url' do
178
+ @following[0].avatar.should eq Croudia.endpoint + '/avatar1'
179
+ end
180
+
181
+ it 'gets description' do
182
+ @following[0].description.should eq 'Description 1'
183
+ end
184
+
185
+ it 'trims description' do
186
+ @following[0].description.should_not match /^\s|\s$/
187
+ end
188
+
189
+ context 'when following info provided' do
190
+ context 'when following' do
191
+ it 'sets following true' do
192
+ @following[0].following.should be_true
193
+ end
194
+ end
195
+
196
+ context 'when not following' do
197
+ it 'sets following false' do
198
+ @following[1].following.should be_false
199
+ end
200
+ end
201
+ end
202
+
203
+ context 'when following info not provided' do
204
+ it 'leaves following nil' do
205
+ @following[2].following.should be_false
206
+ end
207
+ end
208
+ end
209
+
210
+ context 'when follower list provided' do
211
+ it 'gets all users in the page' do
212
+ @followers.size.should eq 3
213
+ end
214
+
215
+ it 'gets username' do
216
+ @followers[0].username.should eq 'follower1'
217
+ end
218
+
219
+ it 'gets nickname' do
220
+ @followers[0].nickname.should eq 'follower 1'
221
+ end
222
+
223
+ it 'gets avatar url' do
224
+ @followers[0].avatar.should eq Croudia.endpoint + '/avatar1'
225
+ end
226
+
227
+ it 'gets description' do
228
+ @followers[0].description.should eq 'Description 1'
229
+ end
230
+
231
+ it 'trims description' do
232
+ @followers[0].description.should_not match /^\s|\s$/
233
+ end
234
+
235
+ context 'when following info provided' do
236
+ context 'when following' do
237
+ it 'sets following true' do
238
+ @followers[0].following.should be_true
239
+ end
240
+ end
241
+
242
+ context 'when not following' do
243
+ it 'sets following false' do
244
+ @followers[1].following.should be_false
245
+ end
246
+ end
247
+ end
248
+
249
+ context 'when following info not provided' do
250
+ it 'leaves following nil' do
251
+ @followers[2].following.should be_false
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,119 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Parser::Voices do
4
+ describe '#voices' do
5
+ context 'when parsing timeline' do
6
+ before do
7
+ stub_get('/voices/timeline').to_return(:body => fixture('voices_timeline'), :headers => {:content_type => 'text/html'})
8
+ @croudia = Croudia::Scraper.new
9
+ @croudia.instance_variable_set('@logged_in', true)
10
+ @timeline = @croudia.timeline
11
+ @voice = @timeline[0]
12
+ end
13
+
14
+ it 'returns an array' do
15
+ @timeline.should be_a Array
16
+ end
17
+
18
+ it 'returns an array of Croudia::Voice' do
19
+ @timeline.each do |voice|
20
+ voice.should be_a Croudia::Voice
21
+ end
22
+ end
23
+
24
+ it 'gets id' do
25
+ @voice.id.should eq '1001'
26
+ end
27
+
28
+ it 'gets user' do
29
+ @voice.user.username.should eq 'username1'
30
+ end
31
+
32
+ it 'user is a Croudia::User' do
33
+ @voice.user.should be_a Croudia::User
34
+ end
35
+
36
+ it 'gets text' do
37
+ @voice.text.should eq 'text 1'
38
+ end
39
+
40
+ it 'gets favorited_count' do
41
+ @voice.favorited_count.should eq 100
42
+ end
43
+
44
+ it 'converts favorited_count into an Integer' do
45
+ @voice.favorited_count.should be_a Integer
46
+ end
47
+
48
+ it 'gets spreaded_count' do
49
+ @voice.spreaded_count.should eq 950
50
+ end
51
+
52
+ it 'converts spreaded_count into an Integer' do
53
+ @voice.spreaded_count.should be_a Integer
54
+ end
55
+
56
+ it 'gets time' do
57
+ @voice.time.should eq Time.at(1356250231)
58
+ end
59
+
60
+ it 'converts time into a Time' do
61
+ if (@voice.time)
62
+ @voice.time.should be_a Time
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'when parsing reply_list' do
68
+ before do
69
+ stub_get('/voices/reply_list').to_return(:body => fixture('voices_reply_list'), :headers => {:content_type => 'text/html'})
70
+ @croudia = Croudia::Scraper.new
71
+ @croudia.instance_variable_set('@logged_in', true)
72
+ @reply_list = @croudia.reply_list
73
+ @voice = @reply_list[0]
74
+ end
75
+
76
+ it 'returns an array' do
77
+ @reply_list.should be_a Array
78
+ end
79
+
80
+ it 'returns an array of Croudia::Voice' do
81
+ @reply_list.each do |voice|
82
+ voice.should be_a Croudia::Voice
83
+ end
84
+ end
85
+
86
+ it 'gets id' do
87
+ @voice.id.should eq '1001'
88
+ end
89
+
90
+ it 'gets user' do
91
+ @voice.user.username.should eq 'wktk'
92
+ end
93
+
94
+ it 'user is a Croudia::User' do
95
+ @voice.user.should be_a Croudia::User
96
+ end
97
+
98
+ it 'gets text' do
99
+ @voice.text.should eq '@wktk wktk! wktk! wktk! (^-^)/'
100
+ end
101
+
102
+ it 'gets favorited_count' do
103
+ @voice.favorited_count.should eq 500
104
+ end
105
+
106
+ it 'converts favorited_count into an Integer' do
107
+ @voice.favorited_count.should be_a Integer
108
+ end
109
+
110
+ it 'gets spreaded_count' do
111
+ @voice.spreaded_count.should eq 1000
112
+ end
113
+
114
+ it 'converts spreaded_count into an Integer' do
115
+ @voice.spreaded_count.should be_a Integer
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,74 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Users do
4
+ describe '#current_user' do
5
+ context 'when logged in' do
6
+ before do
7
+ @croudia = Croudia::Scraper.new
8
+ @croudia.instance_variable_set('@logged_in', true)
9
+ stub_get('/users/redirect_user').to_return(:body => fixture('user_wktk1'), :headers => {:content_type => 'text/html'})
10
+ end
11
+
12
+ it 'gets the correct resource' do
13
+ @croudia.current_user
14
+ a_get('/users/redirect_user').should have_been_made
15
+ end
16
+
17
+ it 'returns an object of the current user' do
18
+ @croudia.current_user.should be_a Croudia::User
19
+ end
20
+
21
+ it 'caches @current_user' do
22
+ @croudia.current_user
23
+ @croudia.current_user
24
+ a_get('/users/redirect_user').should have_been_made.once
25
+ end
26
+
27
+ it 'returns the cached object if exists' do
28
+ @current_user = @croudia.current_user
29
+ @croudia.current_user.object_id.should eq @current_user.object_id
30
+ end
31
+
32
+ it 'destroyes the cache when an true argument provided' do
33
+ @croudia.current_user(true)
34
+ a_get('/users/redirect_user').should have_been_made
35
+ end
36
+ end
37
+
38
+ context 'when not logged in' do
39
+ it 'raises an error' do
40
+ expect{ Croudia::Scraper.new.current_user }.to raise_error
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#user' do
46
+ context 'when an argument provided' do
47
+ before do
48
+ stub_get('/wktk').to_return(:body => fixture('user_wktk1'), :headers => {:content_type => 'text/html'})
49
+ end
50
+
51
+ it 'gets the correct resource' do
52
+ Croudia::Scraper.new.user('wktk')
53
+ a_get('/wktk').should have_been_made
54
+ end
55
+
56
+ it 'returns a user object' do
57
+ Croudia::Scraper.new.user('wktk').should be_a Croudia::User
58
+ end
59
+ end
60
+
61
+ context 'when arguments not provided' do
62
+ it 'returns @current_user when logged in' do
63
+ @croudia = Croudia::Scraper.new
64
+ @croudia.instance_variable_set('@current_user', Croudia::User.new(:username => 'current_user'))
65
+ @croudia.instance_variable_set('@logged_in', true)
66
+ @croudia.user.to_s.should eq 'current_user'
67
+ end
68
+
69
+ it 'raises an error when not logged in' do
70
+ expect{ Croudia::Scraper.new.user }.to raise_error
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,92 @@
1
+ require 'helper'
2
+
3
+ describe Croudia::Scraper::Voices do
4
+ describe '#timeline' do
5
+ context 'when logged in' do
6
+ before do
7
+ stub_get('/voices/timeline').to_return(:body => fixture('voices_timeline'), :headers => {:content_type => 'text/html'})
8
+ @croudia = Croudia::Scraper.new
9
+ @croudia.instance_variable_set('@logged_in', true)
10
+ end
11
+
12
+ it 'does not raise an error' do
13
+ expect{ @croudia.timeline }.not_to raise_error
14
+ end
15
+
16
+ it 'gets the correct resource' do
17
+ @croudia.timeline
18
+ a_get('/voices/timeline').should have_been_made
19
+ end
20
+
21
+ it 'returns an array' do
22
+ @croudia.timeline.should be_a Array
23
+ end
24
+
25
+ it 'returns an array of Croudia::Voice' do
26
+ @croudia.timeline.each do |voice|
27
+ voice.should be_a Croudia::Voice
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'when not logged in' do
33
+ it 'raises an error' do
34
+ expect{ Croudia::Scraper.new.timeline }.to raise_error
35
+ end
36
+ end
37
+ end
38
+
39
+ describe '#reply_list' do
40
+ context 'when logged in' do
41
+ before do
42
+ stub_get('/voices/reply_list').to_return(:body => fixture('voices_reply_list'), :headers => {:content_type => 'text/html'})
43
+ @croudia = Croudia::Scraper.new
44
+ @croudia.instance_variable_set('@logged_in', true)
45
+ end
46
+
47
+ it 'does not raise an error' do
48
+ expect{ @croudia.reply_list }.not_to raise_error
49
+ end
50
+
51
+ it 'gets the correct resource' do
52
+ @croudia.reply_list
53
+ a_get('/voices/reply_list').should have_been_made
54
+ end
55
+
56
+ it 'returns an array of Croudia::Voice' do
57
+ @croudia.reply_list.each do |voice|
58
+ voice.should be_a Croudia::Voice
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'when not logged in' do
64
+ it 'raises an error' do
65
+ expect{ Croudia::Scraper.new.reply_list }.to raise_error
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#update' do
71
+ context 'when not logged in' do
72
+ it 'raises an error' do
73
+ expect{ Croudia::Scraper.new.update('Hi') }.to raise_error
74
+ end
75
+ end
76
+
77
+ context 'when logged in' do
78
+ before do
79
+ stub_get('/voices/written').to_return(:body => fixture('voices_written'), :headers => {:content_type => 'text/html'})
80
+ stub_post('/voices/write').to_return(:headers => {:content_type => 'text/html'})
81
+ @croudia = Croudia::Scraper.new
82
+ @croudia.instance_variable_set('@logged_in', true)
83
+ end
84
+
85
+ it 'posts to the correct resource' do
86
+ @croudia.update('Hello')
87
+ a_get('/voices/written').should have_been_made
88
+ a_post('/voices/write').should have_been_made
89
+ end
90
+ end
91
+ end
92
+ end