mediawiki_api 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61335636d79746833c9ce6320e349c4ddc3b0eb0
4
- data.tar.gz: 50ff419bf6cff5deacd013c516e8dbfe611b8b57
3
+ metadata.gz: 47ada7ae6cca60fe668ec85a2db600bc2c8476d3
4
+ data.tar.gz: 1404eb28565f5c58106dd534426a1d29de9686bb
5
5
  SHA512:
6
- metadata.gz: 8e49ec787cc5313d0db2206062202e350b6c06f4497681a85aed857252518515fde8f5b1c6dedcb113bb246d599d366b1b1fcec4b3ec0114bf935e506e5d2695
7
- data.tar.gz: e674171587b3975ad3d5b14ab0a3527b4160d03336ee8b07cf107f88b6bf98a1190197b79e2357d2967da88fa4a1e38196631e662ca76a0cdf2b9cf402c1759e
6
+ metadata.gz: d19e7cceb2b8436cfcae8198eba6d220ef333bf8b9397328929dec24a7b68bd738e24118b4994d60c19639514d3f85fc636bcef525ba5ce9a038d20555274b91
7
+ data.tar.gz: d1911e5759b7ac06de105c3728c7afbb50a3eec5e79549dfe2d92bdbe45f861ea91cc7d1827a40032350867a274feca6cbe8aee9f0fbca1763c9465b67f3390c
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .bundle/
2
+ .ruby-version
3
+ .ruby-gemset
4
+ .gem
5
+ Gemfile.lock
6
+ *.gem
data/CREDITS CHANGED
@@ -7,6 +7,7 @@ For further details on licensing, see the LICENSE file.
7
7
  == Developers ==
8
8
  * Amir Aharoni
9
9
  * Chris McMahon
10
+ * Dan Duvall
10
11
  * Jeff Hall
11
12
  * Juliusz Gonera
12
13
  * Željko Filipin
data/README.md CHANGED
@@ -32,8 +32,17 @@ client.get_wikitext "title"
32
32
  client.protect_page "title", "reason", "protections" # protections are optional, default is "edit=sysop|move=sysop"
33
33
  client.delete_page "title", "reason"
34
34
  client.upload_image "filename", "path", "comment", "ignorewarnings"
