decidim-api 0.31.3 → 0.32.0.rc1
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 +4 -4
- data/README.md +3 -13
- data/app/controllers/decidim/api/sessions_controller.rb +1 -1
- data/app/models/decidim/api/api_user.rb +5 -1
- data/config/locales/ca-IT.yml +7 -0
- data/config/locales/ca.yml +7 -0
- data/config/locales/cs.yml +13 -0
- data/config/locales/el.yml +11 -0
- data/config/locales/en.yml +7 -0
- data/config/locales/es-MX.yml +7 -0
- data/config/locales/es-PY.yml +7 -0
- data/config/locales/es.yml +7 -0
- data/config/locales/eu.yml +7 -0
- data/config/locales/fi-plain.yml +7 -0
- data/config/locales/fi.yml +7 -0
- data/config/locales/fr-CA.yml +4 -0
- data/config/locales/fr.yml +4 -0
- data/config/locales/ja.yml +7 -0
- data/config/locales/no.yml +1 -0
- data/config/locales/pt-BR.yml +7 -0
- data/config/locales/ro-RO.yml +7 -0
- data/config/locales/sv.yml +7 -0
- data/decidim-api.gemspec +12 -15
- data/docs/usage.md +3 -634
- data/lib/decidim/api/component_mutation_type.rb +1 -2
- data/lib/decidim/api/errors/attribute_validation_error.rb +73 -0
- data/lib/decidim/api/errors/invalid_locale_error.rb +14 -0
- data/lib/decidim/api/errors/locale_error.rb +14 -0
- data/lib/decidim/api/errors/mutation_not_authorized_error.rb +14 -0
- data/lib/decidim/api/errors/not_found_error.rb +14 -0
- data/lib/decidim/api/errors/permission_not_set_error.rb +14 -0
- data/lib/decidim/api/errors/unauthorized_field_error.rb +14 -0
- data/lib/decidim/api/errors/unauthorized_object_error.rb +14 -0
- data/lib/decidim/api/errors/validation_error.rb +13 -0
- data/lib/decidim/api/graphiql/config.rb +1 -1
- data/lib/decidim/api/graphql_permissions.rb +17 -12
- data/lib/decidim/api/query_type.rb +91 -0
- data/lib/decidim/api/schema.rb +27 -1
- data/lib/decidim/api/test/component_context.rb +59 -51
- data/lib/decidim/api/test/shared_examples/commentable_interface_examples.rb +46 -0
- data/lib/decidim/api/test/shared_examples/followable_interface_examples.rb +12 -1
- data/lib/decidim/api/test/shared_examples/statistics_examples.rb +0 -2
- data/lib/decidim/api/test/type_context.rb +10 -2
- data/lib/decidim/api/test.rb +1 -0
- data/lib/decidim/api/types/access_mode_enum.rb +15 -0
- data/lib/decidim/api/types/base_mutation.rb +28 -0
- data/lib/decidim/api/types/base_object.rb +12 -0
- data/lib/decidim/api/types.rb +12 -1
- data/lib/decidim/api/version.rb +1 -1
- data/lib/decidim/api.rb +22 -32
- metadata +59 -34
- /data/lib/decidim/api/test/{mutation_context.rb → shared_examples/mutation_context.rb} +0 -0
|
@@ -43,25 +43,33 @@ shared_context "with a graphql decidim component" do
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
shared_examples "
|
|
47
|
-
let(:process_space_factory) { :participatory_process }
|
|
46
|
+
shared_examples "graphQL not found space" do
|
|
48
47
|
let(:space_type) { "participatoryProcess" }
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
expect(response[space_type]["components"].first[lookout_key]).to eq(query_result)
|
|
53
|
-
end
|
|
49
|
+
it "should not be visible" do
|
|
50
|
+
expect { response }.to raise_error(Decidim::Api::Errors::NotFoundError, "#{space_type.classify} not found")
|
|
54
51
|
end
|
|
52
|
+
end
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
shared_examples "with resource visibility" do
|
|
55
|
+
let(:process_space_factory) { :participatory_process }
|
|
56
|
+
let(:space_type) { "participatoryProcess" }
|
|
57
|
+
|
|
58
|
+
shared_examples "graphQL visible resource" do |visible: true|
|
|
59
|
+
if visible
|
|
60
|
+
it "should be visible" do
|
|
61
|
+
expect(response[space_type]["components"].first[lookout_key]).to eq(query_result)
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
it "should not be visible" do
|
|
65
|
+
expect(response[space_type]["components"]).to be_empty
|
|
66
|
+
end
|
|
59
67
|
end
|
|
60
68
|
end
|
|
61
69
|
|
|
62
70
|
shared_examples "graphQL hidden component" do
|
|
63
71
|
it "should not be visible" do
|
|
64
|
-
expect(response[space_type]["components"]
|
|
72
|
+
expect(response[space_type]["components"]).to be_empty
|
|
65
73
|
end
|
|
66
74
|
end
|
|
67
75
|
|
|
@@ -76,7 +84,7 @@ shared_examples "with resource visibility" do
|
|
|
76
84
|
shared_examples "graphQL space hidden to visitor" do
|
|
77
85
|
context "when user is visitor" do
|
|
78
86
|
let!(:current_user) { nil }
|
|
79
|
-
it_behaves_like "graphQL
|
|
87
|
+
it_behaves_like "graphQL not found space"
|
|
80
88
|
end
|
|
81
89
|
end
|
|
82
90
|
|
|
@@ -119,13 +127,13 @@ shared_examples "with resource visibility" do
|
|
|
119
127
|
|
|
120
128
|
context "when user is member" do
|
|
121
129
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
122
|
-
let!(:
|
|
130
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
123
131
|
it_behaves_like "graphQL visible resource"
|
|
124
132
|
end
|
|
125
133
|
|
|
126
134
|
context "when user is member" do
|
|
127
135
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
128
|
-
let!(:
|
|
136
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
129
137
|
it_behaves_like "graphQL visible resource"
|
|
130
138
|
end
|
|
131
139
|
|
|
@@ -143,7 +151,7 @@ shared_examples "with resource visibility" do
|
|
|
143
151
|
context "when the user is space admin" do
|
|
144
152
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
145
153
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "admin") }
|
|
146
|
-
it_behaves_like "graphQL visible resource"
|
|
154
|
+
it_behaves_like "graphQL visible resource", visible: false
|
|
147
155
|
end
|
|
148
156
|
|
|
149
157
|
context "when the user is space collaborator" do
|
|
@@ -161,7 +169,7 @@ shared_examples "with resource visibility" do
|
|
|
161
169
|
context "when the user is space evaluator" do
|
|
162
170
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
163
171
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "evaluator") }
|
|
164
|
-
it_behaves_like "graphQL visible resource"
|
|
172
|
+
it_behaves_like "graphQL visible resource", visible: false
|
|
165
173
|
end
|
|
166
174
|
|
|
167
175
|
context "when user is visitor" do
|
|
@@ -177,13 +185,13 @@ shared_examples "with resource visibility" do
|
|
|
177
185
|
|
|
178
186
|
context "when user is member" do
|
|
179
187
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
180
|
-
let!(:
|
|
188
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
181
189
|
it_behaves_like "graphQL hidden component"
|
|
182
190
|
end
|
|
183
191
|
end
|
|
184
192
|
end
|
|
185
193
|
|
|
186
|
-
context "when space is published
|
|
194
|
+
context "when space is published and transparent" do
|
|
187
195
|
let(:process_space_factory) { :assembly }
|
|
188
196
|
let(:space_type) { "assembly" }
|
|
189
197
|
|
|
@@ -203,7 +211,7 @@ shared_examples "with resource visibility" do
|
|
|
203
211
|
}
|
|
204
212
|
)
|
|
205
213
|
end
|
|
206
|
-
let!(:participatory_process) { create(process_space_factory, :published, :
|
|
214
|
+
let!(:participatory_process) { create(process_space_factory, :published, :transparent, organization: current_organization) }
|
|
207
215
|
|
|
208
216
|
context "when component is published" do
|
|
209
217
|
let!(:current_component) { create(component_factory, :published, participatory_space: participatory_process) }
|
|
@@ -241,7 +249,7 @@ shared_examples "with resource visibility" do
|
|
|
241
249
|
|
|
242
250
|
context "when user is member" do
|
|
243
251
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
244
|
-
let!(:
|
|
252
|
+
let!(:member) { create(:assembly_member, user: current_user, participatory_space: participatory_process) }
|
|
245
253
|
it_behaves_like "graphQL visible resource"
|
|
246
254
|
end
|
|
247
255
|
|
|
@@ -259,13 +267,13 @@ shared_examples "with resource visibility" do
|
|
|
259
267
|
context "when the user is space admin" do
|
|
260
268
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
261
269
|
let!(:role) { create(:assembly_user_role, assembly: participatory_process, user: current_user, role: "admin") }
|
|
262
|
-
it_behaves_like "graphQL visible resource"
|
|
270
|
+
it_behaves_like "graphQL visible resource", visible: false
|
|
263
271
|
end
|
|
264
272
|
|
|
265
273
|
context "when the user is space collaborator" do
|
|
266
274
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
267
275
|
let!(:role) { create(:assembly_user_role, assembly: participatory_process, user: current_user, role: "collaborator") }
|
|
268
|
-
it_behaves_like "graphQL visible resource"
|
|
276
|
+
it_behaves_like "graphQL visible resource", visible: false
|
|
269
277
|
end
|
|
270
278
|
|
|
271
279
|
context "when the user is space moderator" do
|
|
@@ -277,7 +285,7 @@ shared_examples "with resource visibility" do
|
|
|
277
285
|
context "when the user is space evaluator" do
|
|
278
286
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
279
287
|
let!(:role) { create(:assembly_user_role, assembly: participatory_process, user: current_user, role: "evaluator") }
|
|
280
|
-
it_behaves_like "graphQL visible resource"
|
|
288
|
+
it_behaves_like "graphQL visible resource", visible: false
|
|
281
289
|
end
|
|
282
290
|
|
|
283
291
|
context "when user is visitor" do
|
|
@@ -292,14 +300,14 @@ shared_examples "with resource visibility" do
|
|
|
292
300
|
|
|
293
301
|
context "when user is member" do
|
|
294
302
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
295
|
-
let!(:
|
|
303
|
+
let!(:member) { create(:assembly_member, user: current_user, participatory_space: participatory_process) }
|
|
296
304
|
it_behaves_like "graphQL hidden component"
|
|
297
305
|
end
|
|
298
306
|
end
|
|
299
307
|
end
|
|
300
308
|
|
|
301
|
-
context "when space is published but
|
|
302
|
-
let!(:participatory_process) { create(process_space_factory, :published, :
|
|
309
|
+
context "when space is published but restricted" do
|
|
310
|
+
let!(:participatory_process) { create(process_space_factory, :published, :restricted, :with_steps, organization: current_organization) }
|
|
303
311
|
|
|
304
312
|
context "when component is published" do
|
|
305
313
|
let!(:current_component) { create(component_factory, :published, participatory_space: participatory_process) }
|
|
@@ -309,38 +317,38 @@ shared_examples "with resource visibility" do
|
|
|
309
317
|
context "when the user is space admin" do
|
|
310
318
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
311
319
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "admin") }
|
|
312
|
-
it_behaves_like "graphQL
|
|
320
|
+
it_behaves_like "graphQL not found space"
|
|
313
321
|
end
|
|
314
322
|
|
|
315
323
|
context "when the user is space collaborator" do
|
|
316
324
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
317
325
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "collaborator") }
|
|
318
|
-
it_behaves_like "graphQL
|
|
326
|
+
it_behaves_like "graphQL not found space"
|
|
319
327
|
end
|
|
320
328
|
|
|
321
329
|
context "when the user is space moderator" do
|
|
322
330
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
323
331
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "moderator") }
|
|
324
332
|
|
|
325
|
-
it_behaves_like "graphQL
|
|
333
|
+
it_behaves_like "graphQL not found space"
|
|
326
334
|
end
|
|
327
335
|
|
|
328
336
|
context "when the user is space evaluator" do
|
|
329
337
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
330
338
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "evaluator") }
|
|
331
|
-
it_behaves_like "graphQL
|
|
339
|
+
it_behaves_like "graphQL not found space"
|
|
332
340
|
end
|
|
333
341
|
|
|
334
342
|
it_behaves_like "graphQL space hidden to visitor"
|
|
335
343
|
|
|
336
344
|
context "when user is normal user" do
|
|
337
345
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
338
|
-
it_behaves_like "graphQL
|
|
346
|
+
it_behaves_like "graphQL not found space"
|
|
339
347
|
end
|
|
340
348
|
|
|
341
349
|
context "when user is member" do
|
|
342
350
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
343
|
-
let!(:
|
|
351
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
344
352
|
it_behaves_like "graphQL visible resource"
|
|
345
353
|
end
|
|
346
354
|
end
|
|
@@ -353,36 +361,36 @@ shared_examples "with resource visibility" do
|
|
|
353
361
|
context "when the user is space admin" do
|
|
354
362
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
355
363
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "admin") }
|
|
356
|
-
it_behaves_like "graphQL
|
|
364
|
+
it_behaves_like "graphQL not found space"
|
|
357
365
|
end
|
|
358
366
|
|
|
359
367
|
context "when the user is space collaborator" do
|
|
360
368
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
361
369
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "collaborator") }
|
|
362
|
-
it_behaves_like "graphQL
|
|
370
|
+
it_behaves_like "graphQL not found space"
|
|
363
371
|
end
|
|
364
372
|
|
|
365
373
|
context "when the user is space moderator" do
|
|
366
374
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
367
375
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "moderator") }
|
|
368
|
-
it_behaves_like "graphQL
|
|
376
|
+
it_behaves_like "graphQL not found space"
|
|
369
377
|
end
|
|
370
378
|
|
|
371
379
|
context "when the user is space evaluator" do
|
|
372
380
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
373
381
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "evaluator") }
|
|
374
|
-
it_behaves_like "graphQL
|
|
382
|
+
it_behaves_like "graphQL not found space"
|
|
375
383
|
end
|
|
376
384
|
it_behaves_like "graphQL space hidden to visitor"
|
|
377
385
|
|
|
378
386
|
context "when user is member" do
|
|
379
387
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
380
|
-
let!(:
|
|
388
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
381
389
|
it_behaves_like "graphQL hidden component"
|
|
382
390
|
end
|
|
383
391
|
context "when user is normal user" do
|
|
384
392
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
385
|
-
it_behaves_like "graphQL
|
|
393
|
+
it_behaves_like "graphQL not found space"
|
|
386
394
|
end
|
|
387
395
|
end
|
|
388
396
|
end
|
|
@@ -398,38 +406,38 @@ shared_examples "with resource visibility" do
|
|
|
398
406
|
context "when the user is space admin" do
|
|
399
407
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
400
408
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "admin") }
|
|
401
|
-
it_behaves_like "graphQL
|
|
409
|
+
it_behaves_like "graphQL not found space"
|
|
402
410
|
end
|
|
403
411
|
|
|
404
412
|
context "when the user is space collaborator" do
|
|
405
413
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
406
414
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "collaborator") }
|
|
407
|
-
it_behaves_like "graphQL
|
|
415
|
+
it_behaves_like "graphQL not found space"
|
|
408
416
|
end
|
|
409
417
|
|
|
410
418
|
context "when the user is space moderator" do
|
|
411
419
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
412
420
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "moderator") }
|
|
413
|
-
it_behaves_like "graphQL
|
|
421
|
+
it_behaves_like "graphQL not found space"
|
|
414
422
|
end
|
|
415
423
|
|
|
416
424
|
context "when the user is space evaluator" do
|
|
417
425
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
418
426
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "evaluator") }
|
|
419
|
-
it_behaves_like "graphQL
|
|
427
|
+
it_behaves_like "graphQL not found space"
|
|
420
428
|
end
|
|
421
429
|
|
|
422
430
|
it_behaves_like "graphQL space hidden to visitor"
|
|
423
431
|
|
|
424
432
|
context "when user is member" do
|
|
425
433
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
426
|
-
let!(:
|
|
427
|
-
it_behaves_like "graphQL
|
|
434
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
435
|
+
it_behaves_like "graphQL not found space"
|
|
428
436
|
end
|
|
429
437
|
|
|
430
438
|
context "when user is normal user" do
|
|
431
439
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
432
|
-
it_behaves_like "graphQL
|
|
440
|
+
it_behaves_like "graphQL not found space"
|
|
433
441
|
end
|
|
434
442
|
end
|
|
435
443
|
|
|
@@ -441,38 +449,38 @@ shared_examples "with resource visibility" do
|
|
|
441
449
|
context "when the user is space admin" do
|
|
442
450
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
443
451
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "admin") }
|
|
444
|
-
it_behaves_like "graphQL
|
|
452
|
+
it_behaves_like "graphQL not found space"
|
|
445
453
|
end
|
|
446
454
|
|
|
447
455
|
context "when the user is space collaborator" do
|
|
448
456
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
449
457
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "collaborator") }
|
|
450
|
-
it_behaves_like "graphQL
|
|
458
|
+
it_behaves_like "graphQL not found space"
|
|
451
459
|
end
|
|
452
460
|
|
|
453
461
|
context "when the user is space moderator" do
|
|
454
462
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
455
463
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "moderator") }
|
|
456
|
-
it_behaves_like "graphQL
|
|
464
|
+
it_behaves_like "graphQL not found space"
|
|
457
465
|
end
|
|
458
466
|
|
|
459
467
|
context "when the user is space evaluator" do
|
|
460
468
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
461
469
|
let!(:role) { create(:participatory_process_user_role, participatory_process:, user: current_user, role: "evaluator") }
|
|
462
|
-
it_behaves_like "graphQL
|
|
470
|
+
it_behaves_like "graphQL not found space"
|
|
463
471
|
end
|
|
464
472
|
it_behaves_like "graphQL space hidden to visitor"
|
|
465
473
|
|
|
466
474
|
context "when user is member" do
|
|
467
475
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
468
|
-
let!(:
|
|
469
|
-
it_behaves_like "graphQL
|
|
476
|
+
let!(:member) { create(:member, user: current_user, participatory_space: participatory_process) }
|
|
477
|
+
it_behaves_like "graphQL not found space"
|
|
470
478
|
end
|
|
471
479
|
|
|
472
480
|
context "when user is normal user" do
|
|
473
481
|
let!(:current_user) { create(:user, :confirmed, organization: current_organization) }
|
|
474
482
|
|
|
475
|
-
it_behaves_like "graphQL
|
|
483
|
+
it_behaves_like "graphQL not found space"
|
|
476
484
|
end
|
|
477
485
|
end
|
|
478
486
|
end
|
|
@@ -10,4 +10,50 @@ shared_examples_for "commentable interface" do
|
|
|
10
10
|
expect(response["totalCommentsCount"]).to eq(model.comments_count)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
describe "with comments" do
|
|
15
|
+
let(:comments) { create_list(:comment, 5, commentable: model) }
|
|
16
|
+
let(:subcomments_level1) do
|
|
17
|
+
comments.map do |comment|
|
|
18
|
+
create_list(:comment, 2, commentable: comment)
|
|
19
|
+
end.flatten
|
|
20
|
+
end
|
|
21
|
+
let!(:subcomments_level2) do
|
|
22
|
+
subcomments_level1.map do |comment|
|
|
23
|
+
create(:comment, commentable: comment)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
let(:query) do
|
|
28
|
+
%(
|
|
29
|
+
{
|
|
30
|
+
comments {
|
|
31
|
+
...dataFragment
|
|
32
|
+
comments {
|
|
33
|
+
...dataFragment
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
fragment dataFragment on Comment {
|
|
38
|
+
id
|
|
39
|
+
body
|
|
40
|
+
createdAt
|
|
41
|
+
author { name }
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "includes the comments" do
|
|
47
|
+
expect(response["comments"]).to be_a(Array)
|
|
48
|
+
expect(response["comments"].count).to eq(5)
|
|
49
|
+
|
|
50
|
+
response["comments"].each do |comment|
|
|
51
|
+
expect(comment["comments"]).to be_a(Array)
|
|
52
|
+
expect(comment["comments"].count).to eq(2)
|
|
53
|
+
|
|
54
|
+
subcomments = subcomments_level1.select { |c| c.commentable.id == comment["id"].to_i }
|
|
55
|
+
expect(comment["comments"].map { |c| c["id"].to_i }).to match_array(subcomments.map(&:id))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
13
59
|
end
|
|
@@ -4,10 +4,21 @@ require "spec_helper"
|
|
|
4
4
|
|
|
5
5
|
shared_examples_for "followable interface" do
|
|
6
6
|
describe "follows_count" do
|
|
7
|
+
let!(:follow) { create(:follow, followable: model) }
|
|
7
8
|
let(:query) { "{ followsCount }" }
|
|
8
9
|
|
|
9
10
|
it "includes the field" do
|
|
10
|
-
expect(response["followsCount"]).to eq(model.follows_count)
|
|
11
|
+
expect(response["followsCount"]).to eq(model.reload.follows_count)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "followers" do
|
|
16
|
+
let!(:follow) { create(:follow, followable: model) }
|
|
17
|
+
let(:query) { "{ followers { id } }" }
|
|
18
|
+
|
|
19
|
+
it "includes the field" do
|
|
20
|
+
expect(response["followers"]).to be_present
|
|
21
|
+
expect(response["followers"]).to include({ "id" => model.reload.followers.first.id.to_s })
|
|
11
22
|
end
|
|
12
23
|
end
|
|
13
24
|
end
|
|
@@ -15,7 +15,6 @@ shared_examples "implements stats type" do
|
|
|
15
15
|
{ name: "surveys_count", data: [0], tooltip_key: "surveys_count_tooltip" },
|
|
16
16
|
{ name: "results_count", data: [0], tooltip_key: "results_count_tooltip" },
|
|
17
17
|
{ name: "debates_count", data: [0], tooltip_key: "debates_count_tooltip" },
|
|
18
|
-
{ name: "sortitions_count", data: [0], tooltip_key: "sortitions_count_tooltip" },
|
|
19
18
|
{ name: "posts_count", data: [0], tooltip_key: "posts_count_tooltip" },
|
|
20
19
|
{ name: "collaborative_texts_count", data: [0], tooltip_key: "collaborative_texts_count_tooltip" }
|
|
21
20
|
]))
|
|
@@ -36,7 +35,6 @@ shared_examples "implements stats type" do
|
|
|
36
35
|
{ "name" => { "translation" => "Surveys" }, "value" => 0 },
|
|
37
36
|
{ "name" => { "translation" => "Results" }, "value" => 0 },
|
|
38
37
|
{ "name" => { "translation" => "Debates" }, "value" => 0 },
|
|
39
|
-
{ "name" => { "translation" => "Sortitions" }, "value" => 0 },
|
|
40
38
|
{ "name" => { "translation" => "Posts" }, "value" => 0 },
|
|
41
39
|
{ "name" => { "translation" => "Collaborative texts" }, "value" => 0 }
|
|
42
40
|
]
|
|
@@ -35,8 +35,17 @@ shared_context "with a graphql class type" do
|
|
|
35
35
|
# Matches the error code with the Error class
|
|
36
36
|
# For instance, if the error code is NOT_FOUND_ERROR then it will raise the "Decidim::Api::Errors::NotFoundError" class
|
|
37
37
|
raise "Decidim::Api::Errors::#{code.downcase.classify}".constantize, error["message"] if %w(
|
|
38
|
-
|
|
38
|
+
LOCALE_ERROR
|
|
39
|
+
NOT_FOUND_ERROR
|
|
40
|
+
INVALID_LOCALE_ERROR
|
|
41
|
+
PERMISSION_NOT_SET_ERROR
|
|
42
|
+
ATTRIBUTE_VALIDATION_ERROR
|
|
43
|
+
UNAUTHORIZED_FIELD_ERROR
|
|
44
|
+
UNAUTHORIZED_OBJECT_ERROR
|
|
45
|
+
MUTATION_NOT_AUTHORIZED_ERROR
|
|
46
|
+
VALIDATION_ERROR
|
|
39
47
|
TOO_MANY_ALIASES_ERROR
|
|
48
|
+
INTROSPECTION_DISABLED_ERROR
|
|
40
49
|
RECURSION_LIMIT_EXCEEDED_ERROR
|
|
41
50
|
).include?(code)
|
|
42
51
|
|
|
@@ -103,7 +112,6 @@ shared_examples "when the introspection is disabled" do
|
|
|
103
112
|
before do
|
|
104
113
|
allow(Decidim::Api).to receive(:enable_anonymous_introspection).and_return(false)
|
|
105
114
|
end
|
|
106
|
-
|
|
107
115
|
it "raises an Decidim::Api::Errors::IntrospectionDisabledError" do
|
|
108
116
|
expect { response }.to raise_error(Decidim::Api::Errors::IntrospectionDisabledError, "Introspection is disabled for this request")
|
|
109
117
|
end
|
data/lib/decidim/api/test.rb
CHANGED
|
@@ -22,4 +22,5 @@ require "decidim/api/test/shared_examples/statistics_examples"
|
|
|
22
22
|
require "decidim/api/test/shared_examples/taxonomizable_interface_examples"
|
|
23
23
|
require "decidim/api/test/shared_examples/timestamps_interface_examples"
|
|
24
24
|
require "decidim/api/test/shared_examples/traceable_interface_examples"
|
|
25
|
+
require "decidim/api/test/shared_examples/mutation_context"
|
|
25
26
|
require "decidim/api/test/type_context"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
module Api
|
|
5
|
+
module Types
|
|
6
|
+
class AccessModeEnum < Decidim::Api::Types::BaseEnum
|
|
7
|
+
description "The access modes for participatory spaces"
|
|
8
|
+
|
|
9
|
+
value "OPEN", value: "open", description: "Open to everyone"
|
|
10
|
+
value "TRANSPARENT", value: "transparent", description: "Transparent (visible but restricted participation)"
|
|
11
|
+
value "RESTRICTED", value: "restricted", description: "Restricted to members only"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -5,12 +5,40 @@ module Decidim
|
|
|
5
5
|
module Types
|
|
6
6
|
class BaseMutation < GraphQL::Schema::RelayClassicMutation
|
|
7
7
|
include Decidim::Api::GraphqlPermissions
|
|
8
|
+
include Decidim::FormFactory
|
|
8
9
|
|
|
9
10
|
object_class BaseObject
|
|
10
11
|
field_class Types::BaseField
|
|
11
12
|
input_object_class BaseInputObject
|
|
12
13
|
|
|
13
14
|
required_scopes "api:read", "api:write"
|
|
15
|
+
|
|
16
|
+
def set_locale(locale:, toggle_translations:)
|
|
17
|
+
raise I18n::InvalidLocale, "#{locale} is not a valid locale" unless available_locales.include?(locale)
|
|
18
|
+
|
|
19
|
+
I18n.locale = locale.presence
|
|
20
|
+
RequestStore.store[:toggle_machine_translations] = toggle_translations
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def current_user
|
|
24
|
+
context[:current_user]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def current_component
|
|
28
|
+
context[:current_component]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def current_organization
|
|
32
|
+
context[:current_organization]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def available_locales
|
|
36
|
+
if current_organization.present?
|
|
37
|
+
current_organization.available_locales
|
|
38
|
+
else
|
|
39
|
+
I18n.available_locales.map(&:to_s)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
14
42
|
end
|
|
15
43
|
end
|
|
16
44
|
end
|
|
@@ -10,6 +10,18 @@ module Decidim
|
|
|
10
10
|
field_class Types::BaseField
|
|
11
11
|
|
|
12
12
|
required_scopes "api:read"
|
|
13
|
+
|
|
14
|
+
def current_user
|
|
15
|
+
context[:current_user]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def current_component
|
|
19
|
+
context[:current_component]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def current_organization
|
|
23
|
+
context[:current_organization]
|
|
24
|
+
end
|
|
13
25
|
end
|
|
14
26
|
end
|
|
15
27
|
end
|
data/lib/decidim/api/types.rb
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Decidim
|
|
4
4
|
module Api
|
|
5
|
-
autoload :RecursionAnalyzer, "decidim/api/recursion_analyzer"
|
|
6
5
|
autoload :IntrospectionAnalyzer, "decidim/api/introspection_analyzer"
|
|
7
6
|
autoload :AliasAnalyzer, "decidim/api/alias_analyzer"
|
|
7
|
+
autoload :RecursionAnalyzer, "decidim/api/recursion_analyzer"
|
|
8
8
|
autoload :QueryType, "decidim/api/query_type"
|
|
9
9
|
autoload :MutationType, "decidim/api/mutation_type"
|
|
10
10
|
autoload :Schema, "decidim/api/schema"
|
|
@@ -14,7 +14,16 @@ module Decidim
|
|
|
14
14
|
|
|
15
15
|
module Errors
|
|
16
16
|
autoload :IntrospectionDisabledError, "decidim/api/errors/introspection_disabled_error"
|
|
17
|
+
autoload :LocaleError, "decidim/api/errors/locale_error"
|
|
17
18
|
autoload :TooManyAliasesError, "decidim/api/errors/too_many_aliases_error"
|
|
19
|
+
autoload :InvalidLocaleError, "decidim/api/errors/invalid_locale_error"
|
|
20
|
+
autoload :AttributeValidationError, "decidim/api/errors/attribute_validation_error"
|
|
21
|
+
autoload :MutationNotAuthorizedError, "decidim/api/errors/mutation_not_authorized_error"
|
|
22
|
+
autoload :NotFoundError, "decidim/api/errors/not_found_error"
|
|
23
|
+
autoload :PermissionNotSetError, "decidim/api/errors/permission_not_set_error"
|
|
24
|
+
autoload :UnauthorizedFieldError, "decidim/api/errors/unauthorized_field_error"
|
|
25
|
+
autoload :UnauthorizedObjectError, "decidim/api/errors/unauthorized_object_error"
|
|
26
|
+
autoload :ValidationError, "decidim/api/errors/validation_error"
|
|
18
27
|
autoload :RecursionLimitExceededError, "decidim/api/errors/recursion_limit_exceeded_error"
|
|
19
28
|
end
|
|
20
29
|
|
|
@@ -28,6 +37,8 @@ module Decidim
|
|
|
28
37
|
autoload :BaseObject, "decidim/api/types/base_object"
|
|
29
38
|
autoload :BaseScalar, "decidim/api/types/base_scalar"
|
|
30
39
|
autoload :BaseUnion, "decidim/api/types/base_union"
|
|
40
|
+
|
|
41
|
+
autoload :AccessModeEnum, "decidim/api/types/access_mode_enum"
|
|
31
42
|
end
|
|
32
43
|
end
|
|
33
44
|
end
|