decidim-core 0.12.2 → 0.13.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/decidim/modules/_order-by.scss +4 -1
- data/app/cells/decidim/author/comments.erb +2 -2
- data/app/cells/decidim/author/date.erb +1 -1
- data/app/cells/decidim/author_cell.rb +22 -38
- data/app/cells/decidim/card_m/authors.erb +9 -0
- data/app/cells/decidim/card_m/status.erb +1 -1
- data/app/cells/decidim/card_m_cell.rb +8 -0
- data/app/cells/decidim/collapsible_authors/show.erb +16 -0
- data/app/cells/decidim/collapsible_authors_cell.rb +32 -0
- data/app/cells/decidim/invitations_toggle/content.erb +1 -0
- data/app/cells/decidim/invitations_toggle/label.erb +1 -0
- data/app/cells/decidim/invitations_toggle_cell.rb +27 -0
- data/app/cells/decidim/toggle/show.erb +8 -0
- data/app/cells/decidim/toggle_cell.rb +42 -0
- data/app/cells/decidim/tos_page/refuse_btn_modal.erb +25 -14
- data/app/commands/decidim/create_omniauth_registration.rb +1 -1
- data/app/commands/decidim/create_registration.rb +1 -1
- data/app/commands/decidim/create_report.rb +10 -10
- data/app/commands/decidim/invite_friends.rb +48 -0
- data/app/commands/decidim/invite_user.rb +4 -2
- data/app/commands/decidim/unsubscribe_settings.rb +3 -3
- data/app/commands/decidim/update_notifications_settings.rb +1 -1
- data/app/controllers/concerns/decidim/needs_tos_accepted.rb +6 -1
- data/app/controllers/decidim/data_portability_controller.rb +55 -0
- data/app/controllers/decidim/devise/invitations_controller.rb +1 -0
- data/app/controllers/decidim/invitations_controller.rb +32 -0
- data/app/controllers/decidim/newsletters_opt_in_controller.rb +31 -0
- data/app/forms/decidim/account_form.rb +1 -1
- data/app/forms/decidim/invitations_form.rb +37 -0
- data/app/forms/decidim/notifications_settings_form.rb +5 -0
- data/app/forms/decidim/omniauth_registration_form.rb +1 -1
- data/app/forms/decidim/registration_form.rb +7 -1
- data/app/helpers/decidim/cells_helper.rb +44 -0
- data/app/jobs/decidim/data_portability_export_job.rb +21 -0
- data/app/jobs/decidim/newsletters_opt_in_job.rb +11 -0
- data/app/mailers/decidim/export_mailer.rb +13 -0
- data/app/mailers/decidim/newsletters_opt_in_mailer.rb +15 -0
- data/app/models/decidim/coauthorship.rb +23 -0
- data/app/models/decidim/follow.rb +10 -0
- data/app/models/decidim/identity.rb +10 -0
- data/app/models/decidim/messaging/conversation.rb +10 -0
- data/app/models/decidim/notification.rb +10 -0
- data/app/models/decidim/participatory_space_private_user.rb +10 -0
- data/app/models/decidim/report.rb +10 -0
- data/app/models/decidim/user.rb +16 -1
- data/app/models/decidim/user_group.rb +9 -0
- data/app/services/decidim/action_authorizer.rb +1 -1
- data/app/uploaders/decidim/avatar_uploader.rb +6 -2
- data/app/uploaders/decidim/data_portability_uploader.rb +19 -0
- data/app/views/decidim/data_portability/export.html.erb +1 -0
- data/app/views/decidim/data_portability/show.html.erb +5 -0
- data/app/views/decidim/devise/invitations/edit.html.erb +1 -1
- data/app/views/decidim/devise/shared/_newsletter_modal.html.erb +13 -13
- data/app/views/decidim/export_mailer/data_portability_export.html.erb +2 -0
- data/app/views/decidim/invitations/index.html.erb +48 -0
- data/app/views/decidim/newsletters_opt_in_mailer/notify.html.erb +23 -0
- data/app/views/decidim/profiles/_user.html.erb +1 -1
- data/app/views/devise/mailer/invite_friend.html.erb +27 -0
- data/app/views/devise/mailer/invite_friend.text.erb +19 -0
- data/app/views/layouts/decidim/_user_menu.html.erb +1 -0
- data/config/locales/ca.yml +68 -2
- data/config/locales/en.yml +73 -3
- data/config/locales/es-PY.yml +67 -1
- data/config/locales/es.yml +67 -1
- data/config/locales/eu.yml +68 -2
- data/config/locales/fi.yml +69 -3
- data/config/locales/fr.yml +136 -70
- data/config/locales/gl.yml +69 -3
- data/config/locales/it.yml +69 -3
- data/config/locales/nl.yml +69 -3
- data/config/locales/pl.yml +69 -3
- data/config/locales/pt-BR.yml +69 -3
- data/config/locales/pt.yml +69 -3
- data/config/locales/ru.yml +45 -2
- data/config/locales/sv.yml +69 -3
- data/config/locales/uk.yml +61 -2
- data/config/routes.rb +10 -0
- data/db/migrate/20171212103803_create_unique_nicknames.rb +1 -1
- data/db/migrate/20180221101934_fix_nickname_index.rb +3 -1
- data/db/migrate/20180427141253_create_coauthorships.rb +13 -0
- data/db/migrate/20180611121852_change_newsletter_notification_type_value.rb +21 -0
- data/lib/decidim/api/authorable_interface.rb +10 -1
- data/lib/decidim/authorable.rb +4 -1
- data/lib/decidim/coauthorable.rb +69 -0
- data/lib/decidim/component_manifest.rb +4 -0
- data/lib/decidim/core.rb +10 -0
- data/lib/decidim/core/engine.rb +5 -0
- data/lib/decidim/core/test.rb +1 -0
- data/lib/decidim/core/test/factories.rb +9 -1
- data/lib/decidim/core/test/shared_examples/coauthorable.rb +111 -0
- data/lib/decidim/core/test/shared_examples/coauthorable_interface_examples.rb +31 -0
- data/lib/decidim/core/test/shared_examples/simple_event.rb +7 -1
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/data_portability.rb +29 -0
- data/lib/decidim/data_portability_file_reader.rb +56 -0
- data/lib/decidim/data_portability_file_zipper.rb +55 -0
- data/lib/decidim/data_portability_serializers.rb +23 -0
- data/lib/decidim/data_portability_serializers/data_portability_conversation_serializer.rb +42 -0
- data/lib/decidim/data_portability_serializers/data_portability_follow_serializer.rb +23 -0
- data/lib/decidim/data_portability_serializers/data_portability_identity_serializer.rb +25 -0
- data/lib/decidim/data_portability_serializers/data_portability_notification_serializer.rb +26 -0
- data/lib/decidim/data_portability_serializers/data_portability_participatory_space_private_user_serializer.rb +25 -0
- data/lib/decidim/data_portability_serializers/data_portability_report_serializer.rb +36 -0
- data/lib/decidim/data_portability_serializers/data_portability_user_group_serializer.rb +21 -0
- data/lib/decidim/data_portability_serializers/data_portability_user_serializer.rb +55 -0
- data/lib/decidim/events.rb +1 -0
- data/lib/decidim/events/coauthor_event.rb +42 -0
- data/lib/decidim/exporters/csv.rb +0 -1
- data/lib/decidim/form_builder.rb +1 -2
- data/lib/decidim/nicknamizable.rb +15 -4
- data/lib/decidim/participable.rb +7 -0
- data/lib/decidim/participatory_space_manifest.rb +4 -0
- data/lib/devise/models/decidim_newsletterable.rb +60 -0
- data/lib/tasks/decidim_tasks.rake +29 -0
- metadata +73 -28
@@ -11,7 +11,7 @@ class CreateUniqueNicknames < ActiveRecord::Migration[5.1]
|
|
11
11
|
add_column :decidim_users, :nickname, :string, limit: 20
|
12
12
|
|
13
13
|
User.where.not(name: nil).find_each do |user|
|
14
|
-
user.update!(nickname: User.nicknamize(user.name))
|
14
|
+
user.update!(nickname: User.nicknamize(user.name, decidim_organization_id: user.decidim_organization_id))
|
15
15
|
end
|
16
16
|
|
17
17
|
add_index :decidim_users,
|
@@ -3,13 +3,15 @@
|
|
3
3
|
class FixNicknameIndex < ActiveRecord::Migration[5.1]
|
4
4
|
class User < ApplicationRecord
|
5
5
|
self.table_name = :decidim_users
|
6
|
+
|
7
|
+
include Decidim::Nicknamizable
|
6
8
|
end
|
7
9
|
|
8
10
|
def change
|
9
11
|
User.where(nickname: nil)
|
10
12
|
.where(deleted_at: nil)
|
11
13
|
.where(managed: false)
|
12
|
-
.find_each { |u| u.update(nickname: User.nicknamize(u.name)) }
|
14
|
+
.find_each { |u| u.update(nickname: User.nicknamize(u.name, decidim_organization_id: u.decidim_organization_id)) }
|
13
15
|
|
14
16
|
# rubocop:disable Rails/SkipsModelValidations
|
15
17
|
User.where(nickname: nil).update_all("nickname = ''")
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateCoauthorships < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :decidim_coauthorships do |t|
|
6
|
+
t.references :decidim_author, null: false, index: { name: "index_author_on_coauthorsihp" }
|
7
|
+
t.references :decidim_user_group, index: { name: "index_user_group_on_coauthorsihp" }
|
8
|
+
t.references :coauthorable, polymorphic: true, index: { name: "index_coauthorable_on_coauthorship" }
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ChangeNewsletterNotificationTypeValue < ActiveRecord::Migration[5.2]
|
4
|
+
class User < ApplicationRecord
|
5
|
+
self.table_name = :decidim_users
|
6
|
+
end
|
7
|
+
|
8
|
+
def up
|
9
|
+
add_column :decidim_users, :newsletter_token, :string, default: ""
|
10
|
+
add_column :decidim_users, :newsletter_notifications_at, :datetime
|
11
|
+
User.where(newsletter_notifications: true).update(newsletter_notifications_at: Time.zone.parse("2018-05-24 00:00 +02:00"))
|
12
|
+
remove_column :decidim_users, :newsletter_notifications
|
13
|
+
end
|
14
|
+
|
15
|
+
def down
|
16
|
+
add_column :decidim_users, :newsletter_notifications, :boolean
|
17
|
+
User.where.not(newsletter_notifications_at: nil).update(newsletter_notifications: true)
|
18
|
+
remove_column :decidim_users, :newsletter_notifications_at
|
19
|
+
remove_column :decidim_users, :newsletter_token
|
20
|
+
end
|
21
|
+
end
|
@@ -7,7 +7,16 @@ module Decidim
|
|
7
7
|
name "AuthorableInterface"
|
8
8
|
description "An interface that can be used in authorable objects."
|
9
9
|
|
10
|
-
field :author, !Decidim::Core::AuthorInterface, "The comment's author"
|
10
|
+
field :author, !Decidim::Core::AuthorInterface, "The comment's author" do
|
11
|
+
# can be an Authorable or a Coauthorable
|
12
|
+
resolve ->(authorable, _, _) {
|
13
|
+
if authorable.respond_to?(:normalized_author)
|
14
|
+
authorable&.normalized_author
|
15
|
+
elsif authorable.respond_to?(:creator_identity)
|
16
|
+
authorable&.creator_identity
|
17
|
+
end
|
18
|
+
}
|
19
|
+
end
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
data/lib/decidim/authorable.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Decidim
|
4
|
-
# This concern contains the logic related to authorship
|
4
|
+
# This concern contains the logic related to single authorship.
|
5
|
+
#
|
6
|
+
# Sometimes authorship may belong to a single user or be shared among coauthors, in
|
7
|
+
# this latest case the Coauthorable concern should be used instead of Authorable.
|
5
8
|
module Authorable
|
6
9
|
extend ActiveSupport::Concern
|
7
10
|
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
# This concern contains the logic related to collective or shared authorship.
|
5
|
+
#
|
6
|
+
# Coauthorable shares nearly the same object interface as Authorable but with some differences.
|
7
|
+
# - `authored_by?(user)` is exactly the same
|
8
|
+
# - `normalized_author` is now `identities`.
|
9
|
+
#
|
10
|
+
# All coauthors, including the initial author, will share the same permissions.
|
11
|
+
module Coauthorable
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
included do
|
15
|
+
has_many :coauthorships, -> { order(:created_at) }, as: :coauthorable, class_name: "Decidim::Coauthorship", dependent: :destroy
|
16
|
+
has_many :authors, -> { order(:created_at) }, through: :coauthorships, class_name: "Decidim::User"
|
17
|
+
has_many :user_groups, -> { order(:created_at) }, as: :coauthorable, class_name: "Decidim::UserGroup", through: :coauthorships
|
18
|
+
|
19
|
+
# retrieves models from all identities of the user.
|
20
|
+
scope :from_all_user_identities, ->(user) { joins(:coauthorships).where("decidim_coauthorships.decidim_author_id": user.id) }
|
21
|
+
# retrieves models from the given User, ignoring the UserGroups it belongs to.
|
22
|
+
scope :from_author, ->(author) { joins(:coauthorships).where("decidim_coauthorships.decidim_author_id": author.id).where("decidim_coauthorships.decidim_user_group_id": nil) }
|
23
|
+
# retrieves models from the given UserGroup.
|
24
|
+
scope :from_user_group, ->(user_group) { joins(:coauthorships).where("decidim_coauthorships.decidim_user_group_id": user_group.id) }
|
25
|
+
|
26
|
+
# Checks whether the user is author of the given proposal, either directly
|
27
|
+
# authoring it or via a user group.
|
28
|
+
#
|
29
|
+
# user - the user to check for authorship
|
30
|
+
def authored_by?(user)
|
31
|
+
coauthorships.where(author: user).exists?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the identities for the authors, whether they are user groups or users.
|
35
|
+
#
|
36
|
+
# Returns an Array of User and/or UserGroups.
|
37
|
+
def identities
|
38
|
+
coauthorships.order(:created_at).collect(&:identity)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Syntactic sugar to access first coauthor as a Coauthorship.
|
42
|
+
def creator
|
43
|
+
coauthorships.first
|
44
|
+
end
|
45
|
+
|
46
|
+
# Syntactic sugar to access first coauthor Author
|
47
|
+
def creator_author
|
48
|
+
authors.first
|
49
|
+
end
|
50
|
+
|
51
|
+
# Syntactic sugar to access first identity whether it is a User or a UserGroup.
|
52
|
+
# @return The User od UserGroup that created this Coauthorable.
|
53
|
+
def creator_identity
|
54
|
+
coauthorships.order(:created_at).first&.identity
|
55
|
+
end
|
56
|
+
|
57
|
+
# Adds a new coauthor to the list of coauthors. The coauthorship is created with
|
58
|
+
# current object as coauthorable and `user` param as author. To set the user group
|
59
|
+
# use `extra_attrs` either with `user_group` or `decidim_user_group_id` keys.
|
60
|
+
#
|
61
|
+
# @param user: The new coauthor.
|
62
|
+
# @extra_attrs: Extra
|
63
|
+
def add_coauthor(user, extra_attrs = {})
|
64
|
+
attrs = { coauthorable: self, author: user }
|
65
|
+
Decidim::Coauthorship.create!(attrs.merge(extra_attrs))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -21,6 +21,10 @@ module Decidim
|
|
21
21
|
|
22
22
|
attribute :query_type, String, default: "Decidim::Core::ComponentType"
|
23
23
|
|
24
|
+
# An array with the name of the classes that will be exported with
|
25
|
+
# the data portability feature for this component. For example, `Decidim::<MyModule>::<MyClass>``
|
26
|
+
attribute :data_portable_entities, Array, default: []
|
27
|
+
|
24
28
|
# A path with the `scss` stylesheet this engine provides. It is used to
|
25
29
|
# mix this engine's stylesheets with the main app's stylesheets so it can
|
26
30
|
# use the scss variables and mixins provided by Decidim::Core.
|
data/lib/decidim/core.rb
CHANGED
@@ -18,6 +18,7 @@ module Decidim
|
|
18
18
|
autoload :Loggable, "decidim/loggable"
|
19
19
|
autoload :Reportable, "decidim/reportable"
|
20
20
|
autoload :Authorable, "decidim/authorable"
|
21
|
+
autoload :Coauthorable, "decidim/coauthorable"
|
21
22
|
autoload :Participable, "decidim/participable"
|
22
23
|
autoload :Publicable, "decidim/publicable"
|
23
24
|
autoload :Scopable, "decidim/scopable"
|
@@ -57,6 +58,10 @@ module Decidim
|
|
57
58
|
autoload :ViewModel, "decidim/view_model"
|
58
59
|
autoload :FingerprintCalculator, "decidim/fingerprint_calculator"
|
59
60
|
autoload :Fingerprintable, "decidim/fingerprintable"
|
61
|
+
autoload :DataPortability, "decidim/data_portability"
|
62
|
+
autoload :DataPortabilitySerializers, "decidim/data_portability_serializers"
|
63
|
+
autoload :DataPortabilityFileReader, "decidim/data_portability_file_reader"
|
64
|
+
autoload :DataPortabilityFileZipper, "decidim/data_portability_file_zipper"
|
60
65
|
|
61
66
|
include ActiveSupport::Configurable
|
62
67
|
|
@@ -176,6 +181,11 @@ module Decidim
|
|
176
181
|
true
|
177
182
|
end
|
178
183
|
|
184
|
+
# Time that data portability files are available in server
|
185
|
+
config_accessor :data_portability_expiry_time do
|
186
|
+
7.days
|
187
|
+
end
|
188
|
+
|
179
189
|
# Max requests in a time period to prevent DoS attacks. Only applied on production.
|
180
190
|
config_accessor :throttling_max_requests do
|
181
191
|
100
|
data/lib/decidim/core/engine.rb
CHANGED
@@ -40,6 +40,7 @@ require "cells-erb"
|
|
40
40
|
require "kaminari"
|
41
41
|
require "doorkeeper"
|
42
42
|
require "doorkeeper-i18n"
|
43
|
+
require "nobspw"
|
43
44
|
require "kaminari"
|
44
45
|
|
45
46
|
require "decidim/api"
|
@@ -167,6 +168,10 @@ module Decidim
|
|
167
168
|
position: 1.3
|
168
169
|
end
|
169
170
|
|
171
|
+
menu.item t("my_data", scope: "layouts.decidim.user_profile"),
|
172
|
+
decidim.data_portability_path,
|
173
|
+
position: 1.4
|
174
|
+
|
170
175
|
menu.item t("delete_my_account", scope: "layouts.decidim.user_profile"),
|
171
176
|
decidim.delete_account_path,
|
172
177
|
position: 999,
|
data/lib/decidim/core/test.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "decidim/core/test/shared_examples/authorable"
|
4
|
+
require "decidim/core/test/shared_examples/coauthorable"
|
4
5
|
require "decidim/core/test/shared_examples/publicable"
|
5
6
|
require "decidim/core/test/shared_examples/localised_email"
|
6
7
|
require "decidim/core/test/shared_examples/has_attachments"
|
@@ -82,7 +82,7 @@ FactoryBot.define do
|
|
82
82
|
factory :user, class: "Decidim::User" do
|
83
83
|
email { generate(:email) }
|
84
84
|
password "password1234"
|
85
|
-
password_confirmation
|
85
|
+
password_confirmation { password }
|
86
86
|
name { generate(:name) }
|
87
87
|
nickname { generate(:nickname) }
|
88
88
|
organization
|
@@ -289,6 +289,14 @@ FactoryBot.define do
|
|
289
289
|
organization
|
290
290
|
end
|
291
291
|
|
292
|
+
factory :coauthorship, class: "Decidim::Coauthorship" do
|
293
|
+
coauthorable { create(:dummy_resource) }
|
294
|
+
transient do
|
295
|
+
organization { coauthorable.component.participatory_space.organization }
|
296
|
+
end
|
297
|
+
author { create(:user, :confirmed, organization: organization) }
|
298
|
+
end
|
299
|
+
|
292
300
|
factory :dummy_resource, class: "Decidim::DummyResources::DummyResource" do
|
293
301
|
title { generate(:name) }
|
294
302
|
component { create(:component, manifest_name: "dummy") }
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "coauthorable" do
|
6
|
+
describe "authorable interface" do
|
7
|
+
let!(:creator_author) { coauthorable.authors.first }
|
8
|
+
let(:other_authors) { create_list(:user, 5, organization: coauthorable.component.participatory_space.organization) }
|
9
|
+
let(:other_user_groups) { create_list(:user_group, 5, :verified, organization: creator_author.organization, users: [creator_author]) }
|
10
|
+
|
11
|
+
describe "authors" do
|
12
|
+
context "when there is one author" do
|
13
|
+
it "returns the only coauthor" do
|
14
|
+
expect(coauthorable.authors).to eq([creator_author])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when there are many authors" do
|
19
|
+
before { coauthorable.authors = other_authors }
|
20
|
+
|
21
|
+
it "returns all coauthors" do
|
22
|
+
expect(coauthorable.authors).to eq(other_authors)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "user_groups" do
|
28
|
+
let(:user_group) do
|
29
|
+
create(:user_group,
|
30
|
+
:verified,
|
31
|
+
organization: creator_author.organization,
|
32
|
+
users: [creator_author])
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when there is NO user_group" do
|
36
|
+
it "returns empty array" do
|
37
|
+
expect(coauthorable.user_groups).to eq([])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when there is one user_group" do
|
42
|
+
before do
|
43
|
+
coauthorship = coauthorable.coauthorships.first
|
44
|
+
coauthorship.user_group = user_group
|
45
|
+
coauthorship.save
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the only user_group" do
|
49
|
+
expect(coauthorable.user_groups).to eq([user_group])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when there are many user_groups" do
|
54
|
+
before do
|
55
|
+
coauthorable.coauthorships.clear
|
56
|
+
other_user_groups.each do |ug|
|
57
|
+
Decidim::Coauthorship.create(author: ug.memberships.first.user, user_group: ug, coauthorable: coauthorable)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns all user_groups" do
|
62
|
+
expect(coauthorable.user_groups).to eq(other_user_groups)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "authored by? user" do
|
68
|
+
context "when there are no coauthors" do
|
69
|
+
before { coauthorable.authors.clear }
|
70
|
+
|
71
|
+
it "returns false" do
|
72
|
+
expect(coauthorable.authored_by?(creator_author)).to be(false)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
context "when the checked user is one of the coauthors" do
|
76
|
+
before do
|
77
|
+
other_authors.each { |author| coauthorable.authors << author }
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns true" do
|
81
|
+
expect(coauthorable.authored_by?(creator_author)).to be(true)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the checked user is one of the coauthors user_groups"
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "identities" do
|
89
|
+
context "when there are no coauthors" do
|
90
|
+
before { coauthorable.authors.clear }
|
91
|
+
|
92
|
+
it "returns an empty list" do
|
93
|
+
end
|
94
|
+
end
|
95
|
+
context "when there are many coauthors of both types" do
|
96
|
+
before do
|
97
|
+
other_authors.each { |author| coauthorable.authors << author }
|
98
|
+
other_user_groups.each do |user_group|
|
99
|
+
Decidim::Coauthorship.create(author: user_group.memberships.first.user, user_group: user_group, coauthorable: coauthorable)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
it "returns an array of identities" do
|
103
|
+
identities = [creator_author]
|
104
|
+
identities += other_authors
|
105
|
+
identities += other_user_groups
|
106
|
+
expect(coauthorable.identities.to_a).to eq(identities)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "coauthorable interface" do
|
6
|
+
describe "author" do
|
7
|
+
let(:author) { model.creator_author }
|
8
|
+
|
9
|
+
describe "with a regular user" do
|
10
|
+
let(:query) { "{ author { name } }" }
|
11
|
+
|
12
|
+
it "includes the user's ID" do
|
13
|
+
expect(response["author"]["name"]).to eq(author.name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "with a user group" do
|
18
|
+
let(:user_group) { create(:user_group, :verified, organization: model.participatory_space.organization, users: [author]) }
|
19
|
+
let(:query) { "{ author { name } }" }
|
20
|
+
|
21
|
+
before do
|
22
|
+
coauthorship = model.coauthorships.first
|
23
|
+
coauthorship.update!(user_group: user_group)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "includes the user's ID" do
|
27
|
+
expect(response["author"]["name"]).to eq(user_group.name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -28,7 +28,13 @@ shared_context "when a simple event" do
|
|
28
28
|
let(:participatory_space_title) { participatory_space.title["en"] }
|
29
29
|
let(:participatory_space_path) { Decidim::ResourceLocatorPresenter.new(participatory_space).path }
|
30
30
|
let(:participatory_space_url) { Decidim::ResourceLocatorPresenter.new(participatory_space).url }
|
31
|
-
let(:author)
|
31
|
+
let(:author) do
|
32
|
+
if resource.respond_to?(:creator_author)
|
33
|
+
resource.creator_author
|
34
|
+
else
|
35
|
+
resource.author
|
36
|
+
end
|
37
|
+
end
|
32
38
|
let(:author_presenter) { Decidim::UserPresenter.new(author) }
|
33
39
|
let(:i18n_scope) { event_name }
|
34
40
|
end
|
data/lib/decidim/core/version.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
# This concern contains the logic related to data portability.
|
7
|
+
module DataPortability
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
# Returns a collection scoped by user.
|
12
|
+
# This is the default, if you want, you can overwrite in each Class to be export.
|
13
|
+
def self.user_collection(user)
|
14
|
+
where(decidim_author_id: user.id)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a Default export serializer
|
18
|
+
def self.export_serializer
|
19
|
+
Decidim::Exporters::Serializer
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a collection of images scoped by User.
|
23
|
+
# Returns nil for default.
|
24
|
+
def self.data_portability_images(_user)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|