Skip to content

Fix disallow enabling ParticipatoryText with existing proposals#5134

Merged
oriolgual merged 21 commits intodecidim:masterfrom
CodiTramuntana:fix/enabling_participatory_processes_with_exisitng_proposals
May 27, 2019
Merged

Fix disallow enabling ParticipatoryText with existing proposals#5134
oriolgual merged 21 commits intodecidim:masterfrom
CodiTramuntana:fix/enabling_participatory_processes_with_exisitng_proposals

Conversation

@aitorlb
Copy link
Copy Markdown
Contributor

@aitorlb aitorlb commented May 11, 2019

🎩 What? Why?

It shouldn't be possible to enable participatory_texts when there are existing proposals.

📌 Related Issues

📋 Subtasks

  • Add CHANGELOG entry
  • Add tests

📷 Screenshots (optional)

participatory_texts_enabled

@aitorlb aitorlb requested a review from a team as a code owner May 11, 2019 21:23
@oriolgual
Copy link
Copy Markdown
Contributor

Shouldn't we also add some kind of backend validation?

oriolgual
oriolgual previously approved these changes May 23, 2019
@aitorlb
Copy link
Copy Markdown
Contributor Author

aitorlb commented May 23, 2019

@oriolgual I'm having problems making the validation in:
decidim-proposals/lib/decidim/proposals/component.rb

It turns out that instance.reload does not work in this case to find out if participatory_text_enabled was different before the update:

instance.settings.participatory_texts_enabled == instance.reload.settings.participatory_texts_enabled

And the solutions I've come up are not compatible with the specs:

  • Reconnecting with the database
  component.on(:update) do |instance|
    Decidim::Component.connection.reconnect! # instance.reload is not enough to get the db's setting value
    db_setting_value = Decidim::Component.find(instance.id).settings.participatory_texts_enabled
    next if db_setting_value == instance.settings.participatory_texts_enabled
    raise "Can't update ParticipatoryText setting when there are proposals" if Decidim::Proposals::Proposal.where(component: instance).any?
  end
PG::NoActiveSqlTransaction: ERROR:  ROLLBACK TO SAVEPOINT can only be used in transaction blocks
       : ROLLBACK TO SAVEPOINT active_record_1
  • Using PaperTrail versions
  component.on(:update) do |instance|
    return unless (settings_changeset = instance.versions.last.changeset["settings"])
    before = settings_changeset.first["global"]["participatory_texts_enabled"]
    after = settings_changeset.last["global"]["participatory_texts_enabled"]
    raise "Can't update ParticipatoryText setting when there are proposals" if before != after && Decidim::Proposals::Proposal.where(component: instance).any?
  end
     Failure/Error: return unless (settings_changeset = instance.versions.last.changeset["settings"])
     
     NoMethodError:
       undefined method `changeset' for nil:NilClass

The second could be fixed by creating PaperTrail versions in the factories, but I don't know if it's a good choice as I would need to update many specs...

Would it be acceptable to move the validation for to the UpdateComponent command inside decidim-core?

@oriolgual
Copy link
Copy Markdown
Contributor

Would it be acceptable to move the validation for to the UpdateComponent command inside decidim-core?

Yes, that seems OK!

aitorlb added 3 commits May 25, 2019 22:50
…ntForm

No custom error message has been added after this validation fails because the
checkbox is already being disabled and a help text is being added on the frontend.
oriolgual
oriolgual previously approved these changes May 27, 2019
@oriolgual
Copy link
Copy Markdown
Contributor

Is everything finished here @aitorlb ?

@aitorlb
Copy link
Copy Markdown
Contributor Author

aitorlb commented May 27, 2019

@oriolgual I was just about to push a little refactor if that is okay with you:

      def must_be_able_to_change_participatory_texts_setting
        return unless settings[:participatory_texts_enabled] &.!= component.settings.participatory_texts_enabled

        errors.add(:settings) if Decidim::Proposals::Proposal.where(component: component).any?
      end

I just found out that you can use the &. operator with comparisons...

@oriolgual
Copy link
Copy Markdown
Contributor

@oriolgual I was just about to push a little refactor if that is okay with you:

      def must_be_able_to_change_participatory_texts_setting
        return unless settings[:participatory_texts_enabled] &.!= component.settings.participatory_texts_enabled

        errors.add(:settings) if Decidim::Proposals::Proposal.where(component: component).any?
      end

I just found out that you can use the &. operator with comparisons...

LOL, what does &. do when comparing?

@oriolgual
Copy link
Copy Markdown
Contributor

Oh, I guess it doesn't crash if settings is nil, nice!

@aitorlb
Copy link
Copy Markdown
Contributor Author

aitorlb commented May 27, 2019

It would be equivalent to the following:

settings[:participatory_texts_enabled] && settings[:participatory_texts_enabled] != component.settings.participatory_texts_enabled

It's just a little shorter, hehe...

@aitorlb
Copy link
Copy Markdown
Contributor Author

aitorlb commented May 27, 2019

Oh, I guess it doesn't crash if settings is nil, nice!

The problem is not that it crashes but that it gives a false positive:
if settings[:participatory_texts_enabled] returns nil, it gets compared to component.settings.participatory_texts_enabled. We DON'T want that.

@oriolgual oriolgual merged commit 0a65f98 into decidim:master May 27, 2019
@tramuntanal tramuntanal deleted the fix/enabling_participatory_processes_with_exisitng_proposals branch February 19, 2021 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Error visiting a proposal on a participatory text-enabled component

2 participants