decidim-bulletin_board 0.13.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,19 +10,22 @@ Gem::Specification.new do |s|
10
10
 
11
11
  s.summary = ""
12
12
  s.description = ""
13
- s.homepage = "https://github.com"
13
+ s.homepage = "https://github.com/decidim/decidim-bulletin-board"
14
14
  s.license = "AGPL-3.0"
15
15
  s.required_ruby_version = Gem::Requirement.new(">= 2.6.6")
16
16
 
17
17
  # Specify which files should be added to the gem when it is released.
18
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
19
  s.files = Dir.chdir(File.expand_path(__dir__)) do
20
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ `git ls-files -z`
21
+ .split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ .concat(["app/assets/javascripts/decidim/bulletin_board/decidim-bulletin_board.js"])
21
23
  end
22
24
  s.bindir = "exe"
23
25
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
26
  s.require_paths = ["lib"]
25
27
 
28
+ s.add_dependency "mimemagic", "~> 0.3.7"
26
29
  s.add_dependency "rails", ">= 5.0.0"
27
30
 
28
31
  s.add_dependency "byebug", "~> 11.0"
@@ -8,6 +8,7 @@ require "graphlient"
8
8
  require "wisper"
9
9
 
10
10
  require "decidim/bulletin_board/client"
11
+ require "decidim/bulletin_board/file_client"
11
12
  require "decidim/bulletin_board/engine"
12
13
  require "decidim/bulletin_board/jwk_utils"
13
14
  require "decidim/bulletin_board/message_identifier"
@@ -69,16 +69,16 @@ module Decidim
69
69
 
70
70
  def bulletin_board
71
71
  {
72
- name: "bulletin-board",
73
- pretty_name: "Bulletin Board",
72
+ slug: "bulletin-board",
73
+ name: "Bulletin Board",
74
74
  public_key: settings.bulletin_board_public_key
75
75
  }
76
76
  end
77
77
 
78
78
  def authority
79
79
  {
80
- name: settings.authority_slug,
81
- pretty_name: settings.authority_name,
80
+ slug: settings.authority_slug,
81
+ name: settings.authority_name,
82
82
  public_key: settings.authority_public_key
83
83
  }
84
84
  end
@@ -86,22 +86,22 @@ module Decidim
86
86
  def trustees
87
87
  election_data[:trustees].map do |trustee|
88
88
  {
89
- name: trustee[:slug],
90
- pretty_name: trustee[:name],
89
+ slug: trustee[:name].parameterize,
90
+ name: trustee[:name],
91
91
  public_key: trustee[:public_key]
92
92
  }
93
93
  end
94
94
  end
95
95
 
96
96
  def contests