35
+ client.meta :siteinfo, siprop: "extensions"
36
+ client.prop :info, titles: "Some page"
37
+ client.query titles: ["Some page", "Some other page"]
35
38
  ```
36
39
 
40
+ ## Advanced Usage
41
+
42
+ Any API action can be requested using `#action`. See the
43
+ [MediaWiki API documentation](http://www.mediawiki.org/wiki/API) for supported
44
+ actions and parameters.
45
+
37
46
  ## Links
38
47
 
39
48
  MediaWiki API gem at: [Gerrit](https://gerrit.wikimedia.org/r/#/admin/projects/mediawiki/ruby/api), [GitHub](https://github.com/wikimedia/mediawiki-ruby-api), [RubyGems](https://rubygems.org/gems/mediawiki_api), [Code Climate](https://codeclimate.com/github/wikimedia/mediawiki-ruby-api).
@@ -49,7 +58,15 @@ MediaWiki API gem at: [Gerrit](https://gerrit.wikimedia.org/r/#/admin/projects/m
49
58
 
50
59
  ## Release notes
51
60
 
52
- ### 0.1.4 2014-07-??
61
+ ### 0.2.0 2014-08-06
62
+
63
+ - Automatic response parsing.
64
+ - Handling of API error responses.
65
+ - Watch/unwatch support.
66
+ - Query support.
67
+ - Public MediawikiApi::Client#action method for advanced API use.
68
+
69
+ ### 0.1.4 2014-07-18
53
70
 
54
71
  - Added MediawikiApi::Client#protect_page.
55
72
  - Updated documentation.
@@ -2,19 +2,17 @@ require "faraday"
2
2
  require "faraday-cookie_jar"
3
3
  require "json"
4
4
 
5
- module MediawikiApi
6
- class LoginError < StandardError
7
- end
8
-
9
- class CreateAccountError < StandardError
10
- end
11
-
12
- class TokenError < StandardError
13
- end
5
+ require "mediawiki_api/exceptions"
6
+ require "mediawiki_api/response"
14
7
 
8
+ module MediawikiApi
15
9
  class Client
10
+ FORMAT = "json"
11
+
16
12
  attr_accessor :logged_in
17
13
 
14
+ alias logged_in? logged_in
15
+
18
16
  def initialize(url, log = false)
19
17
  @conn = Faraday.new(url: url) do |faraday|
20
18
  faraday.request :multipart
@@ -24,76 +22,140 @@ module MediawikiApi
24
22
  faraday.adapter Faraday.default_adapter
25
23
  end
26
24
  @logged_in = false
25
+ @tokens = {}
27
26
  end
28
27
 
29
- def log_in(username, password, token = nil)
30
- params = { action: "login", lgname: username, lgpassword: password, format: "json" }
31
- params[:lgtoken] = token unless token.nil?
32
- resp = @conn.post "", params
28
+ def action(name, params = {})
29
+ name = name.to_s
33
30
 
34
- data = JSON.parse(resp.body)["login"]
31
+ method = params.delete(:http_method) || :post
32
+ token_type = params.delete(:token_type)
33
+ envelope = (params.delete(:envelope) || [name]).map(&:to_s)
35
34
 
36
- case data["result"]
37
- when "Success"
38
- @logged_in = true
39
- when "NeedToken"
40
- log_in username, password, data["token"]
41
- else
42
- raise LoginError, data["result"]
35
+ params[:token] = get_token(token_type || name) unless token_type == false
36
+ params = compile_parameters(params)
37
+
38
+ response = @conn.send(method, "", params.merge(action: name, format: FORMAT))
39
+
40
+ if response.headers.include?("mediawiki-api-error")
41
+ raise ApiError.new(Response.new(response, ["error"]))
43
42
  end
43
+
44
+ Response.new(response, envelope)
44
45
  end
45
46
 
46
47
  def create_account(username, password, token = nil)
47
- params = { action: "createaccount", name: username, password: password, format: "json" }
48
+ params = { name: username, password: password, token_type: false }
48
49
  params[:token] = token unless token.nil?
49
- resp = @conn.post "", params
50
50
 
51
- data = JSON.parse(resp.body)["createaccount"]
51
+ data = action(:createaccount, params).data
52
52
 
53
53
  case data["result"]
54
54
  when "Success"
55
55
  @logged_in = true
56
+ @tokens.clear
56
57
  when "NeedToken"
57
- create_account username, password, data["token"]
58
+ data = create_account(username, password, data["token"])
58
59
  else
59
60
  raise CreateAccountError, data["result"]
60
61
  end
62
+
63
+ data
61
64
  end
62
65
 
63
66
  def create_page(title, content)
64
- token = get_token "edit"
65
- @conn.post "", action: "edit", title: title, text: content, token: token, format: "json"
67
+ action(:edit, title: title, text: content)
66
68
  end
67
69
 
68
70
  def delete_page(title, reason)
69
- token = get_token "delete"
70
- @conn.post "", action: "delete", title: title, reason: reason, token: token, format: "json"
71
- end
72
-
73
- def upload_image(filename, path, comment, ignorewarnings)
74
- token = get_token "edit"
75
- @conn.post "", action: "upload", filename: filename, file: Faraday::UploadIO.new(path, 'image/png'), token: token, comment: comment, ignorewarnings: ignorewarnings, format: "json"
71
+ action(:delete, title: title, reason: reason)
76
72
  end
77
73
 
78
74
  def get_wikitext(title)
79
75
  @conn.get "/w/index.php", { action: "raw", title: title }
80
76
  end
81
77
 
82
- def protect_page(title, reason, protections="edit=sysop|move=sysop")
83
- token = get_token "protect"
84
- @conn.post "", action: "protect", title: title, reason: reason, token: token, format: "json", protections: protections
78
+ def list(type, params = {})
79
+ subquery(:list, type, params)
80
+ end
81
+
82
+ def log_in(username, password, token = nil)
83
+ params = { lgname: username, lgpassword: password, token_type: false }
84
+ params[:lgtoken] = token unless token.nil?
85
+
86
+ data = action(:login, params).data
87
+
88
+ case data["result"]
89
+ when "Success"
90
+ @logged_in = true
91
+ @tokens.clear
92
+ when "NeedToken"
93
+ data = log_in(username, password, data["token"])
94
+ else
95
+ raise LoginError, data["result"]
96
+ end
97
+
98
+ data
99
+ end
100
+
101
+ def meta(type, params = {})
102
+ subquery(:meta, type, params)
103
+ end
104
+
105
+ def prop(type, params = {})
106
+ subquery(:prop, type, params)
107
+ end
108
+
109
+ def protect_page(title, reason, protections = "edit=sysop|move=sysop")
110
+ action(:protect, title: title, reason: reason, protections: protections)
111
+ end
112
+
113
+ def query(params = {})
114
+ action(:query, { token_type: false, http_method: :get }.merge(params))
115
+ end
116
+
117
+ def unwatch_page(title)
118
+ action(:watch, titles: title, unwatch: true)
119
+ end
120
+
121
+ def upload_image(filename, path, comment, ignorewarnings)
122
+ file = Faraday::UploadIO.new(path, "image/png")
123
+ action(:upload, token_type: "edit", filename: filename, file: file, comment: comment, ignorewarnings: ignorewarnings)
124
+ end
125
+
126
+ def watch_page(title)
127
+ action(:watch, titles: title)
85
128
  end
86
129
 
87
130
  protected
88
131
 
132
+ def compile_parameters(parameters)
133
+ parameters.each.with_object({}) do |(name, value), params|
134
+ case value
135
+ when false
136
+ # omit it entirely
137
+ when Array
138
+ params[name] = value.join("|")
139
+ else
140
+ params[name] = value
141
+ end
142
+ end
143
+ end
144
+
89
145
  def get_token(type)
90
- resp = @conn.get "", { action: "tokens", type: type, format: "json" }
91
- token_data = JSON.parse(resp.body)
92
- if token_data.has_key?("warnings")
93
- raise TokenError, token_data["warnings"]
94
- else
95
- token_data["tokens"][type + "token"]
146
+ unless @tokens.include?(type)
147
+ response = action(:tokens, type: type, http_method: :get, token_type: false)
148
+
149
+ raise TokenError, response.warnings.join(", ") if response.warnings?
150
+
151
+ @tokens[type] = response.data["#{type}token"]
96
152
  end
153
+
154
+ @tokens[type]
155
+ end
156
+
157
+ def subquery(type, subtype, params = {})
158
+ query(params.merge(type.to_sym => subtype, :envelope => ["query", subtype]))
97
159
  end
98
160
  end
99
161
  end
@@ -0,0 +1,36 @@
1
+ module MediawikiApi
2
+ class ApiError < StandardError
3
+ attr_reader :response
4
+
5
+ def initialize(response)
6
+ @response = response
7
+ end
8
+
9
+ def code
10
+ data["code"]
11
+ end
12
+
13
+ def info
14
+ data["info"]
15
+ end
16
+
17
+ def to_s
18
+ "#{info} (#{code})"
19
+ end
20
+
21
+ private
22
+
23
+ def data
24
+ @response.data || {}
25
+ end
26
+ end
27
+
28
+ class CreateAccountError < StandardError
29
+ end
30
+
31
+ class LoginError < StandardError
32
+ end
33
+
34
+ class TokenError < StandardError
35
+ end
36
+ end
@@ -0,0 +1,88 @@
1
+ require "forwardable"
2
+ require "json"
3
+
4
+ module MediawikiApi
5
+ # Provides access to a parsed MediaWiki API responses.
6
+ #
7
+ # Some types of responses, depending on the action, contain a level or two
8
+ # of addition structure (an envelope) above the actual payload. The {#data}
9
+ # method provides a way of easily getting at it.
10
+ #
11
+ # @example
12
+ # # http.body => '{"query": {"userinfo": {"some": "data"}}}'
13
+ # response = Response.new(http, ["query", "userinfo"])
14
+ # response.data # => { "some" => "data" }
15
+ #
16
+ class Response
17
+ extend Forwardable
18
+
19
+ def_delegators :@response, :status, :success?
20
+
21
+ # Constructs a new response.
22
+ #
23
+ # @param response [Faraday::Response]
24
+ # @param envelope [Array] Property names for expected payload nesting.
25
+ #
26
+ def initialize(response, envelope = [])
27
+ @response = response
28
+ @envelope = envelope
29
+ end
30
+
31
+ # Accessor for root response object values.
32
+ #
33
+ # @param key [String]
34
+ #
35
+ # @return [Object]
36
+ #
37
+ def [](key)
38
+ response_object[key]
39
+ end
40
+
41
+ # The main payload from the parsed response, removed from its envelope.
42
+ #
43
+ # @return [Object]
44
+ #
45
+ def data
46
+ case response_object
47
+ when Hash
48
+ open_envelope(response_object)
49
+ else
50
+ response_object
51
+ end
52
+ end
53
+
54
+ # Set of warning messages from the response.
55
+ #
56
+ # @return [Array]
57
+ #
58
+ def warnings
59
+ if response_object["warnings"]
60
+ response_object["warnings"].values.map(&:values).flatten
61
+ else
62
+ []
63
+ end
64
+ end
65
+
66
+ # Whether the response contains warnings.
67
+ #
68
+ # @return [true, false]
69
+ #
70
+ def warnings?
71
+ !warnings.empty?
72
+ end
73
+
74
+ private
75
+
76
+ def open_envelope(obj, env = @envelope)
77
+ if !obj.is_a?(Hash) || env.nil? || env.empty? || !obj.include?(env.first)
78
+ obj
79
+ else
80
+ open_envelope(obj[env.first], env[1..-1])
81
+ end
82
+ end
83
+
84
+ def response_object
85
+ @response_object ||= JSON.parse(@response.body)
86
+ end
87
+ end
88
+ end
@@ -1,3 +1,3 @@
1
1
  module MediawikiApi
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -6,8 +6,8 @@ require "mediawiki_api/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "mediawiki_api"
8
8
  spec.version = MediawikiApi::VERSION
9
- spec.authors = ["Amir Aharoni", "Chris McMahon", "Jeff Hall", "Juliusz Gonera", "Zeljko Filipin"]
10
- spec.email = ["amir.aharoni@mail.huji.ac.il", "cmcmahon@wikimedia.org", "jhall@wikimedia.org", "jgonera@wikimedia.org", "zeljko.filipin@gmail.com"]
9
+ spec.authors = ["Amir Aharoni", "Chris McMahon", "Dan Duvall", "Jeff Hall", "Juliusz Gonera", "Zeljko Filipin"]
10
+ spec.email = ["amir.aharoni@mail.huji.ac.il", "cmcmahon@wikimedia.org", "dduvall@wikimedia.org", "jhall@wikimedia.org", "jgonera@wikimedia.org", "zeljko.filipin@gmail.com"]
11
11
  spec.summary = %q{A library for interacting with MediaWiki API from Ruby.}
12
12
  spec.description = %q{Uses adapter-agnostic Faraday gem to talk to MediaWiki API.}
13
13
  spec.homepage = "https://github.com/wikimedia/mediawiki-ruby-api"
data/spec/client_spec.rb CHANGED
@@ -1,9 +1,112 @@
1
1
  require "spec_helper"
2
+ require "webmock/rspec"
3
+ require "support/request_helpers"
2
4
 
3
5
  describe MediawikiApi::Client do
4
- subject { MediawikiApi::Client.new(api_url) }
6
+ include MediawikiApi::RequestHelpers
7
+
8
+ let(:client) { MediawikiApi::Client.new(api_url) }
9
+
10
+ subject { client }
11
+
5
12
  body_base = { cookieprefix: "prefix", sessionid: "123" }
6
13
 
14
+ describe "#action" do
15
+ subject { client.action(action, params) }
16
+
17
+ let(:action) { "something" }
18
+ let(:params) { {} }
19
+
20
+ let(:response) { { headers: response_headers, body: response_body.to_json } }
21
+ let(:response_headers) { nil }
22
+ let(:response_body) { { "something" => {} } }
23
+
24
+ before do
25
+ @token_request = stub_token_request(action)
26
+ @request = stub_api_request(:post, action: action, token: mock_token).to_return(response)
27
+ end
28
+
29
+ it { is_expected.to be_a(MediawikiApi::Response) }
30
+
31
+ it "makes requests for both the right token and API action" do
32
+ subject
33
+ expect(@token_request).to have_been_made
34
+ expect(@request).to have_been_made
35
+ end
36
+
37
+ context "without a required token" do
38
+ let(:params) { { token_type: false } }
39
+
40
+ before do
41
+ @request_with_token = @request
42
+ @request_without_token = stub_api_request(:post, action: action).to_return(response)
43
+ end
44
+
45
+ it "does not request a token" do
46
+ subject
47
+ expect(@token_request).to_not have_been_made
48
+ end
49
+
50
+ it "makes the action request without a token" do
51
+ subject
52
+ expect(@request_without_token).to have_been_made
53
+ expect(@request_with_token).to_not have_been_made
54
+ end
55
+ end
56
+
57
+ context "given parameters" do
58
+ let(:params) { { foo: "value" } }
59
+
60
+ before do
61
+ @request_with_parameters = stub_action_request(action, foo: "value").to_return(response)
62
+ end
63
+
64
+ it "includes them" do
65
+ subject
66
+ expect(@request_with_parameters).to have_been_made
67
+ end
68
+ end
69
+
70
+ context "parameter compilation" do
71
+ context "negated parameters" do
72
+ let(:params) { { foo: false } }
73
+
74
+ before do
75
+ @request_with_parameter = stub_action_request(action, foo: false).to_return(response)
76
+ @request_without_parameter = stub_action_request(action).to_return(response)
77
+ end
78
+
79
+ it "omits the parameter" do
80
+ subject
81
+ expect(@request_with_parameter).to_not have_been_made
82
+ expect(@request_without_parameter).to have_been_made
83
+ end
84
+ end
85
+
86
+ context "array parameters" do
87
+ let(:params) { { foo: ["one", "two"] } }
88
+
89
+ before do
90
+ @request = stub_action_request(action, foo: "one|two").to_return(response)
91
+ end
92
+
93
+ it "pipe delimits values" do
94
+ subject
95
+ expect(@request).to have_been_made
96
+ end
97
+ end
98
+ end
99
+
100
+ context "when the response is an error" do
101
+ let(:response_headers) { { "MediaWiki-API-Error" => "code" } }
102
+ let(:response_body) { { error: { info: "detailed message", code: "code" } } }
103
+
104
+ it "raises an ApiError" do
105
+ expect { subject }.to raise_error(MediawikiApi::ApiError, "detailed message (code)")
106
+ end
107
+ end
108
+ end
109
+
7
110
  describe "#log_in" do
8
111
 
9
112
  it "logs in when API returns Success" do
@@ -33,12 +136,15 @@ describe MediawikiApi::Client do
33
136
  end
34
137
 
35
138
  it "logs in" do
36
- subject.log_in "Test", "qwe123"
139
+ response = subject.log_in("Test", "qwe123")
140
+
141
+ expect(response).to include("result" => "Success")
37
142
  expect(subject.logged_in).to be true
38
143
  end
39
144
 
40
145
  it "sends second request with token and cookies" do
41
- subject.log_in "Test", "qwe123"
146
+ response = subject.log_in("Test", "qwe123")
147
+
42
148
  expect(@success_req).to have_been_requested
43
149
  end
44
150
  end
@@ -74,14 +180,6 @@ describe MediawikiApi::Client do
74
180
  subject.create_page("Test", "test123")
75
181
  expect(@edit_req).to have_been_requested
76
182
  end
77
-
78
- context "when API returns Success" do
79
- before do
80
- @edit_req.to_return(body: { result: "Success" }.to_json )
81
- end
82
-
83
- it "returns a MediawikiApi::Page"
84
- end
85
183
  end
86
184
 
87
185
  describe "#delete_page" do
@@ -118,7 +216,7 @@ describe MediawikiApi::Client do
118
216
  with(body: { format: "json", action: "createaccount", name: "Test", password: "qwe123" }).
119
217
  to_return(body: { createaccount: body_base.merge({ result: "Success" }) }.to_json )
120
218
 
121
- expect(subject.create_account("Test", "qwe123")).to be true
219
+ expect(subject.create_account("Test", "qwe123")).to include("result" => "Success")
122
220
  end
123
221
 
124
222
  context "when API returns NeedToken" do
@@ -139,7 +237,7 @@ describe MediawikiApi::Client do
139
237
  end
140
238
 
141
239
  it "creates an account" do
142
- expect(subject.create_account("Test", "qwe123")).to be true
240
+ expect(subject.create_account("Test", "qwe123")).to include("result" => "Success")
143
241
  end
144
242
 
145
243
  it "sends second request with token and cookies" do
@@ -162,4 +260,34 @@ describe MediawikiApi::Client do
162
260
  end
163
261
  end
164
262
  end
263
+
264
+ describe "#watch_page" do
265
+ before do
266
+ stub_request(:get, api_url).
267
+ with(query: { format: "json", action: "tokens", type: "watch" }).
268
+ to_return(body: { tokens: { watchtoken: "t123" } }.to_json )
269
+ @watch_req = stub_request(:post, api_url).
270
+ with(body: { format: "json", token: "t123", action: "watch", titles: "Test" })
271
+ end
272
+
273
+ it "sends a valid watch request" do
274
+ subject.watch_page("Test")
275
+ expect(@watch_req).to have_been_requested
276
+ end
277
+ end
278
+
279
+ describe "#unwatch_page" do
280
+ before do
281
+ stub_request(:get, api_url).
282
+ with(query: { format: "json", action: "tokens", type: "watch" }).
283
+ to_return(body: { tokens: { watchtoken: "t123" } }.to_json )
284
+ @watch_req = stub_request(:post, api_url).
285
+ with(body: { format: "json", token: "t123", action: "watch", titles: "Test", unwatch: "true" })
286
+ end
287
+
288
+ it "sends a valid unwatch request" do
289
+ subject.unwatch_page("Test")
290
+ expect(@watch_req).to have_been_requested
291
+ end
292
+ end
165
293
  end
@@ -0,0 +1,90 @@
1
+ require "spec_helper"
2
+
3
+ describe MediawikiApi::Response do
4
+ let(:response) { MediawikiApi::Response.new(faraday_response, envelope) }
5
+
6
+ let(:faraday_response) { double("Faraday::Response", body: body) }
7
+ let(:body) { "{}" }
8
+ let(:response_object) { JSON.parse(body) }
9
+ let(:envelope) { [] }
10
+
11
+ describe "#data" do
12
+ subject { response.data }
13
+
14
+ context "with a JSON object response body" do
15
+ let(:body) { '{ "query": { "result": "success" } }' }
16
+
17
+ context "and no expected envelope" do
18
+ let(:envelope) { [] }
19
+
20
+ it { is_expected.to eq(response_object) }
21
+ end
22
+
23
+ context "and a single-level envelope" do
24
+ let(:envelope) { ["query"] }
25
+ let(:nested_object) { response_object["query"] }
26
+
27
+ it { is_expected.to eq(nested_object) }
28
+ end
29
+
30
+ context "and a multi-level envelope" do
31
+ let(:envelope) { ["query", "result"] }
32
+ let(:nested_object) { response_object["query"]["result"] }
33
+
34
+ it { is_expected.to eq(nested_object) }
35
+ end
36
+
37
+ context "and a multi-level envelope that doesn't completely match" do
38
+ let(:envelope) { ["query", "something"] }
39
+ let(:partially_nested_object) { response_object["query"] }
40
+
41
+ it { is_expected.to eq(partially_nested_object) }
42
+ end
43
+ end
44
+
45
+ context "with a JSON array response body" do
46
+ let(:body) { '[ "something" ]' }
47
+
48
+ context "with any expected envelope" do
49
+ let(:envelope) { ["what", "ever"] }
50
+
51
+ it { is_expected.to eq(response_object) }
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#warnings" do
57
+ subject { response.warnings }
58
+
59
+ context "where the response contains no warnings" do
60
+ let(:body) { '{ "query": { "result": "success" } }' }
61
+
62
+ it { is_expected.to be_empty }
63
+ end
64
+
65
+ context "where the response contains warnings" do
66
+ let(:body) { '{ "warnings": { "main": { "*": "sorta bad message" } } }' }
67
+
68
+ it { is_expected.to_not be_empty }
69
+ it { is_expected.to include("sorta bad message") }
70
+ end
71
+ end
72
+
73
+ describe "#warnings?" do
74
+ subject { response.warnings? }
75
+
76
+ before { allow(response).to receive(:warnings) { warnings } }
77
+
78
+ context "where there are warnings" do
79
+ let(:warnings) { ["warning"] }
80
+
81
+ it { is_expected.to be(true) }
82
+ end
83
+
84
+ context "where there are no warnings" do
85
+ let(:warnings) { [] }
86
+
87
+ it { is_expected.to be(false) }
88
+ end
89
+ end
90
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,2 @@
1
- require "webmock/rspec"
2
- require "json"
3
- require "mediawiki_api"
4
-
5
- module TestHelpers
6
- def api_url
7
- "http://localhost/api.php"
8
- end
9
- def index_url
10
- "http://localhost/w/index.php"
11
- end
12
- end
13
-
14
- RSpec.configure do |conf|
15
- conf.include TestHelpers
16
- end
1
+ require "bundler/setup"
2
+ Bundler.require(:default, :development)
@@ -0,0 +1,29 @@
1
+ module MediawikiApi::RequestHelpers
2
+ def api_url
3
+ "http://localhost/api.php"
4
+ end
5
+
6
+ def index_url
7
+ "http://localhost/w/index.php"
8
+ end
9
+
10
+ def mock_token
11
+ "token123"
12
+ end
13
+
14
+ def stub_api_request(method, params)
15
+ stub_request(method, api_url).
16
+ with((method == :post ? :body : :query) => params.merge(format: "json"))
17
+ end
18
+
19
+ def stub_action_request(action, params = {})
20
+ method = params.delete(:http_method) || :post
21
+
22
+ stub_api_request(method, params.merge(action: action, token: mock_token))
23
+ end
24
+
25
+ def stub_token_request(type)
26
+ stub_api_request(:get, action: "tokens", type: type).
27
+ to_return(body: { tokens: { "#{type}token" => mock_token } }.to_json)
28
+ end
29
+ end
metadata CHANGED
@@ -1,18 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mediawiki_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amir Aharoni
8
8
  - Chris McMahon
9
+ - Dan Duvall
9
10
  - Jeff Hall
10
11
  - Juliusz Gonera
11
12
  - Zeljko Filipin
12
13
  autorequire:
13
14
  bindir: bin
14
15
  cert_chain: []
15
- date: 2014-07-18 00:00:00.000000000 Z
16
+ date: 2014-08-06 00:00:00.000000000 Z
16
17
  dependencies:
17
18
  - !ruby/object:Gem::Dependency
18
19
  name: faraday
@@ -126,6 +127,7 @@ description: Uses adapter-agnostic Faraday gem to talk to MediaWiki API.
126
127
  email:
127
128
  - amir.aharoni@mail.huji.ac.il
128
129
  - cmcmahon@wikimedia.org
130
+ - dduvall@wikimedia.org
129
131
  - jhall@wikimedia.org
130
132
  - jgonera@wikimedia.org
131
133
  - zeljko.filipin@gmail.com
@@ -133,19 +135,23 @@ executables: []
133
135
  extensions: []
134
136
  extra_rdoc_files: []
135
137
  files:
138
+ - ".gitignore"
136
139
  - ".gitreview"
137
140
  - ".rspec"
138
141
  - CREDITS
139
142
  - Gemfile
140
- - Gemfile.lock
141
143
  - LICENSE.txt
142
144
  - README.md
143
145
  - lib/mediawiki_api.rb
144
146
  - lib/mediawiki_api/client.rb
147
+ - lib/mediawiki_api/exceptions.rb
148
+ - lib/mediawiki_api/response.rb
145
149
  - lib/mediawiki_api/version.rb
146
150
  - mediawiki_api.gemspec
147
151
  - spec/client_spec.rb
152
+ - spec/response_spec.rb
148
153
  - spec/spec_helper.rb
154
+ - spec/support/request_helpers.rb
149
155
  homepage: https://github.com/wikimedia/mediawiki-ruby-api
150
156
  licenses:
151
157
  - GPL-2
@@ -166,10 +172,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
172
  version: '0'
167
173
  requirements: []
168
174
  rubyforge_project:
169
- rubygems_version: 2.4.1
175
+ rubygems_version: 2.2.2
170
176
  signing_key:
171
177
  specification_version: 4
172
178
  summary: A library for interacting with MediaWiki API from Ruby.
173
179
  test_files:
174
180
  - spec/client_spec.rb
181
+ - spec/response_spec.rb
175
182
  - spec/spec_helper.rb
183
+ - spec/support/request_helpers.rb
data/Gemfile.lock DELETED
@@ -1,54 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- mediawiki_api (0.1.4)
5
- faraday (~> 0.9, >= 0.9.0)
6
- faraday-cookie_jar (~> 0.0, >= 0.0.6)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- addressable (2.3.6)
12
- crack (0.4.2)
13
- safe_yaml (~> 1.0.0)
14
- diff-lcs (1.2.5)
15
- domain_name (0.5.19)
16
- unf (>= 0.0.5, < 1.0.0)
17
- faraday (0.9.0)
18
- multipart-post (>= 1.2, < 3)
19
- faraday-cookie_jar (0.0.6)
20
- faraday (>= 0.7.4)
21
- http-cookie (~> 1.0.0)
22
- http-cookie (1.0.2)
23
- domain_name (~> 0.5)
24
- multipart-post (2.0.0)
25
- rake (0.9.6)
26
- rspec (3.0.0)
27
- rspec-core (~> 3.0.0)
28
- rspec-expectations (~> 3.0.0)
29
- rspec-mocks (~> 3.0.0)
30
- rspec-core (3.0.2)
31
- rspec-support (~> 3.0.0)
32
- rspec-expectations (3.0.2)
33
- diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.0.0)
35
- rspec-mocks (3.0.2)
36
- rspec-support (~> 3.0.0)
37
- rspec-support (3.0.2)
38
- safe_yaml (1.0.3)
39
- unf (0.1.4)
40
- unf_ext
41
- unf_ext (0.0.6)
42
- webmock (1.18.0)
43
- addressable (>= 2.3.6)
44
- crack (>= 0.3.2)
45
-
46
- PLATFORMS
47
- ruby
48
-
49
- DEPENDENCIES
50
- bundler (~> 1.3)
51
- mediawiki_api!
52
- rake (~> 0)
53
- rspec (~> 3.0, >= 3.0.0)
54
- webmock (~> 1.17, >= 1.17.2)