wikidata_adaptor 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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.env.test +7 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +45 -0
  5. data/.yardopts +10 -0
  6. data/CHANGELOG.md +106 -0
  7. data/CLAUDE.md +200 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/COVERAGE.md +77 -0
  10. data/Gemfile +20 -0
  11. data/Gemfile.lock +124 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +269 -0
  14. data/Rakefile +18 -0
  15. data/integration/.env.example +20 -0
  16. data/integration/README.md +58 -0
  17. data/integration/config/99_IntegrationTesting.php +3 -0
  18. data/integration/config/wikibase-php.ini +15 -0
  19. data/integration/docker-compose.yml +98 -0
  20. data/lib/wikidata_adaptor/rest_api/aliases.rb +88 -0
  21. data/lib/wikidata_adaptor/rest_api/descriptions.rb +138 -0
  22. data/lib/wikidata_adaptor/rest_api/items.rb +36 -0
  23. data/lib/wikidata_adaptor/rest_api/labels.rb +138 -0
  24. data/lib/wikidata_adaptor/rest_api/open_api_document.rb +15 -0
  25. data/lib/wikidata_adaptor/rest_api/properties.rb +36 -0
  26. data/lib/wikidata_adaptor/rest_api/property_data_types.rb +15 -0
  27. data/lib/wikidata_adaptor/rest_api/search_item.rb +44 -0
  28. data/lib/wikidata_adaptor/rest_api/search_property.rb +44 -0
  29. data/lib/wikidata_adaptor/rest_api/sitelinks.rb +59 -0
  30. data/lib/wikidata_adaptor/rest_api/statements.rb +153 -0
  31. data/lib/wikidata_adaptor/rest_api.rb +32 -0
  32. data/lib/wikidata_adaptor/test_helpers/rest_api/aliases.rb +229 -0
  33. data/lib/wikidata_adaptor/test_helpers/rest_api/descriptions.rb +308 -0
  34. data/lib/wikidata_adaptor/test_helpers/rest_api/items.rb +213 -0
  35. data/lib/wikidata_adaptor/test_helpers/rest_api/labels.rb +302 -0
  36. data/lib/wikidata_adaptor/test_helpers/rest_api/open_api_document.rb +29 -0
  37. data/lib/wikidata_adaptor/test_helpers/rest_api/properties.rb +233 -0
  38. data/lib/wikidata_adaptor/test_helpers/rest_api/property_data_types.rb +23 -0
  39. data/lib/wikidata_adaptor/test_helpers/rest_api/search_item.rb +118 -0
  40. data/lib/wikidata_adaptor/test_helpers/rest_api/search_property.rb +118 -0
  41. data/lib/wikidata_adaptor/test_helpers/rest_api/sitelinks.rb +143 -0
  42. data/lib/wikidata_adaptor/test_helpers/rest_api/statements.rb +475 -0
  43. data/lib/wikidata_adaptor/test_helpers/rest_api/support/support.rb +310 -0
  44. data/lib/wikidata_adaptor/test_helpers/rest_api.rb +89 -0
  45. data/lib/wikidata_adaptor/version.rb +6 -0
  46. data/lib/wikidata_adaptor.rb +28 -0
  47. data/sig/wikidata_adaptor.rbs +4 -0
  48. metadata +106 -0
