kiita 0.1.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.
@@ -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