Skip to content

Extract organiser grant/revoke diffing into WorkshopOrganiserAssigner service (#2941) - #3049

Open
davidmillen50 wants to merge 3 commits into
codebar:masterfrom
davidmillen50:2941-extract-organiser-grant-revoke-diffing-from-workshops-controller
Open

davidmillen50 wants to merge 3 commits into
codebar:masterfrom
davidmillen50:2941-extract-organiser-grant-revoke-diffing-from-workshops-controller

Conversation

@davidmillen50

@davidmillen50 davidmillen50 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

this refactor relates to issue 2941

Before: missing organiser_ids raised NoMethodError (nil.reject!) and left roles untouched.
After:

  • [] (empty array from form deselect) clears all current organisers (silent, intended)
  • nil (absent param) raises ArgumentError ('organiser_ids is required')
  • Spec added for absent-param case
  • Rubocop clean; controller specs fixed (false positives removed)

@davidmillen50
davidmillen50 force-pushed the 2941-extract-organiser-grant-revoke-diffing-from-workshops-controller branch 3 times, most recently from b897cc5 to 88a8cd0 Compare October 22, 2026 13:18

@mroderick mroderick left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One behaviour change on the update path and two assertion gaps in the new specs - details in the line comments.

The blocker for me is the absent-param handling in WorkshopOrganiserAssigner: nil on update now silently clears all organisers where it previously raised, and nil means chapter fallback on create but full revocation on update. The rest of the extraction looks faithful.

if @default_to_chapter && @organiser_ids.blank?
grant(@workshop.chapter.organisers.pluck(:id))
else
desired_ids = Array(@organiser_ids).reject(&:empty?).map(&:to_s)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the organisers param is absent, @organiser_ids is nil and Array(nil) gives [], so revoke_other_organisers([]) strips every current organiser and the update redirects with a success notice. Before this change the same request raised NoMethodError on nil.reject! and left the roles untouched. The edit form's multi-select omits the key entirely when nothing is selected, so deselecting all organisers and saving hits exactly this path.

Nil also means opposite things on the two routes now: chapter fallback on create (default_to_chapter: true), full strip on update.

If the old 500 was simply broken and a silent clear is the intended behaviour for #2941, could you note that in the PR description and add a spec for the absent-param case? If not, guarding the else branch reads like:

raise ArgumentError, 'organiser_ids is required on the update path' if @organiser_ids.nil?

or returning without revoking, so only a submitted list can clear the roster.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left the error as it was previously implemented

host: nil, organisers: [organiser.id.to_s]
}
}
end.not_to raise_error

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.not_to raise_error is the only assertion in both new create specs, so they stay green even if the grant never happens: a mistyped service call, or a wrong params key falling back to the chapter default, passes just the same. Could the provided-ids spec also assert the effect?

workshop.reload
expect(workshop.organisers).to include(organiser)

The PATCH #update spec below has real value assertions, so this is only about the two create cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should now be resolved

chapter_organiser.add_role(:organiser, chapter)
described_class.new(workshop, [], default_to_chapter: true).call
workshop.reload
expect(workshop.organisers).to include(chapter_organiser)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pins the chapter-fallback grant but not that the fallback is grant-only. If the branch ever picked up revocation (or the condition on line 9 drifted), pre-existing workshop organisers would lose their roles with this spec still green. Could it also assert a workshop-only organiser keeps the role?

existing = Fabricate(:member)
existing.add_role(:organiser, workshop)
described_class.new(workshop, [], default_to_chapter: true).call
workshop.reload
expect(workshop.organisers).to include(existing)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should now be resolved

@davidmillen50
davidmillen50 force-pushed the 2941-extract-organiser-grant-revoke-diffing-from-workshops-controller branch from b2a2928 to faa1309 Compare October 25, 2026 13:40
@davidmillen50
davidmillen50 force-pushed the 2941-extract-organiser-grant-revoke-diffing-from-workshops-controller branch from faa1309 to 3a25aec Compare October 25, 2026 14:22

This branch has not been deployed

No deployments
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.

2 participants