delicious 1.0.0
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/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
|