delicious 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/delicious.gemspec +28 -0
- data/lib/delicious.rb +39 -0
- data/lib/delicious/api_model.rb +26 -0
- data/lib/delicious/bookmarks/api.rb +15 -0
- data/lib/delicious/bookmarks/methods/all.rb +112 -0
- data/lib/delicious/bookmarks/methods/create.rb +57 -0
- data/lib/delicious/bookmarks/methods/delete.rb +23 -0
- data/lib/delicious/bundle.rb +43 -0
- data/lib/delicious/bundles/api.rb +20 -0
- data/lib/delicious/bundles/methods/all.rb +23 -0
- data/lib/delicious/bundles/methods/delete.rb +23 -0
- data/lib/delicious/bundles/methods/find.rb +26 -0
- data/lib/delicious/bundles/methods/set.rb +27 -0
- data/lib/delicious/client.rb +57 -0
- data/lib/delicious/error.rb +6 -0
- data/lib/delicious/post.rb +42 -0
- data/lib/delicious/tag.rb +26 -0
- data/lib/delicious/tags/api.rb +15 -0
- data/lib/delicious/tags/methods/all.rb +24 -0
- data/lib/delicious/tags/methods/delete.rb +23 -0
- data/lib/delicious/tags/methods/rename.rb +24 -0
- data/lib/delicious/version.rb +5 -0
- data/spec/delicious/bookmarks/methods/all_spec.rb +122 -0
- data/spec/delicious/bookmarks/methods/create_spec.rb +120 -0
- data/spec/delicious/bundle_spec.rb +42 -0
- data/spec/delicious/bundles/methods/set_spec.rb +78 -0
- data/spec/delicious/client_spec.rb +189 -0
- data/spec/delicious/post_spec.rb +34 -0
- data/spec/delicious/tags/methods/all_spec.rb +70 -0
- data/spec/delicious/tags/methods/delete_spec.rb +47 -0
- data/spec/delicious/tags/methods/rename_spec.rb +47 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/helpers/request_helper.rb +10 -0
- data/spec/support/shared/api_action.rb +13 -0
- metadata +175 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Bundle do
|
4
|
+
it { should validate_presence_of :name }
|
5
|
+
it { should validate_presence_of :tags }
|
6
|
+
|
7
|
+
describe '#delete' do
|
8
|
+
context 'persisted' do
|
9
|
+
it 'invokes delete with the bundle name on associated client' do
|
10
|
+
client = ::Delicious::Client.new { |c| c.access_token = 'my-access-token' }
|
11
|
+
bundle = described_class.build_persisted client, name: 'mybundle', tags: %w(tag1 tag2)
|
12
|
+
expect(client.bundles).to receive(:delete).with bundle: 'mybundle'
|
13
|
+
bundle.delete
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'not persisted' do
|
18
|
+
it 'throws an error' do
|
19
|
+
bundle = described_class.new name: 'mybundle', tags: %w(tag1 tag2)
|
20
|
+
expect { bundle.delete }.to raise_error('Bundle was not saved yet')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#save' do
|
26
|
+
context 'persisted' do
|
27
|
+
it 'invokes set with bundle attrs on associated client' do
|
28
|
+
client = ::Delicious::Client.new { |c| c.access_token = 'my-access-token' }
|
29
|
+
bundle = described_class.build_persisted client, name: 'mybundle', tags: %w(tag1 tag2)
|
30
|
+
expect(client.bundles).to receive(:set).with('mybundle', %w(tag1 tag2))
|
31
|
+
expect(bundle.save).to eq true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'not persisted' do
|
36
|
+
it 'throws an error' do
|
37
|
+
bundle = described_class.new name: 'mybundle', tags: %w(tag1 tag2)
|
38
|
+
expect { bundle.save }.to raise_error('Bundle was not saved yet')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Bundles::Methods::Set do
|
4
|
+
let(:client) do
|
5
|
+
Delicious::Client.new do |config|
|
6
|
+
config.access_token = 'my-access-token'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#set' do
|
11
|
+
let(:result) { :success }
|
12
|
+
|
13
|
+
let(:bundle) { 'hardware' }
|
14
|
+
let(:tags) { %w(tag1 tag2) }
|
15
|
+
|
16
|
+
let(:method) { :post }
|
17
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/bundles/set' }
|
18
|
+
let(:action) { client.bundles.set bundle, tags }
|
19
|
+
|
20
|
+
let(:success_body) { '<?xml version="1.0" encoding="UTF-8"?><result>ok</result>' }
|
21
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result>tagbundle name is required</result>' }
|
22
|
+
|
23
|
+
before do
|
24
|
+
body = result == :failure ? failure_body : success_body
|
25
|
+
@request = stub_request(method, endpoint)
|
26
|
+
.to_return body: body, headers: {'Content-Type' => 'text/xml; charset=UTF-8'}
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'valid attrs given' do
|
30
|
+
it_behaves_like 'api action'
|
31
|
+
|
32
|
+
it 'sends post to /v1/tags/bundles/set' do
|
33
|
+
action
|
34
|
+
expect(WebMock).to have_requested(:post, endpoint).with do |r|
|
35
|
+
assert_param(r, 'bundle', 'hardware') && assert_param(r, 'tags', 'tag1,tag2')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'ok from server' do
|
40
|
+
it 'returns an instance of Delicious::Bundle' do
|
41
|
+
expect(action).to be_an_instance_of(Delicious::Bundle)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has name' do
|
45
|
+
expect(action.name).to eq 'hardware'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'has tags' do
|
49
|
+
expect(action.tags).to eq %w(tag1 tag2)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'error on server' do
|
54
|
+
let(:result) { :failure }
|
55
|
+
|
56
|
+
it 'throws an error' do
|
57
|
+
expect { action }.to raise_error Delicious::Error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'bundle name omitted' do
|
63
|
+
let(:bundle) { nil }
|
64
|
+
|
65
|
+
it 'throws an error' do
|
66
|
+
expect { action }.to raise_error(Delicious::Error, "Bundle name can't be blank")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'tags are empty' do
|
71
|
+
let(:tags) { nil }
|
72
|
+
|
73
|
+
it 'throws an error' do
|
74
|
+
expect { action }.to raise_error(Delicious::Error, "Please specify at least 1 tag")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Client do
|
4
|
+
let(:client) do
|
5
|
+
described_class.new do |config|
|
6
|
+
config.access_token = 'my-access-token'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'configuration' do
|
11
|
+
it 'sets access_token to my-access-token' do
|
12
|
+
expect(client.access_token).to eq 'my-access-token'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets access_token to another-access-token' do
|
16
|
+
another_client = described_class.new { |config| config.access_token = 'another-access-token' }
|
17
|
+
expect(another_client.access_token).to eq 'another-access-token'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'actions' do
|
22
|
+
let(:result) { :success }
|
23
|
+
let(:success_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="done"/>' }
|
24
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="error adding link"/>' }
|
25
|
+
before do
|
26
|
+
body = result == :failure ? failure_body : success_body
|
27
|
+
@request = stub_request(method, endpoint)
|
28
|
+
.to_return body: body, headers: {'Content-Type' => 'text/xml; charset=UTF-8'}
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#bookmarks' do
|
32
|
+
describe '#delete' do
|
33
|
+
let(:method) { :post }
|
34
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/posts/delete' }
|
35
|
+
let(:action) { client.bookmarks.delete 'http://example.com' }
|
36
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="The url or md5 could not be found."/>' }
|
37
|
+
|
38
|
+
it_behaves_like 'api action'
|
39
|
+
|
40
|
+
it 'sends url=http://example.com' do
|
41
|
+
action
|
42
|
+
expect(WebMock).to have_requested(:post, endpoint).with { |r| assert_param(r, 'url', 'http://example.com') }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'existing URL' do
|
46
|
+
it 'returns true' do
|
47
|
+
expect(action).to eq true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'non-existing URL' do
|
52
|
+
let(:result) { :failure }
|
53
|
+
|
54
|
+
it 'return false' do
|
55
|
+
expect(action).to eq false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#bundles' do
|
62
|
+
describe '#find' do
|
63
|
+
let(:method) { :get }
|
64
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/bundles/all?bundle=hardware' }
|
65
|
+
let(:action) { client.bundles.find 'hardware' }
|
66
|
+
let(:success_body) do
|
67
|
+
<<-EOT
|
68
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
69
|
+
<bundles>
|
70
|
+
<bundle name="hardware" tags="cpu hardware wifi"/>
|
71
|
+
</bundles>
|
72
|
+
EOT
|
73
|
+
end
|
74
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?>' }
|
75
|
+
|
76
|
+
it_behaves_like 'api action'
|
77
|
+
|
78
|
+
it 'sends /v1/tags/bundles/all request' do
|
79
|
+
action
|
80
|
+
expect(WebMock).to have_requested(:get, endpoint)
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'found' do
|
84
|
+
let(:result) { :success }
|
85
|
+
|
86
|
+
it 'returns bundle instance' do
|
87
|
+
expect(action).to be_an_instance_of Delicious::Bundle
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'sets name' do
|
91
|
+
expect(action.name).to eq 'hardware'
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'sets tags' do
|
95
|
+
expect(action.tags).to eq %w(cpu hardware wifi)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'can be deleted' do
|
99
|
+
bundle = action
|
100
|
+
expect(client.bundles).to receive(:delete).with(bundle: bundle.name)
|
101
|
+
bundle.delete
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'not found' do
|
106
|
+
let(:result) { :failure }
|
107
|
+
|
108
|
+
it 'is nil' do
|
109
|
+
expect(action).to be_nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#all' do
|
115
|
+
let(:method) { :get }
|
116
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/bundles/all' }
|
117
|
+
let(:action) { client.bundles.all }
|
118
|
+
let(:success_body) do
|
119
|
+
<<-EOT
|
120
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
121
|
+
<bundles>
|
122
|
+
<bundle name="hardware" tags="cpu hardware wifi"/>
|
123
|
+
<bundle name="software" tags="editor graphics programming"/>
|
124
|
+
</bundles>
|
125
|
+
EOT
|
126
|
+
end
|
127
|
+
|
128
|
+
it_behaves_like 'api action'
|
129
|
+
|
130
|
+
it 'sends /v1/tags/bundles/all request' do
|
131
|
+
action
|
132
|
+
expect(WebMock).to have_requested(:get, endpoint)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'returns array of 2 bundles' do
|
136
|
+
expect(action.count).to eq 2
|
137
|
+
end
|
138
|
+
|
139
|
+
describe 'first' do
|
140
|
+
it 'has name' do
|
141
|
+
expect(action[0].name).to eq 'hardware'
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'has tags' do
|
145
|
+
expect(action[0].tags).to eq %w(cpu hardware wifi)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'can be deleted' do
|
149
|
+
bundle = action[0]
|
150
|
+
expect(client.bundles).to receive(:delete).with(bundle: 'hardware')
|
151
|
+
bundle.delete
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'second' do
|
156
|
+
it 'has name' do
|
157
|
+
expect(action[1].name).to eq 'software'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe '#delete' do
|
164
|
+
let(:method) { :post }
|
165
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/bundles/delete' }
|
166
|
+
let(:action) { client.bundles.delete 'hardware' }
|
167
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="The url or md5 could not be found."/>' }
|
168
|
+
|
169
|
+
it_behaves_like 'api action'
|
170
|
+
|
171
|
+
it 'sends post to /v1/tags/bundles/delete' do
|
172
|
+
action
|
173
|
+
expect(WebMock).to have_requested(:post, endpoint).with { |r| assert_param(r, 'bundle', 'hardware') }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'existing URL' do
|
177
|
+
it 'returns true' do
|
178
|
+
expect(action).to eq true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#tags' do
|
185
|
+
it 'is an instance of Delicious::Tags::Api' do
|
186
|
+
expect(client.tags).to be_an_instance_of Delicious::Tags::Api
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Post do
|
4
|
+
it { should validate_presence_of :url }
|
5
|
+
it { should validate_presence_of :description }
|
6
|
+
|
7
|
+
it 'defaults shared to false' do
|
8
|
+
expect(described_class.new.shared).to eq false
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#delete' do
|
12
|
+
context 'persisted' do
|
13
|
+
before do
|
14
|
+
stub_request(:post, 'https://previous.delicious.com/v1/posts/add')
|
15
|
+
.to_return body: '<?xml version="1.0" encoding="UTF-8"?><result code="done"/>',
|
16
|
+
headers: {'Content-Type' => 'text/xml; charset=UTF-8'}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'invokes delete with the URL on associated client' do
|
20
|
+
client = Delicious::Client.new { |c| c.access_token = 'my-access-token' }
|
21
|
+
post = client.bookmarks.create url: 'http://example.com', description: 'Cool site'
|
22
|
+
expect(client.bookmarks).to receive(:delete).with url: 'http://example.com'
|
23
|
+
post.delete
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'not persisted' do
|
28
|
+
it 'throws an error' do
|
29
|
+
post = described_class.new url: 'http://example.com', description: 'Cool site'
|
30
|
+
expect { post.delete }.to raise_error('Bookmark was not saved yet')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Tags::Methods::All do
|
4
|
+
let(:client) do
|
5
|
+
Delicious::Client.new do |config|
|
6
|
+
config.access_token = 'my-access-token'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#all' do
|
11
|
+
let(:result) { :success }
|
12
|
+
|
13
|
+
let(:method) { :get }
|
14
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/get' }
|
15
|
+
let(:action) { client.tags.all }
|
16
|
+
|
17
|
+
let(:success_body) do
|
18
|
+
<<-EOT
|
19
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
20
|
+
<tags>
|
21
|
+
<tag count="78" tag="ruby"/>
|
22
|
+
<tag count="70" tag="rails"/>
|
23
|
+
<tag count="58" tag="css"/>
|
24
|
+
</tags>
|
25
|
+
EOT
|
26
|
+
end
|
27
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="access denied"/>' }
|
28
|
+
|
29
|
+
before do
|
30
|
+
body = result == :failure ? failure_body : success_body
|
31
|
+
@request = stub_request(method, endpoint)
|
32
|
+
.to_return body: body, headers: {'Content-Type' => 'text/xml; charset=UTF-8'}
|
33
|
+
end
|
34
|
+
|
35
|
+
it_behaves_like 'api action'
|
36
|
+
|
37
|
+
context 'success' do
|
38
|
+
it 'returns 3 tags' do
|
39
|
+
expect(action.count).to eq 3
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'first tag' do
|
43
|
+
subject { action[0] }
|
44
|
+
|
45
|
+
it { should be_an_instance_of Delicious::Tag }
|
46
|
+
|
47
|
+
it 'has name' do
|
48
|
+
expect(subject.name).to eq 'ruby'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'has count' do
|
52
|
+
expect(subject.count).to eq 78
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is possible to delete' do
|
56
|
+
expect(client.tags).to receive(:delete).with 'ruby'
|
57
|
+
subject.delete
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'failure' do
|
63
|
+
let(:result) { :failure }
|
64
|
+
|
65
|
+
it 'throws an error' do
|
66
|
+
expect { action }.to raise_error Delicious::Error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Delicious::Tags::Methods::Delete do
|
4
|
+
let(:client) do
|
5
|
+
Delicious::Client.new do |config|
|
6
|
+
config.access_token = 'my-access-token'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#delete' do
|
11
|
+
let(:result) { :success }
|
12
|
+
|
13
|
+
let(:method) { :post }
|
14
|
+
let(:endpoint) { 'https://previous.delicious.com/v1/tags/delete' }
|
15
|
+
let(:action) { client.tags.delete 'ruby' }
|
16
|
+
|
17
|
+
let(:success_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="done"/>' }
|
18
|
+
let(:failure_body) { '<?xml version="1.0" encoding="UTF-8"?><result code="done"/>' }
|
19
|
+
|
20
|
+
before do
|
21
|
+
body = result == :failure ? failure_body : success_body
|
22
|
+
@request = stub_request(method, endpoint)
|
23
|
+
.to_return body: body, headers: {'Content-Type' => 'text/xml; charset=UTF-8'}
|
24
|
+
end
|
25
|
+
|
26
|
+
it_behaves_like 'api action'
|
27
|
+
|
28
|
+
it 'sends request' do
|
29
|
+
action
|
30
|
+
expect(WebMock).to have_requested(:post, endpoint).with { |r| assert_param(r, 'tag', 'ruby') }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'success' do
|
34
|
+
it 'return true' do
|
35
|
+
expect(action).to eq true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'failure' do
|
40
|
+
let(:result) { :failure }
|
41
|
+
|
42
|
+
it 'return true' do
|
43
|
+
expect(action).to eq true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|