97
- election_data[:questions].map do |question|
97
+ election_data[:questions].each_with_index.map do |question, index|
98
98
  {
99
99
  "@type": "CandidateContest",
100
100
  object_id: question[:slug],
101
- sequence_order: question[:weight],
101
+ sequence_order: index,
102
102
  vote_variation: question[:max_selections] == 1 ? "one_of_m" : "n_of_m",
103
103
  name: default_text(question[:title]),
104
- number_elected: question[:answers].count,
104
+ number_elected: question[:max_selections],
105
105
  ballot_title: text(question[:title]),
106
106
  ballot_subtitle: text(question[:description]),
107
107
  ballot_selections: contest_answers(question)
@@ -110,10 +110,10 @@ module Decidim
110
110
  end
111
111
 
112
112
  def contest_answers(question)
113
- question[:answers].map do |answer|
113
+ question[:answers].each_with_index.map do |answer, index|
114
114
  {
115
115
  object_id: "#{question[:slug]}_#{answer[:slug]}",
116
- sequence_order: answer[:weight],
116
+ sequence_order: index,
117
117
  candidate_id: answer[:slug]
118
118
  }
119
119
  end
@@ -33,7 +33,7 @@ module Decidim
33
33
  response = graphql.query do
34
34
  mutation do
35
35
  publishResults(messageId: args[:message_id], signedData: args[:signed_data]) do
36
- election do
36
+ pendingMessage do
37
37
  status
38
38
  end
39
39
  error
@@ -43,7 +43,7 @@ module Decidim
43
43
 
44
44
  return broadcast(:error, response.data.publish_results.error) if response.data.publish_results.error.present?
45
45
 
46
- broadcast(:ok, response.data.publish_results.election)
46
+ broadcast(:ok, response.data.publish_results.pending_message)
47
47
  rescue Graphlient::Errors::ServerError
48
48
  broadcast(:error, "Sorry, something went wrong")
49
49
  end
@@ -14,6 +14,7 @@ require "decidim/bulletin_board/authority/publish_results"
14
14
  require "decidim/bulletin_board/authority/get_election_results"
15
15
  require "decidim/bulletin_board/voter/cast_vote"
16
16
  require "decidim/bulletin_board/voter/get_pending_message_status"
17
+ require "decidim/bulletin_board/test/reset_test_database"
17
18
 
18
19
  module Decidim
19
20
  module BulletinBoard
@@ -101,11 +102,20 @@ module Decidim
101
102
  def publish_results(election_id)
102
103
  publish_results = configure Authority::PublishResults.new(election_id)
103
104
  yield publish_results.message_id if block_given?
104
- publish_results.on(:ok) { |status| return status }
105
+ publish_results.on(:ok) { |pending_message| return pending_message }
105
106
  publish_results.on(:error) { |error_message| raise StandardError, error_message }
106
107
  publish_results.call
107
108
  end
108
109
 
110
+ if Rails.env.test?
111
+ def reset_test_database
112
+ reset_test_database = configure Test::ResetTestDatabase.new
113
+ reset_test_database.on(:ok) { |result| return result }
114
+ reset_test_database.on(:error) { |error_message| raise StandardError, error_message }
115
+ reset_test_database.call
116
+ end
117
+ end
118
+
109
119
  private
110
120
 
111
121
  attr_reader :settings, :graphql
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module BulletinBoard
5
+ # Client to store GraphQL requests to a CSV file instead of sending them to the BulletinBoard
6
+ # It is intended to be used for load testing
7
+ class FileClient < Decidim::BulletinBoard::Client
8
+ def initialize(file_path, config = Decidim::BulletinBoard)
9
+ @settings = Settings.new(config)
10
+ @graphql = Graphql::Factory.client_for_file(settings, file_path)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -310,6 +310,34 @@
310
310
  },
311
311
  "isDeprecated": false,
312
312
  "deprecationReason": null
313
+ },
314
+ {
315
+ "name": "verifiableResultsHash",
316
+ "description": null,
317
+ "args": [
318
+
319
+ ],
320
+ "type": {
321
+ "kind": "SCALAR",
322
+ "name": "String",
323
+ "ofType": null
324
+ },
325
+ "isDeprecated": false,
326
+ "deprecationReason": null
327
+ },
328
+ {
329
+ "name": "verifiableResultsUrl",
330
+ "description": null,
331
+ "args": [
332
+
333
+ ],
334
+ "type": {
335
+ "kind": "SCALAR",
336
+ "name": "String",
337
+ "ofType": null
338
+ },
339
+ "isDeprecated": false,
340
+ "deprecationReason": null
313
341
  }
314
342
  ],
315
343
  "inputFields": null,
@@ -370,6 +398,16 @@
370
398
  "enumValues": null,
371
399
  "possibleTypes": null
372
400
  },
401
+ {
402
+ "kind": "SCALAR",
403
+ "name": "Int",
404
+ "description": "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.",
405
+ "fields": null,
406
+ "inputFields": null,
407
+ "interfaces": null,
408
+ "enumValues": null,
409
+ "possibleTypes": null
410
+ },
373
411
  {
374
412
  "kind": "SCALAR",
375
413
  "name": "JSON",
@@ -442,13 +480,9 @@
442
480
 
443
481
  ],
444
482
  "type": {
445
- "kind": "NON_NULL",
446
- "name": null,
447
- "ofType": {
448
- "kind": "SCALAR",
449
- "name": "JSON",
450
- "ofType": null
451
- }
483
+ "kind": "SCALAR",
484
+ "name": "JSON",
485
+ "ofType": null
452
486
  },
453
487
  "isDeprecated": false,
