diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index b95f420515..1f8935739f 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -88,7 +88,11 @@ jobs: key: asset-cache-${{ runner.os }}-${{ steps.cache-hash.outputs.hash }} - run: mkdir -p ./spec/tmp/screenshots name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 + + # TODO: Use latest version + - uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: "114.0.5735.90" - run: bundle exec rake "test:run[exclude, spec/system/**/*_spec.rb, ${{ matrix.slice }}]" name: RSpec - run: ./.github/upload_coverage.sh decidim-app $GITHUB_EVENT_PATH @@ -153,7 +157,10 @@ jobs: key: asset-cache-${{ runner.os }}-${{ steps.cache-hash.outputs.hash }} - run: mkdir -p ./spec/tmp/screenshots name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 + # TODO: Use latest version + - uses: nanasess/setup-chromedriver@v2 + with: + chromedriver-version: "114.0.5735.90" - run: bundle exec rake "test:run[include, spec/system/**/*_spec.rb, ${{ matrix.slice }}]" name: RSpec - run: ./.github/upload_coverage.sh decidim-app $GITHUB_EVENT_PATH diff --git a/.rubocop_rails.yml b/.rubocop_rails.yml index 78093bd531..0ec984f454 100644 --- a/.rubocop_rails.yml +++ b/.rubocop_rails.yml @@ -87,6 +87,8 @@ Rails/ScopeArgs: Rails/SkipsModelValidations: Enabled: true + Exclude: + - db/migrate/*.rb Rails/Validation: Include: diff --git a/Gemfile.lock b/Gemfile.lock index a0597ebc64..af952b5432 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -15,7 +15,7 @@ GIT GIT remote: https://github.com/OpenSourcePolitics/decidim-module-homepage_interactive_map.git - revision: 3bbd5fff51fbfa94ff6e784baa73af190b1c679d + revision: 4e6b7a1a5fcfa0661ba93d1bedb2e09da66d5326 branch: release/0.26-stable specs: decidim-homepage_interactive_map (2.0.0) diff --git a/app/services/decidim/repair_comments_service.rb b/app/services/decidim/repair_comments_service.rb new file mode 100644 index 0000000000..284f2ffac1 --- /dev/null +++ b/app/services/decidim/repair_comments_service.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Decidim + class RepairCommentsService + include Decidim::TranslatableAttributes + + def self.run + new.execute + end + + def execute + return [] if ok? + + update_comments! + end + + def ok? + invalid_comments.empty? + end + + def invalid_comments + return @invalid_comments if @invalid_comments + + invalid_comments = [] + Decidim::Comments::Comment.find_each do |comment| + next if translated_attribute(comment.body).is_a?(String) + + invalid_comments << [comment, comment.body.values.first] + end + @invalid_comments = invalid_comments + end + + private + + # Update each users with new nickname + # Returns Array of updated User ID + def update_comments! + invalid_comments.map do |comment, new_body| + comment.body = new_body + + comment.id if comment.save!(validate: false) # Validation is skipped to allow updating comments from root that don't accepts new comments + end.compact + end + end +end diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 1e6e8ad8b8..5e75fcffde 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -require "initializers/sentry_setup" +require "decidim_app/sentry_setup" SentrySetup.init diff --git a/db/migrate/20180611124846_fix_nickname_index.decidim.rb b/db/migrate/20180611124846_fix_nickname_index.decidim.rb index e9dd2e0584..948cc5efc7 100644 --- a/db/migrate/20180611124846_fix_nickname_index.decidim.rb +++ b/db/migrate/20180611124846_fix_nickname_index.decidim.rb @@ -13,10 +13,7 @@ def change .where(managed: false) .find_each { |u| u.update(nickname: User.nicknamize(u.name)) } - # rubocop:disable Rails/SkipsModelValidations User.where(nickname: nil).update_all("nickname = ''") - # rubocop:enable Rails/SkipsModelValidations - change_column_default :decidim_users, :nickname, "" change_column_null(:decidim_users, :nickname, false) end diff --git a/db/migrate/20180611124847_add_version_to_action_logs.decidim.rb b/db/migrate/20180611124847_add_version_to_action_logs.decidim.rb index a9141efb12..046646215b 100644 --- a/db/migrate/20180611124847_add_version_to_action_logs.decidim.rb +++ b/db/migrate/20180611124847_add_version_to_action_logs.decidim.rb @@ -14,9 +14,7 @@ def up version_id = action_log.extra.dig("version", "id") next unless version_id - # rubocop:disable Rails/SkipsModelValidations action_log.update_column(:version_id, version_id) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20180611124849_rename_features_to_components.decidim.rb b/db/migrate/20180611124849_rename_features_to_components.decidim.rb index 7e5bee3caf..e2b4b00a78 100644 --- a/db/migrate/20180611124849_rename_features_to_components.decidim.rb +++ b/db/migrate/20180611124849_rename_features_to_components.decidim.rb @@ -20,11 +20,8 @@ def change rename_index :decidim_components, "index_decidim_features_on_decidim_participatory_space", "index_decidim_components_on_decidim_participatory_space" end - # rubocop:disable Rails/SkipsModelValidations Version.where(item_type: "Decidim::Feature").update_all(item_type: "Decidim::Component") ActionLog.where(resource_type: "Decidim::Feature").update_all(resource_type: "Decidim::Component") - # rubocop:enable Rails/SkipsModelValidations - ActionLog.find_each do |log| new_extra = log.extra.dup next if new_extra["component"].present? diff --git a/db/migrate/20180611124852_change_event_name_and_class_to_rename_to_publish_proposal_event.decidim.rb b/db/migrate/20180611124852_change_event_name_and_class_to_rename_to_publish_proposal_event.decidim.rb index 4a3c6cb244..6b58ca3a30 100644 --- a/db/migrate/20180611124852_change_event_name_and_class_to_rename_to_publish_proposal_event.decidim.rb +++ b/db/migrate/20180611124852_change_event_name_and_class_to_rename_to_publish_proposal_event.decidim.rb @@ -4,16 +4,12 @@ class ChangeEventNameAndClassToRenameToPublishProposalEvent < ActiveRecord::Migration[5.1] def up - # rubocop:disable Rails/SkipsModelValidations Decidim::Notification.where(event_name: "decidim.events.proposals.proposal_created") .update_all(event_name: "decidim.events.proposals.proposal_published", event_class: "Decidim::Proposals::PublishProposalEvent") - # rubocop:enable Rails/SkipsModelValidations end def down - # rubocop:disable Rails/SkipsModelValidations Decidim::Notification.where(event_name: "decidim.events.proposals.proposal_published") .update_all(event_name: "decidim.events.proposals.proposal_created", event_class: "Decidim::Proposals::CreateProposalEvent") - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20180611124854_add_accepted_tos_version_field_to_users.decidim.rb b/db/migrate/20180611124854_add_accepted_tos_version_field_to_users.decidim.rb index b74e8e6f4f..c2f28377a4 100644 --- a/db/migrate/20180611124854_add_accepted_tos_version_field_to_users.decidim.rb +++ b/db/migrate/20180611124854_add_accepted_tos_version_field_to_users.decidim.rb @@ -15,9 +15,7 @@ class User < ApplicationRecord def up add_column :decidim_users, :accepted_tos_version, :datetime Organization.find_each do |organization| - # rubocop:disable Rails/SkipsModelValidations organization.users.update_all(accepted_tos_version: organization.tos_version) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20180611124915_update_root_commentable_for_comments.decidim_comments.rb b/db/migrate/20180611124915_update_root_commentable_for_comments.decidim_comments.rb index c91d689a94..891aedfc31 100644 --- a/db/migrate/20180611124915_update_root_commentable_for_comments.decidim_comments.rb +++ b/db/migrate/20180611124915_update_root_commentable_for_comments.decidim_comments.rb @@ -4,12 +4,9 @@ class UpdateRootCommentableForComments < ActiveRecord::Migration[5.0] def up - # rubocop:disable Rails/SkipsModelValidations Decidim::Comments::Comment.where(depth: 0).update_all( "decidim_root_commentable_id = decidim_commentable_id, decidim_root_commentable_type = decidim_commentable_type" ) - # rubocop:enable Rails/SkipsModelValidations - Decidim::Comments::Comment.where("depth > 0").find_each do |comment| comment.root_commentable = root_commentable(comment) comment.save(validate: false) diff --git a/db/migrate/20180611124952_add_published_at_to_proposals.decidim_proposals.rb b/db/migrate/20180611124952_add_published_at_to_proposals.decidim_proposals.rb index e43a6bc50d..0b7a78d21f 100644 --- a/db/migrate/20180611124952_add_published_at_to_proposals.decidim_proposals.rb +++ b/db/migrate/20180611124952_add_published_at_to_proposals.decidim_proposals.rb @@ -5,9 +5,7 @@ class AddPublishedAtToProposals < ActiveRecord::Migration[5.1] def up add_column :decidim_proposals_proposals, :published_at, :datetime, index: true - # rubocop:disable Rails/SkipsModelValidations Decidim::Proposals::Proposal.update_all("published_at = updated_at") - # rubocop:enable Rails/SkipsModelValidations end def down diff --git a/db/migrate/20180611124987_migrate_old_results.decidim_accountability.rb b/db/migrate/20180611124987_migrate_old_results.decidim_accountability.rb index 83d40d794f..12e8d14763 100644 --- a/db/migrate/20180611124987_migrate_old_results.decidim_accountability.rb +++ b/db/migrate/20180611124987_migrate_old_results.decidim_accountability.rb @@ -26,7 +26,6 @@ class ResourceLink < ApplicationRecord def up return unless ActiveRecord::Base.connection.data_source_exists? :decidim_results_results - # rubocop:disable Rails/SkipsModelValidations OldResult.find_each do |old_result| Result.create!( id: old_result.id, @@ -51,5 +50,4 @@ def up drop_table :decidim_results_results end - # rubocop:enable Rails/SkipsModelValidations end diff --git a/db/migrate/20180709170619_rename_missing_features_to_components.decidim.rb b/db/migrate/20180709170619_rename_missing_features_to_components.decidim.rb index b75130113a..8e390b6cd7 100644 --- a/db/migrate/20180709170619_rename_missing_features_to_components.decidim.rb +++ b/db/migrate/20180709170619_rename_missing_features_to_components.decidim.rb @@ -8,10 +8,8 @@ class Notification < ApplicationRecord end def up - # rubocop:disable Rails/SkipsModelValidations Notification.where(decidim_resource_type: "Decidim::Feature").update_all(decidim_resource_type: "Decidim::Component") Notification.where(event_class: "Decidim::FeaturePublishedEvent").update_all(event_class: "Decidim::ComponentPublishedEvent") Notification.where(event_name: "decidim.events.features.feature_published").update_all(event_name: "decidim.events.components.component_published") - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20181012230419_fix_result_follows.decidim.rb b/db/migrate/20181012230419_fix_result_follows.decidim.rb index d323fdac3f..f5f03e082c 100644 --- a/db/migrate/20181012230419_fix_result_follows.decidim.rb +++ b/db/migrate/20181012230419_fix_result_follows.decidim.rb @@ -4,8 +4,6 @@ class FixResultFollows < ActiveRecord::Migration[5.2] def change - # rubocop:disable Rails/SkipsModelValidations Decidim::Follow.where(decidim_followable_type: "Decidim::Results::Result").update_all(decidim_followable_type: "Decidim::Accountability::Result") - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20181012230428_move_users_groups_to_users_table.decidim.rb b/db/migrate/20181012230428_move_users_groups_to_users_table.decidim.rb index 43945295f3..336609cb85 100644 --- a/db/migrate/20181012230428_move_users_groups_to_users_table.decidim.rb +++ b/db/migrate/20181012230428_move_users_groups_to_users_table.decidim.rb @@ -29,7 +29,6 @@ class Coauthorship < ApplicationRecord self.table_name = "decidim_coauthorships" end - # rubocop:disable Rails/SkipsModelValidations def change add_column :decidim_users, :type, :string User.update_all(type: "Decidim::User") @@ -82,5 +81,4 @@ def change drop_table :decidim_user_groups end - # rubocop:enable Rails/SkipsModelValidations end diff --git a/db/migrate/20181012230433_fix_user_groups_ids_in_comments.decidim_comments.rb b/db/migrate/20181012230433_fix_user_groups_ids_in_comments.decidim_comments.rb index ef75a39580..6c945c2dfb 100644 --- a/db/migrate/20181012230433_fix_user_groups_ids_in_comments.decidim_comments.rb +++ b/db/migrate/20181012230433_fix_user_groups_ids_in_comments.decidim_comments.rb @@ -3,7 +3,6 @@ # This migration comes from decidim_comments (originally 20181003080320) class FixUserGroupsIdsInComments < ActiveRecord::Migration[5.2] - # rubocop:disable Rails/SkipsModelValidations def change Decidim::UserGroup.find_each do |group| old_id = group.extended_data["old_user_group_id"] @@ -14,5 +13,4 @@ def change .update_all(decidim_user_group_id: group.id) end end - # rubocop:enable Rails/SkipsModelValidations end diff --git a/db/migrate/20181012230445_fix_user_groups_ids_in_proposals_endorsements.decidim_proposals.rb b/db/migrate/20181012230445_fix_user_groups_ids_in_proposals_endorsements.decidim_proposals.rb index 5ea034f7fb..e45de0793c 100644 --- a/db/migrate/20181012230445_fix_user_groups_ids_in_proposals_endorsements.decidim_proposals.rb +++ b/db/migrate/20181012230445_fix_user_groups_ids_in_proposals_endorsements.decidim_proposals.rb @@ -3,7 +3,6 @@ # This migration comes from decidim_proposals (originally 20181003074440) class FixUserGroupsIdsInProposalsEndorsements < ActiveRecord::Migration[5.2] - # rubocop:disable Rails/SkipsModelValidations def change Decidim::UserGroup.find_each do |group| old_id = group.extended_data["old_user_group_id"] @@ -14,5 +13,4 @@ def change .update_all(decidim_user_group_id: group.id) end end - # rubocop:enable Rails/SkipsModelValidations end diff --git a/db/migrate/20181012230446_fix_user_groups_ids_on_debates.decidim_debates.rb b/db/migrate/20181012230446_fix_user_groups_ids_on_debates.decidim_debates.rb index 231b7f1498..746d81d5bb 100644 --- a/db/migrate/20181012230446_fix_user_groups_ids_on_debates.decidim_debates.rb +++ b/db/migrate/20181012230446_fix_user_groups_ids_on_debates.decidim_debates.rb @@ -3,7 +3,6 @@ # This migration comes from decidim_debates (originally 20181003081235) class FixUserGroupsIdsOnDebates < ActiveRecord::Migration[5.2] - # rubocop:disable Rails/SkipsModelValidations def change Decidim::UserGroup.find_each do |group| old_id = group.extended_data["old_user_group_id"] @@ -14,5 +13,4 @@ def change .update_all(decidim_user_group_id: group.id) end end - # rubocop:enable Rails/SkipsModelValidations end diff --git a/db/migrate/20181220220346_add_columns_to_pages.decidim.rb b/db/migrate/20181220220346_add_columns_to_pages.decidim.rb index 0c27420671..7cb6bf8a3c 100644 --- a/db/migrate/20181220220346_add_columns_to_pages.decidim.rb +++ b/db/migrate/20181220220346_add_columns_to_pages.decidim.rb @@ -7,7 +7,6 @@ class StaticPage < ApplicationRecord self.table_name = :decidim_static_pages end - # rubocop:disable Rails/SkipsModelValidations def change change_table :decidim_static_pages do |t| t.column :weight, :integer, default: nil, null: true @@ -17,6 +16,5 @@ def change Decidim::StaticPage.where( slug: ["faq", "terms-and-conditions", "accessibility"] ).update_all(show_in_footer: true) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20181220220348_add_timestamps_to_components.decidim.rb b/db/migrate/20181220220348_add_timestamps_to_components.decidim.rb index bed70d9060..e14124fc45 100644 --- a/db/migrate/20181220220348_add_timestamps_to_components.decidim.rb +++ b/db/migrate/20181220220348_add_timestamps_to_components.decidim.rb @@ -5,9 +5,7 @@ class AddTimestampsToComponents < ActiveRecord::Migration[5.2] def change add_timestamps :decidim_components, null: true - # rubocop:disable Rails/SkipsModelValidations Decidim::Component.update_all(created_at: Time.current, updated_at: Time.current) - # rubocop:enable Rails/SkipsModelValidations change_column_null :decidim_components, :created_at, false change_column_null :decidim_components, :updated_at, false end diff --git a/db/migrate/20181220220349_fix_user_follows.decidim.rb b/db/migrate/20181220220349_fix_user_follows.decidim.rb index b311754e9a..dbfa420353 100644 --- a/db/migrate/20181220220349_fix_user_follows.decidim.rb +++ b/db/migrate/20181220220349_fix_user_follows.decidim.rb @@ -11,10 +11,8 @@ class Follow < ApplicationRecord end def change - # rubocop:disable Rails/SkipsModelValidations Follow.where( decidim_followable_type: "Decidim::User" ).update_all(decidim_followable_type: "Decidim::UserBaseEntity") - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20181220220356_add_id_documents_fields_to_org.decidim.rb b/db/migrate/20181220220356_add_id_documents_fields_to_org.decidim.rb index cd06f87fcc..8da3f03828 100644 --- a/db/migrate/20181220220356_add_id_documents_fields_to_org.decidim.rb +++ b/db/migrate/20181220220356_add_id_documents_fields_to_org.decidim.rb @@ -7,9 +7,7 @@ def change add_column :decidim_organizations, :id_documents_methods, :string, array: true, default: ["online"] add_column :decidim_organizations, :id_documents_explanation_text, :jsonb, default: {} - # rubocop:disable Rails/SkipsModelValidations Decidim::Organization.reset_column_information Decidim::Organization.update_all(id_documents_methods: ["online"]) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20181220220360_add_notification_types_to_users.decidim.rb b/db/migrate/20181220220360_add_notification_types_to_users.decidim.rb index d855d69949..576c555a57 100644 --- a/db/migrate/20181220220360_add_notification_types_to_users.decidim.rb +++ b/db/migrate/20181220220360_add_notification_types_to_users.decidim.rb @@ -5,10 +5,7 @@ class AddNotificationTypesToUsers < ActiveRecord::Migration[5.2] def change add_column :decidim_users, :notification_types, :string, default: "all" - # rubocop:disable Rails/SkipsModelValidations Decidim::UserBaseEntity.update_all(notification_types: "all") - # rubocop:enable Rails/SkipsModelValidations - change_column_null :decidim_users, :notification_types, false end end diff --git a/db/migrate/20190717132653_fix_user_names.decidim.rb b/db/migrate/20190717132653_fix_user_names.decidim.rb index bac685a36c..04c23e1343 100644 --- a/db/migrate/20190717132653_fix_user_names.decidim.rb +++ b/db/migrate/20190717132653_fix_user_names.decidim.rb @@ -18,9 +18,7 @@ def change entity.name = entity.name.delete(characters_to_remove).strip sanitized_nickname = entity.nickname.delete(characters_to_remove).strip - # rubocop:disable Rails/SkipsModelValidations entity.update_columns(nickname: Decidim::UserBaseEntity.nicknamize(sanitized_nickname, organization: entity.organization)) - # rubocop:enable Rails/SkipsModelValidations end end end diff --git a/db/migrate/20200923121725_add_direct_message_types_to_users.decidim.rb b/db/migrate/20200923121725_add_direct_message_types_to_users.decidim.rb index c60c6417d4..202af3574e 100644 --- a/db/migrate/20200923121725_add_direct_message_types_to_users.decidim.rb +++ b/db/migrate/20200923121725_add_direct_message_types_to_users.decidim.rb @@ -5,10 +5,7 @@ class AddDirectMessageTypesToUsers < ActiveRecord::Migration[5.2] def change add_column :decidim_users, :direct_message_types, :string, default: "all" - # rubocop:disable Rails/SkipsModelValidations Decidim::UserBaseEntity.update_all(direct_message_types: "all") - # rubocop:enable Rails/SkipsModelValidations - change_column_null :decidim_users, :direct_message_types, false end end diff --git a/db/migrate/20201126165604_add_machine_translation_display_priority_to_organizations.decidim.rb b/db/migrate/20201126165604_add_machine_translation_display_priority_to_organizations.decidim.rb index 95d360c325..bd78a61579 100644 --- a/db/migrate/20201126165604_add_machine_translation_display_priority_to_organizations.decidim.rb +++ b/db/migrate/20201126165604_add_machine_translation_display_priority_to_organizations.decidim.rb @@ -11,7 +11,7 @@ def change add_column :decidim_organizations, :machine_translation_display_priority, :string Organization.reset_column_information - Organization.update_all(machine_translation_display_priority: :original) # rubocop:disable Rails/SkipsModelValidations + Organization.update_all(machine_translation_display_priority: :original) change_column_default :decidim_organizations, :machine_translation_display_priority, "original" change_column_null :decidim_organizations, :machine_translation_display_priority, false diff --git a/db/migrate/20201126165622_move_budgets_to_own_model.decidim_budgets.rb b/db/migrate/20201126165622_move_budgets_to_own_model.decidim_budgets.rb index be0e1e1e58..a718197c66 100644 --- a/db/migrate/20201126165622_move_budgets_to_own_model.decidim_budgets.rb +++ b/db/migrate/20201126165622_move_budgets_to_own_model.decidim_budgets.rb @@ -67,17 +67,13 @@ def create_budget_resource_from(component) end def add_budget_references_to_projects(resource) - # rubocop:disable Rails/SkipsModelValidations Project.where(decidim_component_id: resource.decidim_component_id) .update_all(decidim_budgets_budget_id: resource.id) - # rubocop:enable Rails/SkipsModelValidations end def add_budget_reference_to_orders(resource) - # rubocop:disable Rails/SkipsModelValidations Order.where(decidim_component_id: resource.decidim_component_id) .update_all(decidim_budgets_budget_id: resource.id) - # rubocop:enable Rails/SkipsModelValidations end # down methods @@ -96,16 +92,12 @@ def revert_budget_to_component(resource) end def add_component_reference_to_orders(resource) - # rubocop:disable Rails/SkipsModelValidations Order.where(decidim_budgets_budget_id: resource.id) .update_all(decidim_component_id: resource.decidim_component_id) - # rubocop:enable Rails/SkipsModelValidations end def add_component_reference_to_projects(resource) - # rubocop:disable Rails/SkipsModelValidations Project.where(decidim_budgets_budget_id: resource.id) .update_all(decidim_component_id: resource.decidim_component_id) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20201126165632_add_commentable_counter_cache_to_debates.decidim_debates.rb b/db/migrate/20201126165632_add_commentable_counter_cache_to_debates.decidim_debates.rb index 160742df45..0ac0d4c427 100644 --- a/db/migrate/20201126165632_add_commentable_counter_cache_to_debates.decidim_debates.rb +++ b/db/migrate/20201126165632_add_commentable_counter_cache_to_debates.decidim_debates.rb @@ -7,10 +7,8 @@ def change add_column :decidim_debates_debates, :comments_count, :integer, null: false, default: 0, index: true Decidim::Debates::Debate.reset_column_information - # rubocop:disable Rails/SkipsModelValidations Decidim::Debates::Debate.includes(:comments).find_each do |debate| debate.update_columns(comments_count: debate.comments.not_hidden.count) end - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20201126165633_add_cached_comment_metadata_to_debates.decidim_debates.rb b/db/migrate/20201126165633_add_cached_comment_metadata_to_debates.decidim_debates.rb index b2c3a13967..0aa01f85a4 100644 --- a/db/migrate/20201126165633_add_cached_comment_metadata_to_debates.decidim_debates.rb +++ b/db/migrate/20201126165633_add_cached_comment_metadata_to_debates.decidim_debates.rb @@ -8,7 +8,6 @@ def change add_column :decidim_debates_debates, :last_comment_by_id, :integer add_column :decidim_debates_debates, :last_comment_by_type, :string - # rubocop:disable Rails/SkipsModelValidations Decidim::Debates::Debate.reset_column_information Decidim::Debates::Debate.includes(comments: [:author, :user_group]).find_each do |debate| last_comment = debate.comments.order("created_at DESC").first @@ -20,6 +19,5 @@ def change last_comment_by_type: last_comment.decidim_author_type ) end - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20201126165639_fix_attachments_titles.decidim_participatory_processes.rb b/db/migrate/20201126165639_fix_attachments_titles.decidim_participatory_processes.rb index f606f02d5c..3250b93b95 100644 --- a/db/migrate/20201126165639_fix_attachments_titles.decidim_participatory_processes.rb +++ b/db/migrate/20201126165639_fix_attachments_titles.decidim_participatory_processes.rb @@ -16,7 +16,6 @@ def up attached_to.try(:organization).try(:default_locale).presence || Decidim.default_locale - # rubocop:disable Rails/SkipsModelValidations attachment.update_columns( title: { locale => attachment.title @@ -25,7 +24,6 @@ def up locale => attachment.description } ) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20201126165641_move_proposals_fields_to_i18n.decidim_proposals.rb b/db/migrate/20201126165641_move_proposals_fields_to_i18n.decidim_proposals.rb index c897329380..38f6b5b45d 100644 --- a/db/migrate/20201126165641_move_proposals_fields_to_i18n.decidim_proposals.rb +++ b/db/migrate/20201126165641_move_proposals_fields_to_i18n.decidim_proposals.rb @@ -28,10 +28,8 @@ def up locale => proposal.body } - # rubocop:disable Rails/SkipsModelValidations proposal.update_column("new_title", proposal.new_title) proposal.update_column("new_body", proposal.new_body) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20210521003332_encrypt_authorization_metadatas.decidim.rb b/db/migrate/20210521003332_encrypt_authorization_metadatas.decidim.rb index c01ea659c6..2d70f2743b 100644 --- a/db/migrate/20210521003332_encrypt_authorization_metadatas.decidim.rb +++ b/db/migrate/20210521003332_encrypt_authorization_metadatas.decidim.rb @@ -16,12 +16,10 @@ def up def down Decidim::Authorization.all.each do |auth| - # rubocop:disable Rails/SkipsModelValidations auth.update_columns( metadata: decrypt_hash(auth.metadata), verification_metadata: decrypt_hash(auth.verification_metadata) ) - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/db/migrate/20210521003333_add_allow_public_access_to_static_pages.decidim.rb b/db/migrate/20210521003333_add_allow_public_access_to_static_pages.decidim.rb index b0d7ba19cf..8e69c41ed6 100644 --- a/db/migrate/20210521003333_add_allow_public_access_to_static_pages.decidim.rb +++ b/db/migrate/20210521003333_add_allow_public_access_to_static_pages.decidim.rb @@ -8,11 +8,9 @@ def change reversible do |direction| direction.up do - # rubocop:disable Rails/SkipsModelValidations Decidim::StaticPage.where(slug: "terms-and-conditions").update_all( allow_public_access: true ) - # rubocop:enable Rails/SkipsModelValidations end end end diff --git a/db/migrate/20210521003342_rename_name_column_to_title_in_decidim_participatory_process_groups.decidim_participatory_processes.rb b/db/migrate/20210521003342_rename_name_column_to_title_in_decidim_participatory_process_groups.decidim_participatory_processes.rb index a4f1e8ca26..6ee78972e4 100644 --- a/db/migrate/20210521003342_rename_name_column_to_title_in_decidim_participatory_process_groups.decidim_participatory_processes.rb +++ b/db/migrate/20210521003342_rename_name_column_to_title_in_decidim_participatory_process_groups.decidim_participatory_processes.rb @@ -6,35 +6,25 @@ class RenameNameColumnToTitleInDecidimParticipatoryProcessGroups < ActiveRecord: def up rename_column :decidim_participatory_process_groups, :name, :title PaperTrail::Version.where(item_type: "Decidim::ParticipatoryProcessGroup").each do |version| - # rubocop:disable Rails/SkipsModelValidations version.update_attribute(:object_changes, version.object_changes.gsub(/^name:/, "title:")) if version.object_changes.present? - # rubocop:enable Rails/SkipsModelValidations - next unless version.object.present? && version.object.has_key?("name") object = version.object object["title"] = object.delete("name") - # rubocop:disable Rails/SkipsModelValidations version.update_attribute(:object, object) - # rubocop:enable Rails/SkipsModelValidations end end def down PaperTrail::Version.where(item_type: "Decidim::ParticipatoryProcessGroup").each do |version| - # rubocop:disable Rails/SkipsModelValidations version.update_attribute(:object_changes, version.object_changes.gsub(/^title:/, "name:")) if version.object_changes.present? - # rubocop:enable Rails/SkipsModelValidations - next unless version.object.present? && version.object.has_key?("title") object = version.object object["name"] = object.delete("title") - # rubocop:disable Rails/SkipsModelValidations version.update_attribute(:object, object) - # rubocop:enable Rails/SkipsModelValidations end rename_column :decidim_participatory_process_groups, :title, :name end diff --git a/db/migrate/20211116164534_add_external_domain_whitelist_to_organization.decidim.rb b/db/migrate/20211116164534_add_external_domain_whitelist_to_organization.decidim.rb index caf1d841d9..ec166ce83f 100644 --- a/db/migrate/20211116164534_add_external_domain_whitelist_to_organization.decidim.rb +++ b/db/migrate/20211116164534_add_external_domain_whitelist_to_organization.decidim.rb @@ -8,9 +8,7 @@ def change reversible do |direction| direction.up do - # rubocop:disable Rails/SkipsModelValidations Decidim::Organization.update_all("external_domain_whitelist = ARRAY['decidim.org', 'github.com']") - # rubocop:enable Rails/SkipsModelValidations end end end diff --git a/db/migrate/20220512134631_rename_upcoming_events_content_block_to_upcoming_meetings.decidim_meetings.rb b/db/migrate/20220512134631_rename_upcoming_events_content_block_to_upcoming_meetings.decidim_meetings.rb index 47655d6f4c..a78e7975c5 100644 --- a/db/migrate/20220512134631_rename_upcoming_events_content_block_to_upcoming_meetings.decidim_meetings.rb +++ b/db/migrate/20220512134631_rename_upcoming_events_content_block_to_upcoming_meetings.decidim_meetings.rb @@ -8,8 +8,6 @@ class ContentBlock < ApplicationRecord end def change - # rubocop:disable Rails/SkipsModelValidations ContentBlock.where(manifest_name: "upcoming_events").update_all(manifest_name: "upcoming_meetings") - # rubocop:enable Rails/SkipsModelValidations end end diff --git a/docker-compose.yml b/docker-compose.yml index 322a3ef190..22c7660d6a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,7 @@ services: - DECIDIM_HOST=0.0.0.0 - REDIS_URL=redis://redis:6379 - MEMCACHE_SERVERS=memcached:11211 + - RAILS_SERVE_STATIC_FILES=true ports: - 3000:3000 depends_on: diff --git a/lib/active_storage/migrator.rb b/lib/active_storage/migrator.rb index 57338158d3..358ce55a5a 100644 --- a/lib/active_storage/migrator.rb +++ b/lib/active_storage/migrator.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "logger_with_stdout" +require "parallel" # inspired from https://www.stefanwienert.de/blog/2018/11/05/active-storage-migrate-between-providers-from-local-to-amazon/ module ActiveStorage @@ -19,14 +20,14 @@ def migrate! ActiveStorage::Blob.service = @source_service @logger.info "#{ActiveStorage::Blob.count} Blobs to go..." - ActiveStorage::Blob.find_each do |blob| + ::Parallel.each(ActiveStorage::Blob.all, in_processes: 10) do |blob| @logger.info "migrating blob #{blob.key}" blob.open do |tf| checksum = blob.checksum @destination_service.upload(blob.key, tf, checksum: checksum) end - rescue ActiveStorage::FileNotFoundError - @logger.error "FileNotFoundError #{blob.key}" + rescue ActiveStorage::FileNotFoundError, ActiveStorage::IntegrityError => e + @logger.error "#{e} #{blob.key}" next end end diff --git a/lib/decidim_app/k8s/organization_exporter.rb b/lib/decidim_app/k8s/organization_exporter.rb index f9ad5fd703..ee09fe6fd5 100644 --- a/lib/decidim_app/k8s/organization_exporter.rb +++ b/lib/decidim_app/k8s/organization_exporter.rb @@ -39,7 +39,7 @@ def initialize(organization, logger, export_path, image = "") @logger = logger @export_path = export_path @image = image - @database_name = Rails.configuration.database_configuration[Rails.env]["database"] + @database_configuration = Rails.configuration.database_configuration[Rails.env].deep_symbolize_keys end def self.export!(organization, logger, export_path, image) @@ -57,8 +57,17 @@ def export! end def dumping_database - @logger.info("dumping database #{@database_name} to #{organization_export_path}/postgres/#{resource_name}--de.dump") - system("pg_dump -Fc #{@database_name} > #{organization_export_path}/postgres/#{resource_name}--de.dump") + @logger.info("dumping database #{@database_configuration[:database]} to #{organization_export_path}/postgres/#{resource_name}--de.dump") + + cmd = "pg_dump -Fc" + cmd += " -h '#{@database_configuration[:host]}'" if @database_configuration[:host].present? + cmd += " -p '#{@database_configuration[:port]}'" if @database_configuration[:port].present? + cmd += " -U '#{@database_configuration[:username]}'" if @database_configuration[:username].present? + cmd = "PGPASSWORD=#{@database_configuration[:password]} #{cmd}" if @database_configuration[:password].present? + cmd += " -d '#{@database_configuration[:database]}'" if @database_configuration[:database].present? + cmd += " -f #{organization_export_path}/postgres/#{resource_name}--de.dump" + + system(cmd) end def exporting_configuration diff --git a/lib/initializers/sentry_setup.rb b/lib/decidim_app/sentry_setup.rb similarity index 96% rename from lib/initializers/sentry_setup.rb rename to lib/decidim_app/sentry_setup.rb index a5f4537653..0ed728c8be 100644 --- a/lib/initializers/sentry_setup.rb +++ b/lib/decidim_app/sentry_setup.rb @@ -2,6 +2,7 @@ require "sentry-ruby" require "json" +require "decidim_app/sentry_setup" module SentrySetup class << self diff --git a/lib/tasks/repair_data.rake b/lib/tasks/repair_data.rake index b6f2637299..af929e3d91 100644 --- a/lib/tasks/repair_data.rake +++ b/lib/tasks/repair_data.rake @@ -18,5 +18,22 @@ namespace :decidim do logger.info("Operation terminated") end + + desc "Check for malformed comments body and repair them if needed" + task comments: :environment do + logger = Logger.new($stdout) + logger.info("Checking all comments...") + + updated_comments_ids = Decidim::RepairCommentsService.run + + if updated_comments_ids.blank? + logger.info("No comments updated") + else + logger.info("#{updated_comments_ids} comments updated") + logger.info("Updated comments ID : #{updated_comments_ids.join(",")}") + end + + logger.info("Operation terminated") + end end end diff --git a/spec/lib/active_storage/migrator_spec.rb b/spec/lib/active_storage/migrator_spec.rb index fe1d7a352f..5815cda92c 100644 --- a/spec/lib/active_storage/migrator_spec.rb +++ b/spec/lib/active_storage/migrator_spec.rb @@ -67,7 +67,7 @@ let(:blob) { ActiveStorage::Blob.create_and_upload!(io: File.open(Rails.root.join("spec/test_assets/logo_asset.png")), filename: "logo_asset.png") } before do - allow(ActiveStorage::Blob).to receive(:find_each).and_yield(blob) + allow(::Parallel).to receive(:each).with(ActiveStorage::Blob.all, in_processes: 10).and_yield(blob) end it "migrates the blobs" do @@ -83,7 +83,19 @@ end it "logs the error" do - expect(subject.instance_variable_get(:@logger)).to receive(:error).with("FileNotFoundError #{blob.key}") + expect(subject.instance_variable_get(:@logger)).to receive(:error).with("ActiveStorage::FileNotFoundError #{blob.key}") + + subject.migrate! + end + end + + context "when the blob doesn't have integrity" do + before do + allow(blob).to receive(:open).and_raise(ActiveStorage::IntegrityError) + end + + it "logs the error" do + expect(subject.instance_variable_get(:@logger)).to receive(:error).with("ActiveStorage::IntegrityError #{blob.key}") subject.migrate! end diff --git a/spec/lib/decidim_app/k8s/organization_exporter_spec.rb b/spec/lib/decidim_app/k8s/organization_exporter_spec.rb index c30522edef..e913b8ee4a 100644 --- a/spec/lib/decidim_app/k8s/organization_exporter_spec.rb +++ b/spec/lib/decidim_app/k8s/organization_exporter_spec.rb @@ -22,7 +22,7 @@ } end - let(:database_name) { Rails.configuration.database_configuration[Rails.env]["database"] } + let(:database_configuration) { Rails.configuration.database_configuration[Rails.env].deep_symbolize_keys } before do organization.update!(secondary_hosts: [organization_secondary_host]) @@ -53,7 +53,16 @@ describe "#dumping_database" do it "dumps the database" do # rubocop:disable RSpec/SubjectStub - expect(subject).to receive(:system).with("pg_dump -Fc #{database_name} > #{export_path}/#{name_space}--#{hostname}/postgres/#{hostname}--de.dump") + + cmd = "pg_dump -Fc" + cmd += " -h '#{database_configuration[:host]}'" if database_configuration[:host].present? + cmd += " -p '#{database_configuration[:port]}'" if database_configuration[:port].present? + cmd += " -U '#{database_configuration[:username]}'" if database_configuration[:username].present? + cmd = "PGPASSWORD=#{database_configuration[:password]} #{cmd}" if database_configuration[:password].present? + cmd += " -d '#{database_configuration[:database]}'" if database_configuration[:database].present? + cmd += " -f #{export_path}/#{name_space}--#{hostname}/postgres/#{hostname}--de.dump" + + expect(subject).to receive(:system).with(cmd) # rubocop:enable RSpec/SubjectStub subject.dumping_database end diff --git a/spec/lib/sentry_setup_spec.rb b/spec/lib/decidim_app/sentry_setup_spec.rb similarity index 100% rename from spec/lib/sentry_setup_spec.rb rename to spec/lib/decidim_app/sentry_setup_spec.rb diff --git a/spec/services/decidim/repair_comments_service_spec.rb b/spec/services/decidim/repair_comments_service_spec.rb new file mode 100644 index 0000000000..1c9da68d8a --- /dev/null +++ b/spec/services/decidim/repair_comments_service_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Decidim::RepairCommentsService do + subject { described_class.new } + + let!(:comments) { create_list(:comment, 10) } + + describe "#execute" do + it "returns empty array" do + expect(subject.execute).to be_empty + end + + it "does not change valid comments" do + expect { subject.execute }.not_to(change { comments.map(&:body) }) + end + + context "when invalid bodys" do + let(:invalid) { build :comment } + + before do + invalid.body = { "en" => { "en" => "foobar" } } + invalid.save!(validate: false) + end + + it "returns array of invalid comments IDs" do + expect(subject.execute).to eq([invalid.id]) + invalid.reload.body.delete("machine_translations") + expect(invalid.body).to eq({ "en" => "foobar" }) + end + end + end + + describe "#ok?" do + it "returns true" do + expect(subject).to be_ok + end + end + + describe "#invalid_comments" do + let(:invalid) { build :comment } + + before do + invalid.body = { "en" => { "en" => "foobar" } } + invalid.save!(validate: false) + end + + it "returns array of invalid comments" do + expect(subject.invalid_comments).to eq([[invalid, { "en" => "foobar" }]]) + end + end +end