kiita 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ module Kiita
2
+ class Post
3
+ include Kiita::Model
4
+ attr_reader :uuid
5
+
6
+ cattr_reader :attributes
7
+ @@attributes = %w[
8
+ id title body created_at updated_at created_at_in_words updated_at_in_words
9
+ stock_count stock_users comment_count url gist_url private stocked
10
+ ]
11
+
12
+ define_attributes @@attributes, Proc.new{ Kiita::API.get("/items/#{uuid}") }
13
+
14
+ def initialize(uuid, options = {})
15
+ if uuid.is_a?(Hash)
16
+ options = uuid
17
+ @uuid = options["uuid"]
18
+ else
19
+ @uuid = uuid
20
+ end
21
+
22
+ super(options)
23
+ end
24
+
25
+ def self.all(options = {})
26
+ Kiita::API.get("/items", options).map{|post| Kiita::Post.new(post) }
27
+ end
28
+
29
+ def self.search(keyword, options = {})
30
+ Kiita::API.get("/search", options.merge!(q: keyword)).map{|post| Kiita::Post.new(post) }
31
+ end
32
+
33
+ def self.lazy_load(uuid)
34
+ new(uuid)
35
+ end
36
+
37
+ def self.find(uuid)
38
+ new(uuid, Kiita::API.get("/items/#{uuid}").merge!(loaded: true))
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,30 @@
1
+ module Kiita
2
+ class Tag
3
+ include Kiita::Model
4
+ attr_reader :url_name
5
+
6
+ cattr_reader :attributes
7
+ @@attributes = %w[name icon_url item_count follower_count following]
8
+
9
+ define_attributes @@attributes, -> { Hash.new }
10
+
11
+ def initialize(url_name, options = {})
12
+ if url_name.is_a?(Hash)
13
+ options = url_name
14
+ @url_name = options["url_name"]
15
+ else
16
+ @url_name = url_name
17
+ end
18
+
19
+ super(options)
20
+ end
21
+
22
+ def posts(options = {})
23
+ Kiita::API.get("/tags/#{url_name}/items", options).map{|post| Kiita::Post.new(post) }
24
+ end
25
+
26
+ def self.all(options = {})
27
+ Kiita::API.get("/tags", options).map{|tag| Kiita::Tag.new(tag) }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ module Kiita
2
+ class User
3
+ include Kiita::Model
4
+ attr_reader :url_name
5
+
6
+ cattr_reader :attributes
7
+ @@attributes = %w[
8
+ name profile_image_url url description website_url organization location
9
+ facebook linkedin twitter github followers following_users items
10
+ ]
11
+
12
+ define_attributes @@attributes, Proc.new{ Kiita::API.get("/users/#{url_name}") }
13
+
14
+ def initialize(url_name, options = {})
15
+ if url_name.is_a?(Hash)
16
+ options = url_name
17
+ @url_name = options["url_name"]
18
+ else
19
+ @url_name = url_name
20
+ end
21
+
22
+ super(options)
23
+ end
24
+
25
+ def posts(options = {})
26
+ @posts ||= Kiita::API.get("/users/#{url_name}/items", options).map do |post|
27
+ Kiita::Post.new(post)
28
+ end
29
+ end
30
+
31
+ def stocks(options = {})
32
+ @stocks ||= Kiita::API.get("/users/#{url_name}/stocks", options).map do |post|
33
+ Kiita::Post.new(post)
34
+ end
35
+ end
36
+
37
+ def following_users(options = {})
38
+ @following_users ||= Kiita::API.get("/users/#{url_name}/following_users", options).map do |user|
39
+ Kiita::User.new(user)
40
+ end
41
+ end
42
+
43
+ def following_tags(options = {})
44
+ @following_tags ||= Kiita::API.get("/users/#{url_name}/following_tags", options).map do |tag|
45
+ Kiita::Tag.new(tag)
46
+ end
47
+ end
48
+
49
+ def self.lazy_load(url_name)
50
+ new(url_name)
51
+ end
52
+
53
+ def self.find(url_name)
54
+ new(url_name, Kiita::API.get("/users/#{url_name}").merge!(loaded: true))
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module Kiita
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,301 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Kiita::API do
5
+ def qiita_api_response(path)
6
+ File.new("#{File.dirname(__FILE__)}/../support/api_responses/#{path}")
7
+ end
8
+
9
+ describe "Initialization" do
10
+ context "without any options" do
11
+ subject { Kiita::API.new }
12
+ it { should be_a Kiita::API }
13
+ its(:token) { should be_nil }
14
+ end
15
+
16
+ context "without an token option" do
17
+ subject { Kiita::API.new(token: "token") }
18
+ its(:token) { should == "token" }
19
+ end
20
+ end
21
+
22
+ describe "Basic API" do
23
+ describe "class methods" do
24
+ describe "#get" do
25
+ before{ @stub = stub_request(:get, "https://qiita.com/api/v1/?") }
26
+ after { @stub.should have_been_requested }
27
+
28
+ it("makes a get request without token"){ Kiita::API.get("/") }
29
+ end
30
+
31
+ describe "#post" do
32
+ before{ @stub = stub_request(:post, "https://qiita.com/api/v1/") }
33
+ after { @stub.should have_been_requested }
34
+
35
+ it("makes a post request without token"){ Kiita::API.post("/") }
36
+ end
37
+
38
+ describe "#put" do
39
+ before{ @stub = stub_request(:put, "https://qiita.com/api/v1/") }
40
+ after { @stub.should have_been_requested }
41
+
42
+ it("makes a put request without token"){ Kiita::API.put("/") }
43
+ end
44
+
45
+ describe "#delete" do
46
+ before{ @stub = stub_request(:delete, "https://qiita.com/api/v1/") }
47
+ after { @stub.should have_been_requested }
48
+
49
+ it("makes a delete request without token"){ Kiita::API.delete("/") }
50
+ end
51
+ end
52
+
53
+ describe "instance methods" do
54
+ describe "#get" do
55
+ before{ @stub = stub_request(:get, "https://qiita.com/api/v1/?token=token") }
56
+ after { @stub.should have_been_requested }
57
+
58
+ it("makes a get request with token"){ Kiita::API.new(token: "token").get("/") }
59
+ end
60
+
61
+ describe "#post" do
62
+ before{ @stub = stub_request(:post, "https://qiita.com/api/v1/?token=token") }
63
+ after { @stub.should have_been_requested }
64
+
65
+ it("makes a post request with token"){ Kiita::API.new(token: "token").post("/") }
66
+ end
67
+
68
+ describe "#put" do
69
+ before{ @stub = stub_request(:put, "https://qiita.com/api/v1/?token=token") }
70
+ after { @stub.should have_been_requested }
71
+
72
+ it("makes a put request with token"){ Kiita::API.new(token: "token").put("/") }
73
+ end
74
+
75
+ describe "#delete" do
76
+ before{ @stub = stub_request(:delete, "https://qiita.com/api/v1/?token=token") }
77
+ after { @stub.should have_been_requested }
78
+
79
+ it("makes a delete request with token"){ Kiita::API.new(token: "token").delete("/") }
80
+ end
81
+ end
82
+
83
+ describe "errors" do
84
+ use_vcr_cassette "qiita/public_apis", record: :new_episodes
85
+
86
+ it "raises BadRequest error" do
87
+ expect{ Kiita::API.post("/auth") }.to raise_exception(Kiita::BadRequest)
88
+ end
89
+
90
+ it "raises NotFound error" do
91
+ expect{ Kiita::API.get("/notfound") }.to raise_exception(Kiita::NotFound)
92
+ end
93
+ end
94
+ end
95
+
96
+ describe "Methods that don't require authentication" do
97
+ use_vcr_cassette "qiita/public_apis", record: :new_episodes
98
+
99
+ describe "#rate_limit" do
100
+ specify { Kiita::API.rate_limit["remaining"].should be_a Fixnum }
101
+ specify { Kiita::API.rate_limit["limit"].should be_a Fixnum }
102
+ end
103
+
104
+ describe "#authenticate" do
105
+ context "with a url name and a password" do
106
+ before { stub_request(:post, /^https:\/\/qiita.com/).to_return(body: qiita_api_response("auth.json")) }
107
+ let(:auth_result) { Kiita::API.authenticate("user", "hogehoge") }
108
+ subject { auth_result }
109
+ it { should be_a Hash }
110
+ specify { auth_result["token"].should == "1afb7c91b2a049e1a7981cbd234v5hg" }
111
+ end
112
+ end
113
+
114
+ describe "#user" do
115
+ subject { Kiita::API.user("yaotti") }
116
+ it { should be_a Kiita::User }
117
+ its(:url_name){ should == "yaotti" }
118
+ its(:name) { should == "やおっち/Hiroshige Umino" }
119
+
120
+ describe "#posts created by the user" do
121
+ context "without options" do
122
+ subject { Kiita::API.user("yaotti").posts }
123
+ it { should be_an Array }
124
+ its(:first) { should be_a Kiita::Post }
125
+ end
126
+
127
+ context "page 2 per 10 items" do
128
+ subject { Kiita::API.user("yaotti").posts(page: 2, per_page: 10) }
129
+ its(:size) { should == 10 }
130
+ end
131
+ end
132
+
133
+ describe "#stocks created by the user" do
134
+ context "without options" do
135
+ subject { Kiita::API.user("yaotti").stocks }
136
+ it { should be_an Array }
137
+ its(:first) { should be_a Kiita::Post }
138
+ end
139
+
140
+ context "page 2 per 10 items" do
141
+ subject { Kiita::API.user("yaotti").stocks(page: 2, per_page: 10) }
142
+ its(:size) { should == 10 }
143
+ end
144
+ end
145
+
146
+ describe "#following_users" do
147
+ context "without options" do
148
+ subject { Kiita::API.user("yaotti").following_users }
149
+ it { should be_an Array }
150
+ its(:first) { should be_a Kiita::User }
151
+ end
152
+
153
+ context "page 2 per 10 items" do
154
+ subject { Kiita::API.user("yaotti").following_users(page: 2, per_page: 10) }
155
+ its(:size) { should == 10 }
156
+ end
157
+ end
158
+
159
+ describe "#following_tags" do
160
+ context "without options" do
161
+ subject { Kiita::API.user("yaotti").following_tags }
162
+ it { should be_an Array }
163
+ its(:first) { should be_a Kiita::Tag }
164
+ end
165
+
166
+ context "page 2 per 10 items" do
167
+ subject { Kiita::API.user("yaotti").following_tags(page: 2, per_page: 10) }
168
+ its(:size) { should == 10 }
169
+ end
170
+ end
171
+ end
172
+
173
+ describe "#post" do
174
+ subject { Kiita::API.item("2e6258b7c6a5b13b7d16") }
175
+ it { should be_a Kiita::Post }
176
+ its(:uuid) { should == "2e6258b7c6a5b13b7d16" }
177
+ its(:id) { should == 1408 }
178
+ its(:title){ should == "インストールされている gem を全て削除する。" }
179
+ end
180
+
181
+ describe "#posts" do
182
+ context "without options" do
183
+ subject { Kiita::API.items }
184
+ it { should be_an Array }
185
+ its(:first) { should be_a Kiita::Post }
186
+ end
187
+
188
+ context "page 2 per 10 items" do
189
+ subject { Kiita::API.items(page: 2, per_page: 10) }
190
+ its(:size) { should == 10 }
191
+ end
192
+ end
193
+
194
+ describe "#search" do
195
+ context "without options" do
196
+ subject { Kiita::API.search("Ruby") }
197
+ it { should be_an Array }
198
+ its(:first) { should be_a Kiita::Post }
199
+ end
200
+
201
+ context "page 2 per 10 items" do
202
+ subject { Kiita::API.search("Ruby", page: 2, per_page: 10) }
203
+ its(:size) { should == 10 }
204
+ end
205
+ end
206
+
207
+ describe "#tags" do
208
+ context "without options" do
209
+ subject { Kiita::API.tags }
210
+ it { should be_an Array }
211
+ its(:first) { should be_a Kiita::Tag }
212
+ end
213
+
214
+ context "page 2 per 10 tags" do
215
+ subject { Kiita::API.tags(page: 2, per_page: 10) }
216
+ its(:size) { should == 10 }
217
+ end
218
+
219
+ describe "#posts associated to the tag" do
220
+ context "without options" do
221
+ subject { Kiita::API.tag("ruby").posts }
222
+ it { should be_an Array }
223
+ its(:first) { should be_a Kiita::Post }
224
+ end
225
+
226
+ context "page 2 per 10 items" do
227
+ subject { Kiita::API.tag("ruby").posts(page: 2, per_page: 10) }
228
+ its(:size) { should == 10 }
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ describe "APIs that require authentication" do
235
+ let(:client) { Kiita::API.new(token: "token") }
236
+
237
+ describe "#me" do
238
+ before { stub_request(:get, /^https:\/\/qiita.com/).to_return(body: qiita_api_response("user.json")) }
239
+ subject { client.me }
240
+ it { should be_a Kiita::User }
241
+ its(:name) { should == "Test User" }
242
+ end
243
+
244
+ describe "#search" do
245
+ context "with stocked option" do
246
+ before { stub_request(:get, /^https:\/\/qiita.com/).to_return(body: qiita_api_response("search.json")) }
247
+ subject { client.search("Ruby", stocked: 'true') }
248
+ it { should be_an Array }
249
+ its(:first) { should be_a Kiita::Post }
250
+ end
251
+
252
+ context "with stocked option, page 2 and per 10 items" do
253
+ before do
254
+ @stub = stub_request(:get, "https://qiita.com/api/v1/search?page=2&per_page=10&q=Ruby&stocked=true&token=token")
255
+ .to_return(body: qiita_api_response("search.json"))
256
+ end
257
+ after { @stub.should have_been_requested }
258
+ it("calls Search API with options"){ client.search("Ruby", stocked: 'true', page: 2, per_page: 10) }
259
+ end
260
+ end
261
+ =begin
262
+ describe "#save a post" do
263
+ end
264
+
265
+ describe "#update a post" do
266
+ end
267
+
268
+ describe "#destroy a post" do
269
+ end
270
+ =end
271
+ describe "#stocks" do
272
+ context "without options" do
273
+ before { stub_request(:get, /^https:\/\/qiita.com/).to_return(body: qiita_api_response("user_stocks.json")) }
274
+ subject { client.stocks }
275
+ it { should be_an Array }
276
+ its(:first) { should be_a Kiita::Post }
277
+ end
278
+
279
+ context "page 2 per 10 items" do
280
+ before do
281
+ @stub = stub_request(:get, "https://qiita.com/api/v1/stocks?page=2&per_page=10&token=token")
282
+ .to_return(body: qiita_api_response("user_stocks.json"))
283
+ end
284
+ after { @stub.should have_been_requested }
285
+ it("calls User Stocks API with options"){ client.stocks(page: 2, per_page: 10) }
286
+ end
287
+ end
288
+
289
+ describe "#stock! a post" do
290
+ before { stub_request(:put, /^https:\/\/qiita.com/).to_return(body: '') }
291
+ subject { client.stock!("2e6258b7c6a5b13b7d16") }
292
+ it { should be_true }
293
+ end
294
+
295
+ describe "#unstock! a post" do
296
+ before { stub_request(:delete, /^https:\/\/qiita.com/).to_return(body: '') }
297
+ subject { client.unstock!("2e6258b7c6a5b13b7d16") }
298
+ it { should be_true }
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Kiita::Errors do
4
+ # nothing to test
5
+ end
@@ -0,0 +1,64 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe Kiita::Post do
5
+ use_vcr_cassette "qiita/item_api", record: :new_episodes
6
+
7
+ describe "initialization" do
8
+ context "with valid attrs" do
9
+ let(:valid_attrs) do
10
+ {
11
+ "id" => 1408,
12
+ "title" => "インストールされている gem を全て削除する。",
13
+ "body" => "I'm a body!",
14
+ "created_at" => "2011-12-19 00:04:14 +0900",
15
+ "updated_at" => "2012-03-16 11:30:26 +0900",
16
+ "created_at_in_words" => "10ヶ月前",
17
+ "updated_at_in_words" => "7ヶ月前",
18
+ "stock_count" => 100,
19
+ "stock_users" => ["testuser"],
20
+ "comment_count" => 100,
21
+ "url" => "http://qiita.com/items/2e6258b7c6a5b13b7d16",
22
+ "gist_url" => nil,
23
+ "private" => false,
24
+ "stocked" => nil
25
+ }
26
+ end
27
+
28
+ subject { Kiita::Post.new(valid_attrs) }
29
+ its(:id) { should == 1408 }
30
+ its(:title) { should == "インストールされている gem を全て削除する。" }
31
+ its(:body) { should be_a String }
32
+ its(:created_at) { should == "2011-12-19 00:04:14 +0900" }
33
+ its(:updated_at) { should == "2012-03-16 11:30:26 +0900" }
34
+ its(:created_at_in_words){ should include "ヶ月前" }
35
+ its(:updated_at_in_words){ should include "7ヶ月前" }
36
+ its(:stock_count) { should be_a Fixnum }
37
+ its(:stock_users) { should be_an Array }
38
+ its(:comment_count) { should be_a Fixnum }
39
+ its(:url) { should == "http://qiita.com/items/2e6258b7c6a5b13b7d16" }
40
+ its(:gist_url) { should be_nil }
41
+ its(:private) { should be_false }
42
+ its(:stocked) { should be_nil }
43
+ end
44
+ end
45
+
46
+ describe "#find" do
47
+ subject { Kiita::Post.find("2e6258b7c6a5b13b7d16") }
48
+
49
+ its(:id) { should == 1408 }
50
+ its(:title) { should == "インストールされている gem を全て削除する。" }
51
+ its(:body) { should be_a String }
52
+ its(:created_at) { should == "2011-12-19 00:04:14 +0900" }
53
+ its(:updated_at) { should == "2012-03-16 11:30:26 +0900" }
54
+ its(:created_at_in_words){ should include "ヶ月前" }
55
+ its(:updated_at_in_words){ should include "7ヶ月前" }
56
+ its(:stock_count) { should be_a Fixnum }
57
+ its(:stock_users) { should be_an Array }
58
+ its(:comment_count) { should be_a Fixnum }
59
+ its(:url) { should == "http://qiita.com/items/2e6258b7c6a5b13b7d16" }
60
+ its(:gist_url) { should be_nil }
61
+ its(:private) { should be_false }
62
+ its(:stocked) { should be_nil }
63
+ end
64
+ end