454
488
  "deprecationReason": null
@@ -851,6 +885,20 @@
851
885
  "isDeprecated": false,
852
886
  "deprecationReason": null
853
887
  },
888
+ {
889
+ "name": "resetTestDatabase",
890
+ "description": null,
891
+ "args": [
892
+
893
+ ],
894
+ "type": {
895
+ "kind": "OBJECT",
896
+ "name": "ResetTestDatabaseMutationPayload",
897
+ "ofType": null
898
+ },
899
+ "isDeprecated": false,
900
+ "deprecationReason": null
901
+ },
854
902
  {
855
903
  "name": "startKeyCeremony",
856
904
  "description": null,
@@ -1232,28 +1280,28 @@
1232
1280
  "description": "Autogenerated return type of PublishResultsMutation",
1233
1281
  "fields": [
1234
1282
  {
1235
- "name": "election",
1283
+ "name": "error",
1236
1284
  "description": null,
1237
1285
  "args": [
1238
1286
 
1239
1287
  ],
1240
1288
  "type": {
1241
- "kind": "OBJECT",
1242
- "name": "Election",
1289
+ "kind": "SCALAR",
1290
+ "name": "String",
1243
1291
  "ofType": null
1244
1292
  },
1245
1293
  "isDeprecated": false,
1246
1294
  "deprecationReason": null
1247
1295
  },
1248
1296
  {
1249
- "name": "error",
1297
+ "name": "pendingMessage",
1250
1298
  "description": null,
1251
1299
  "args": [
1252
1300
 
1253
1301
  ],
1254
1302
  "type": {
1255
- "kind": "SCALAR",
1256
- "name": "String",
1303
+ "kind": "OBJECT",
1304
+ "name": "PendingMessage",
1257
1305
  "ofType": null
1258
1306
  },
1259
1307
  "isDeprecated": false,
@@ -1451,6 +1499,37 @@
1451
1499
  "enumValues": null,
1452
1500
  "possibleTypes": null
1453
1501
  },
1502
+ {
1503
+ "kind": "OBJECT",
1504
+ "name": "ResetTestDatabaseMutationPayload",
1505
+ "description": "Autogenerated return type of ResetTestDatabaseMutation",
1506
+ "fields": [
1507
+ {
1508
+ "name": "timestamp",
1509
+ "description": null,
1510
+ "args": [
1511
+
1512
+ ],
1513
+ "type": {
1514
+ "kind": "NON_NULL",
1515
+ "name": null,
1516
+ "ofType": {
1517
+ "kind": "SCALAR",
1518
+ "name": "Int",
1519
+ "ofType": null
1520
+ }
1521
+ },
1522
+ "isDeprecated": false,
1523
+ "deprecationReason": null
1524
+ }
1525
+ ],
1526
+ "inputFields": null,
1527
+ "interfaces": [
1528
+
1529
+ ],
1530
+ "enumValues": null,
1531
+ "possibleTypes": null
1532
+ },
1454
1533
  {
1455
1534
  "kind": "OBJECT",
1456
1535
  "name": "StartKeyCeremonyMutationPayload",
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "decidim/bulletin_board/graphql/file_adapter"
4
+
3
5
  module Decidim
4
6
  module BulletinBoard
5
7
  module Graphql
@@ -12,6 +14,15 @@ module Decidim
12
14
  "Authorization" => settings.authority_api_key
13
15
  })
14
16
  end
17
+
18
+ def self.client_for_file(settings, file_path)
19
+ Graphlient::Client.new(file_path,
20
+ schema_path: File.join(__dir__, "bb_schema.json"),
21
+ http: FileAdapter,
22
+ headers: {
23
+ "Authorization" => settings.authority_api_key
24
+ })
25
+ end
15
26
  end
16
27
  end
17
28
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ module Decidim
6
+ module BulletinBoard
7
+ module Graphql
8
+ class FileAdapter
9
+ attr_reader :file_name
10
+
11
+ def initialize(file_name, _options = {}, &_block)
12
+ @file_name = file_name
13
+ end
14
+
15
+ def execute(document:, operation_name: nil, variables: {}, context: {})
16
+ body = {}
17
+ body["query"] = document.to_query_string
18
+ body["variables"] = variables if variables.any?
19
+ body["operationName"] = operation_name if operation_name
20
+
21
+ CSV.open(file_name, "a+", col_sep: ";") do |csv|
22
+ csv << [JSON.generate(body), context[:headers]["Authorization"]]
23
+ end
24
+
25
+ { "data" => { "vote" => {} } }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -60,6 +60,10 @@ module Decidim
60
60
  @message_id
61
61
  end
62
62
 
63
+ def unique_trustee_id(authority_slug, trustee_name)
64
+ "#{authority_slug}.#{trustee_name}"
65
+ end
66
+
63
67
  class << self
64
68
  def format(unique_election_id, type_subtype, author_type, author_id)
65
69
  "#{unique_election_id}.#{type_subtype}+#{INVERTED_AUTHOR_TYPE[author_type]}.#{author_id}"
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module BulletinBoard
5
+ module Test
6
+ # This command uses the GraphQL client to clear the database in test mode.
7
+ class ResetTestDatabase < Decidim::BulletinBoard::Command
8
+ # Executes the command. Broadcasts these events:
9
+ #
10
+ # - :ok when everything is valid and the mutation operation is successful.
11
+ # - :error if query operation was not successful.
12
+ #
13
+ # Returns nothing.
14
+ def call
15
+ graphql.query do
16
+ mutation do
17
+ resetTestDatabase do
18
+ timestamp
19
+ end
20
+ end
21
+ end
22
+
23
+ broadcast(:ok)
24
+ rescue Graphlient::Errors::ServerError
25
+ broadcast(:error, "Sorry, something went wrong")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Decidim
4
4
  module BulletinBoard
5
- VERSION = "0.13.0"
5
+ VERSION = "0.16.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-bulletin_board
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Morcillo
@@ -11,8 +11,22 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2021-02-23 00:00:00.000000000 Z
14
+ date: 2021-04-06 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: mimemagic
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: 0.3.7
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 0.3.7
16
30
  - !ruby/object:Gem::Dependency
17
31
  name: rails
18
32
  requirement: !ruby/object:Gem::Requirement
@@ -154,8 +168,6 @@ files:
154
168
  - ".rubocop.yml"
155
169
  - ".ruby-version"
156
170
  - ".travis.yml"
157
- - CHANGELOG.md
158
- - CODE_OF_CONDUCT.md
159
171
  - Gemfile
160
172
  - Gemfile.lock
161
173
  - README.md
@@ -163,7 +175,6 @@ files:
163
175
  - app/assets/config/manifest.js
164
176
  - app/assets/javascripts/decidim/bulletin_board/decidim-bulletin_board.js
165
177
  - bin/console
166
- - bin/release
167
178
  - bin/setup
168
179
  - decidim-bulletin_board.gemspec
169
180
  - lib/decidim/bulletin_board.rb
@@ -178,15 +189,18 @@ files:
178
189
  - lib/decidim/bulletin_board/client.rb
179
190
  - lib/decidim/bulletin_board/command.rb
180
191
  - lib/decidim/bulletin_board/engine.rb
192
+ - lib/decidim/bulletin_board/file_client.rb
181
193
  - lib/decidim/bulletin_board/graphql/bb_schema.json
182
194
  - lib/decidim/bulletin_board/graphql/factory.rb
195
+ - lib/decidim/bulletin_board/graphql/file_adapter.rb
183
196
  - lib/decidim/bulletin_board/jwk_utils.rb
184
197
  - lib/decidim/bulletin_board/message_identifier.rb
185
198
  - lib/decidim/bulletin_board/settings.rb
199
+ - lib/decidim/bulletin_board/test/reset_test_database.rb
186
200
  - lib/decidim/bulletin_board/version.rb
187
201
  - lib/decidim/bulletin_board/voter/cast_vote.rb
188
202
  - lib/decidim/bulletin_board/voter/get_pending_message_status.rb
189
- homepage: https://github.com
203
+ homepage: https://github.com/decidim/decidim-bulletin-board
190
204
  licenses:
191
205
  - AGPL-3.0
192
206
  metadata: {}