@@ -0,0 +1,308 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikidataAdaptor
4
+ module TestHelpers
5
+ module RestApi
6
+ # WebMock stubs for Wikibase REST API descriptions endpoints
7
+ module Descriptions
8
+ ###########################################
9
+ # GET /v1/entities/items/:item_id/descriptions
10
+ ###########################################
11
+ def stub_get_item_descriptions(item_id)
12
+ stub_rest_api_request(
13
+ :get,
14
+ "/v1/entities/items/#{item_id}/descriptions",
15
+ response_body: {
16
+ en: "English science fiction writer and humourist",
17
+ fr: "écrivain de science-fiction et humoriste anglais"
18
+ }
19
+ )
20
+ end
21
+
22
+ ##########################################################
23
+ # GET /v1/entities/items/:item_id/descriptions/:language_code
24
+ ##########################################################
25
+ def stub_get_item_description(item_id, language_code)
26
+ stub_rest_api_request(
27
+ :get,
28
+ "/v1/entities/items/#{item_id}/descriptions/#{language_code}",
29
+ response_body: "English science fiction writer and humourist"
30
+ )
31
+ end
32
+
33
+ ###############################################################################
34
+ # GET /v1/entities/items/:item_id/descriptions_with_language_fallback/:language_code
35
+ ###############################################################################
36
+ def stub_get_item_description_with_language_fallback(item_id, language_code)
37
+ stub_rest_api_request(
38
+ :get,
39
+ "/v1/entities/items/#{item_id}/descriptions_with_language_fallback/#{language_code}",
40
+ response_body: "English science fiction writer and humourist"
41
+ )
42
+ end
43
+
44
+ ###############################################################################
45
+ # GET /v1/entities/items/:item_id/descriptions_with_language_fallback/:language_code
46
+ # -> 307 Location: /v1/entities/items/:item_id/descriptions/:redirect_language_code
47
+ ###############################################################################
48
+ def stub_get_item_description_with_language_fallback_redirect(item_id, language_code,
49
+ redirect_language_code: language_code,
50
+ response_body: "English science fiction writer and humourist")
51
+ stub_rest_api_request(
52
+ :get,
53
+ "/v1/entities/items/#{item_id}/descriptions_with_language_fallback/#{language_code}",
54
+ response_status: 307,
55
+ response_headers: {
56
+ "Location" => "#{WIKIBASE_REST_ENDPOINT}/v1/entities/items/#{item_id}/descriptions/#{redirect_language_code}"
57
+ },
58
+ response_body: ""
59
+ )
60
+
61
+ stub_rest_api_request(
62
+ :get,
63
+ "/v1/entities/items/#{item_id}/descriptions/#{redirect_language_code}",
64
+ response_body: response_body
65
+ )
66
+ end
67
+
68
+ ##############################################
69
+ # GET /v1/entities/properties/:property_id/descriptions
70
+ ##############################################
71
+ def stub_get_property_descriptions(property_id)
72
+ stub_rest_api_request(
73
+ :get,
74
+ "/v1/entities/properties/#{property_id}/descriptions",
75
+ response_body: {
76
+ en: "that class of which this subject is a particular example and member",
77
+ fr: "classe dont ce sujet est un exemple particulier"
78
+ }
79
+ )
80
+ end
81
+
82
+ ################################################################
83
+ # GET /v1/entities/properties/:property_id/descriptions/:language_code
84
+ ################################################################
85
+ def stub_get_property_description(property_id, language_code)
86
+ stub_rest_api_request(
87
+ :get,
88
+ "/v1/entities/properties/#{property_id}/descriptions/#{language_code}",
89
+ response_body: "that class of which this subject is a particular example and member"
90
+ )
91
+ end
92
+
93
+ #######################################################################################
94
+ # GET /v1/entities/properties/:property_id/descriptions_with_language_fallback/:language_code
95
+ #######################################################################################
96
+ def stub_get_property_description_with_language_fallback(property_id, language_code)
97
+ stub_rest_api_request(
98
+ :get,
99
+ "/v1/entities/properties/#{property_id}/descriptions_with_language_fallback/#{language_code}",
100
+ response_body: "that class of which this subject is a particular example and member"
101
+ )
102
+ end
103
+
104
+ #######################################################################################
105
+ # GET /v1/entities/properties/:property_id/descriptions_with_language_fallback/:language_code
106
+ # -> 307 Location: /v1/entities/properties/:property_id/descriptions/:redirect_language_code
107
+ #######################################################################################
108
+ def stub_get_property_description_with_language_fallback_redirect(property_id, language_code,
109
+ redirect_language_code: language_code,
110
+ response_body: "that class of which this subject is a particular example and member")
111
+ stub_rest_api_request(
112
+ :get,
113
+ "/v1/entities/properties/#{property_id}/descriptions_with_language_fallback/#{language_code}",
114
+ response_status: 307,
115
+ response_headers: {
116
+ "Location" => "#{WIKIBASE_REST_ENDPOINT}/v1/entities/properties/#{property_id}/descriptions/#{redirect_language_code}"
117
+ },
118
+ response_body: ""
119
+ )
120
+
121
+ stub_rest_api_request(
122
+ :get,
123
+ "/v1/entities/properties/#{property_id}/descriptions/#{redirect_language_code}",
124
+ response_body: response_body
125
+ )
126
+ end
127
+
128
+ ################################################################
129
+ # PUT /v1/entities/items/:item_id/descriptions/:language_code
130
+ ################################################################
131
+ def stub_put_item_description(item_id, language_code, payload, response_body: nil)
132
+ stub_rest_api_request(
133
+ :put,
134
+ "/v1/entities/items/#{item_id}/descriptions/#{language_code}",
135
+ with: { body: payload.to_json },
136
+ response_body: response_body || payload["description"]
137
+ )
138
+ end
139
+
140
+ # Stub PUT item description request returning 500 error
141
+ #
142
+ # @param item_id [String] The item ID
143
+ # @param language_code [String] The language code
144
+ # @param payload [Hash] The request payload
145
+ #
146
+ # @return [WebMock::RequestStub]
147
+ def stub_put_item_description_unexpected_error(item_id, language_code, payload)
148
+ stub_rest_api_request(
149
+ :put,
150
+ "/v1/entities/items/#{item_id}/descriptions/#{language_code}",
151
+ response_status: 500,
152
+ with: { body: payload.to_json },
153
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
154
+ )
155
+ end
156
+
157
+ ######################################################################
158
+ # PUT /v1/entities/properties/:property_id/descriptions/:language_code
159
+ ######################################################################
160
+ def stub_put_property_description(property_id, language_code, payload, response_body: nil)
161
+ stub_rest_api_request(
162
+ :put,
163
+ "/v1/entities/properties/#{property_id}/descriptions/#{language_code}",
164
+ with: { body: payload.to_json },
165
+ response_body: response_body || payload["description"]
166
+ )
167
+ end
168
+
169
+ # Stub PUT property description request returning 500 error
170
+ #
171
+ # @param property_id [String] The property ID
172
+ # @param language_code [String] The language code
173
+ # @param payload [Hash] The request payload
174
+ #
175
+ # @return [WebMock::RequestStub]
176
+ def stub_put_property_description_unexpected_error(property_id, language_code, payload)
177
+ stub_rest_api_request(
178
+ :put,
179
+ "/v1/entities/properties/#{property_id}/descriptions/#{language_code}",
180
+ response_status: 500,
181
+ with: { body: payload.to_json },
182
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
183
+ )
184
+ end
185
+
186
+ ################################################
187
+ # PATCH /v1/entities/items/:item_id/descriptions
188
+ ################################################
189
+ def stub_patch_item_descriptions(item_id, payload, response_body: nil)
190
+ stub_rest_api_request(
191
+ :patch,
192
+ "/v1/entities/items/#{item_id}/descriptions",
193
+ with: { body: payload.to_json },
194
+ response_body: response_body || {
195
+ en: "British author",
196
+ fr: "écrivain de science-fiction et humoriste anglais"
197
+ }
198
+ )
199
+ end
200
+
201
+ # Stub PATCH item descriptions request returning 500 error
202
+ #
203
+ # @param item_id [String] The item ID
204
+ # @param payload [Hash] The request payload
205
+ #
206
+ # @return [WebMock::RequestStub]
207
+ def stub_patch_item_descriptions_unexpected_error(item_id, payload)
208
+ stub_rest_api_request(
209
+ :patch,
210
+ "/v1/entities/items/#{item_id}/descriptions",
211
+ response_status: 500,
212
+ with: { body: payload.to_json },
213
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
214
+ )
215
+ end
216
+
217
+ ######################################################
218
+ # PATCH /v1/entities/properties/:property_id/descriptions
219
+ ######################################################
220
+ def stub_patch_property_descriptions(property_id, payload, response_body: nil)
221
+ stub_rest_api_request(
222
+ :patch,
223
+ "/v1/entities/properties/#{property_id}/descriptions",
224
+ with: { body: payload.to_json },
225
+ response_body: response_body || {
226
+ en: "class membership",
227
+ fr: "classe dont ce sujet est un exemple particulier"
228
+ }
229
+ )
230
+ end
231
+
232
+ # Stub PATCH property descriptions request returning 500 error
233
+ #
234
+ # @param property_id [String] The property ID
235
+ # @param payload [Hash] The request payload
236
+ #
237
+ # @return [WebMock::RequestStub]
238
+ def stub_patch_property_descriptions_unexpected_error(property_id, payload)
239
+ stub_rest_api_request(
240
+ :patch,
241
+ "/v1/entities/properties/#{property_id}/descriptions",
242
+ response_status: 500,
243
+ with: { body: payload.to_json },
244
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
245
+ )
246
+ end
247
+
248
+ #####################################################################
249
+ # DELETE /v1/entities/items/:item_id/descriptions/:language_code
250
+ #####################################################################
251
+ def stub_delete_item_description(item_id, language_code, payload, response_body: "Description deleted")
252
+ stub_rest_api_request(
253
+ :delete,
254
+ "/v1/entities/items/#{item_id}/descriptions/#{language_code}",
255
+ with: { body: payload.to_json },
256
+ response_body: response_body
257
+ )
258
+ end
259
+
260
+ # Stub DELETE item description request returning 500 error
261
+ #
262
+ # @param item_id [String] The item ID
263
+ # @param language_code [String] The language code
264
+ # @param payload [Hash] The request payload
265
+ #
266
+ # @return [WebMock::RequestStub]
267
+ def stub_delete_item_description_unexpected_error(item_id, language_code, payload)
268
+ stub_rest_api_request(
269
+ :delete,
270
+ "/v1/entities/items/#{item_id}/descriptions/#{language_code}",
271
+ response_status: 500,
272
+ with: { body: payload.to_json },
273
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
274
+ )
275
+ end
276
+
277
+ ###########################################################################
278
+ # DELETE /v1/entities/properties/:property_id/descriptions/:language_code
279
+ ###########################################################################
280
+ def stub_delete_property_description(property_id, language_code, payload, response_body: "Description deleted")
281
+ stub_rest_api_request(
282
+ :delete,
283
+ "/v1/entities/properties/#{property_id}/descriptions/#{language_code}",
284
+ with: { body: payload.to_json },
285
+ response_body: response_body
286
+ )
287
+ end
288
+
289
+ # Stub DELETE property description request returning 500 error
290
+ #
291
+ # @param property_id [String] The property ID
292
+ # @param language_code [String] The language code
293
+ # @param payload [Hash] The request payload
294
+ #
295
+ # @return [WebMock::RequestStub]
296
+ def stub_delete_property_description_unexpected_error(property_id, language_code, payload)
297
+ stub_rest_api_request(
298
+ :delete,
299
+ "/v1/entities/properties/#{property_id}/descriptions/#{language_code}",
300
+ response_status: 500,
301
+ with: { body: payload.to_json },
302
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
303
+ )
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "support/support"
4
+ module WikidataAdaptor
5
+ module TestHelpers
6
+ module RestApi
7
+ # WebMock stubs for Wikibase REST API items endpoints
8
+ module Items
9
+ include WikidataAdaptor::TestHelpers::RestApi::Support
10
+
11
+ ###############################
12
+ # GET /v1/entities/items/:item_id
13
+ ###############################
14
+ def stub_get_item(item_id, response_body = nil)
15
+ stub_rest_api_request(
16
+ :get,
17
+ "/v1/entities/items/#{item_id}",
18
+ response_body: response_body || load_path_example(
19
+ "/v1/entities/items/{item_id}", "get"
20
+ )
21
+ )
22
+ end
23
+
24
+ # Stub GET item request returning 400 invalid item error
25
+ #
26
+ # @param item_id [String] The item ID
27
+ #
28
+ # @return [WebMock::RequestStub]
29
+ def stub_get_item_invalid_item(item_id)
30
+ stub_rest_api_request(
31
+ :get,
32
+ "/v1/entities/items/#{item_id}",
33
+ response_status: 400,
34
+ response_body: {
35
+ code: "invalid-item-id",
36
+ message: "Not a valid item ID: {#{item_id}}"
37
+ }
38
+ )
39
+ end
40
+
41
+ # Stub GET item request returning 404 not found error
42
+ #
43
+ # @param item_id [String] The item ID
44
+ #
45
+ # @return [WebMock::RequestStub]
46
+ def stub_get_item_not_found(item_id)
47
+ stub_rest_api_request(
48
+ :get,
49
+ "/v1/entities/items/#{item_id}",
50
+ response_status: 404,
51
+ response_body: {
52
+ code: "item-not-found",
53
+ message: "Could not find an item with the ID: {#{item_id}}"
54
+ }
55
+ )
56
+ end
57
+
58
+ # Stub GET item request returning 500 error
59
+ #
60
+ # @param item_id [String] The item ID
61
+ #
62
+ # @return [WebMock::RequestStub]
63
+ def stub_get_item_unexpected_error(item_id)
64
+ stub_rest_api_request(
65
+ :get,
66
+ "/v1/entities/items/#{item_id}",
67
+ response_status: 500,
68
+ response_body: {
69
+ code: "unexpected-error",
70
+ message: "Unexpected Error"
71
+ }
72
+ )
73
+ end
74
+
75
+ ###############################
76
+ # POST /v1/entities/items
77
+ ###############################
78
+ def stub_post_item(payload, response_body = nil)
79
+ stub_rest_api_request(
80
+ :post,
81
+ "/v1/entities/items",
82
+ response_status: 201,
83
+ with: { body: payload.to_json },
84
+ response_body: response_body || posted_item_response_fixture.to_json
85
+ )
86
+ end
87
+
88
+ # Stub POST item request returning 400 invalid item error
89
+ #
90
+ # @param response_body [Hash, nil] Optional response body
91
+ #
92
+ # @return [WebMock::RequestStub]
93
+ def stub_post_item_invalid_item(response_body = nil)
94
+ stub_rest_api_request(
95
+ :post,
96
+ "/v1/entities/items",
97
+ response_status: 400,
98
+ response_body: response_body || {
99
+ code: "invalid-item-data",
100
+ message: "The provided item data is invalid."
101
+ }
102
+ )
103
+ end
104
+
105
+ # Stub POST item request returning 403 access denied error
106
+ #
107
+ # @return [WebMock::RequestStub]
108
+ def stub_post_item_access_denied
109
+ stub_rest_api_request(
110
+ :post,
111
+ "/v1/entities/items",
112
+ response_status: 403,
113
+ response_body: {
114
+ code: "permission-denied",
115
+ message: "Access to resource is denied",
116
+ context: {
117
+ denial_reason: "{reason_code}",
118
+ denial_context: "{additional_context}"
119
+ }
120
+ }
121
+ )
122
+ end
123
+
124
+ # Stub POST item request returning 422 data policy violation error
125
+ #
126
+ # @return [WebMock::RequestStub]
127
+ def stub_post_item_data_policy_violation
128
+ stub_rest_api_request(
129
+ :post,
130
+ "/v1/entities/items",
131
+ response_status: 422,
132
+ response_body: {
133
+ code: "data-policy-violation",
134
+ message: "Edit violates data policy",
135
+ context: {
136
+ violation: "{violation_code}",
137
+ violation_context: {
138
+ some: "context"
139
+ }
140
+ }
141
+ }
142
+ )
143
+ end
144
+
145
+ # Stub POST item request returning 429 request limit reached error
146
+ #
147
+ # @return [WebMock::RequestStub]
148
+ def stub_post_item_request_limit_reached
149
+ stub_rest_api_request(
150
+ :post,
151
+ "/v1/entities/items",
152
+ response_status: 429,
153
+ response_body: {
154
+ code: "request-limit-reached",
155
+ message: "Exceeded the limit of actions that can be performed in a given span of time",
156
+ context: {
157
+ reason: "{reason_code}"
158
+ }
159
+ }
160
+ )
161
+ end
162
+
163
+ # Stub POST item request returning 500 error
164
+ #
165
+ # @param payload [Hash] The request payload
166
+ #
167
+ # @return [WebMock::RequestStub]
168
+ def stub_post_item_unexpected_error(payload)
169
+ stub_rest_api_request(
170
+ :post,
171
+ "/v1/entities/items",
172
+ response_status: 500,
173
+ with: { body: payload.to_json },
174
+ response_body: {
175
+ code: "unexpected-error",
176
+ message: "Unexpected Error"
177
+ }
178
+ )
179
+ end
180
+
181
+ ################################
182
+ # PATCH /v1/entities/items/:item_id
183
+ ################################
184
+ def stub_patch_item(item_id, payload, response_body: nil)
185
+ stub_rest_api_request(
186
+ :patch,
187
+ "/v1/entities/items/#{item_id}",
188
+ with: { body: payload.to_json },
189
+ response_body: response_body || load_path_example(
190
+ "/v1/entities/items/{item_id}", "get"
191
+ )
192
+ )
193
+ end
194
+
195
+ # Stub PATCH item request returning 500 error
196
+ #
197
+ # @param item_id [String] The item ID
198
+ # @param payload [Hash] The request payload
199
+ #
200
+ # @return [WebMock::RequestStub]
201
+ def stub_patch_item_unexpected_error(item_id, payload)
202
+ stub_rest_api_request(
203
+ :patch,
204
+ "/v1/entities/items/#{item_id}",
205
+ response_status: 500,
206
+ with: { body: payload.to_json },
207
+ response_body: { code: "unexpected-error", message: "Unexpected Error" }
208
+ )
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end