Files
grecia/.rubocop.yml
Javi Martín a7e1b42b6c Use checkboxes and radio buttons on poll forms
Our original interface to vote in a poll had a few issues:

* Since there was no button to send the form, it wasn't clear that
  selecting an option would automatically store it in the database.
* The interface was almost identical for single-choice questions and
  multiple-choice questions, which made it hard to know which type of
  question we were answering.
* Adding other type of questions, like open answers, was hard since we
  would have to add a different submit button for each answer.

So we're now using radio buttons for single-choice questions and
checkboxes for multiple-choice questions, which are the native controls
designed for these purposes, and a button to send the whole form.

Since we don't have a database table for poll ballots like we have for
budget ballots, we're adding a new `Poll::WebVote` model to manage poll
ballots. We're using WebVote instead of Ballot or Vote because they
could be mistaken with other vote classes.

Note that browsers don't allow removing answers with radio buttons, so
once somebody has voted in a single-choice question, they can't remove
the vote unless they manually edit their HTML. This is the same behavior
we had before commit 7df0e9a96.

As mentioned in c2010f975, we're now adding the `ChangeByZero` rubocop
rule, since we've removed the test that used `and change`.
2025-08-14 13:06:37 +02:00

903 lines
14 KiB
YAML

require:
- rubocop-capybara
- rubocop-factory_bot
- rubocop-performance
- rubocop-rails
- rubocop-rspec
- rubocop-rspec_rails
AllCops:
DisplayCopNames: true
DisplayStyleGuide: true
Exclude:
- "db/schema.rb"
- "app/lib/ckeditor/backend/active_storage.rb"
- "config/initializers/disable_active_storage_pdf_auto_previews.rb"
- "vendor/**/*"
DisabledByDefault: true
Bundler/DuplicatedGem:
Enabled: true
Bundler/OrderedGems:
Enabled: true
ConsiderPunctuation: true
Capybara/ClickLinkOrButtonStyle:
Enabled: true
EnforcedStyle: strict
Capybara/CurrentPathExpectation:
Enabled: true
Capybara/NegationMatcher:
Enabled: true
EnforcedStyle: not_to
Capybara/RSpec/HaveSelector:
Enabled: true
Capybara/SpecificActions:
Enabled: true
Capybara/VisibilityMatcher:
Enabled: true
FactoryBot/AssociationStyle:
Enabled: true
FactoryBot/ConsistentParenthesesStyle:
Enabled: true
FactoryBot/FactoryAssociationWithStrategy:
Enabled: true
FactoryBot/FactoryClassName:
Enabled: true
FactoryBot/RedundantFactoryOption:
Enabled: true
Layout/ArgumentAlignment:
Enabled: true
Layout/ArrayAlignment:
Enabled: true
Layout/AssignmentIndentation:
Enabled: true
Layout/BeginEndAlignment:
Enabled: true
EnforcedStyleAlignWith: begin
Layout/BlockAlignment:
Enabled: true
Layout/BlockEndNewline:
Enabled: true
Layout/ClosingHeredocIndentation:
Enabled: true
Layout/ClosingParenthesisIndentation:
Enabled: true
Layout/DefEndAlignment:
Enabled: true
EnforcedStyleAlignWith: def
Layout/DotPosition:
Enabled: true
Layout/ElseAlignment:
Enabled: true
Layout/EmptyLineAfterGuardClause:
Enabled: true
Layout/EmptyLineBetweenDefs:
Enabled: true
Layout/EmptyLines:
Enabled: true
Layout/EmptyLinesAroundAccessModifier:
Enabled: true
Layout/EmptyLinesAroundBlockBody:
Enabled: true
Layout/EmptyLinesAroundClassBody:
Enabled: true
Layout/EmptyLinesAroundMethodBody:
Enabled: true
Layout/EmptyLinesAroundModuleBody:
Enabled: true
Layout/EndAlignment:
Enabled: true
Layout/EndOfLine:
EnforcedStyle: lf
Layout/ExtraSpacing:
Enabled: true
Layout/FirstArrayElementIndentation:
Enabled: true
EnforcedStyle: consistent
Layout/FirstHashElementIndentation:
Enabled: true
EnforcedStyle: consistent
Layout/HashAlignment:
Enabled: true
Layout/HeredocIndentation:
Enabled: true
Layout/IndentationConsistency:
EnforcedStyle: indented_internal_methods
Layout/IndentationStyle:
Enabled: true
Layout/IndentationWidth:
Enabled: true
Layout/LeadingEmptyLines:
Enabled: true
Layout/LineContinuationSpacing:
Enabled: true
Layout/LineEndStringConcatenationIndentation:
Enabled: true
Layout/LineLength:
Max: 110
Exclude:
- "Gemfile"
- "config/environments/production.rb"
- "config/environments/staging.rb"
- "config/initializers/devise.rb"
- "config/initializers/backtrace_silencers.rb"
- "db/migrate/*create_delayed_jobs.rb"
- "db/migrate/*create_active_storage_variant_records.active_storage.rb"
- "app/models/budget/stats.rb"
Layout/MultilineArrayBraceLayout:
Enabled: true
Layout/MultilineBlockLayout:
Enabled: true
Layout/MultilineHashBraceLayout:
Enabled: true
Layout/MultilineHashKeyLineBreaks:
Enabled: true
Layout/MultilineMethodCallBraceLayout:
Enabled: true
Layout/MultilineMethodCallIndentation:
Enabled: true
Exclude:
- "config/environments/production.rb"
Layout/MultilineOperationIndentation:
Enabled: true
Layout/ParameterAlignment:
Enabled: true
Layout/RescueEnsureAlignment:
Enabled: true
Layout/SpaceAfterColon:
Enabled: true
Layout/SpaceAfterComma:
Enabled: true
Layout/SpaceAfterMethodName:
Enabled: true
Layout/SpaceAfterNot:
Enabled: true
Layout/SpaceAfterSemicolon:
Enabled: true
Layout/SpaceAroundBlockParameters:
Enabled: true
Layout/SpaceAroundEqualsInParameterDefault:
Enabled: true
Layout/SpaceAroundMethodCallOperator:
Enabled: true
Layout/SpaceAroundOperators:
Enabled: true
Layout/SpaceBeforeBlockBraces:
Enabled: true
Layout/SpaceBeforeComma:
Enabled: true
Layout/SpaceBeforeComment:
Enabled: true
Layout/SpaceBeforeFirstArg:
Enabled: true
Layout/SpaceBeforeSemicolon:
Enabled: true
Layout/SpaceInLambdaLiteral:
Enabled: true
Layout/SpaceInsideArrayLiteralBrackets:
Enabled: true
Layout/SpaceInsideArrayPercentLiteral:
Enabled: true
Layout/SpaceInsideBlockBraces:
Enabled: true
Layout/SpaceInsideHashLiteralBraces:
Enabled: true
EnforcedStyle: compact
Layout/SpaceInsideParens:
Enabled: true
Layout/SpaceInsidePercentLiteralDelimiters:
Enabled: true
Layout/SpaceInsideRangeLiteral:
Enabled: true
Layout/SpaceInsideReferenceBrackets:
Enabled: true
Layout/SpaceInsideStringInterpolation:
Enabled: true
Layout/TrailingEmptyLines:
Enabled: true
Layout/TrailingWhitespace:
Enabled: true
Lint/AmbiguousRegexpLiteral:
Enabled: true
Lint/BooleanSymbol:
Enabled: true
Lint/ConstantDefinitionInBlock:
Enabled: true
Lint/ConstantReassignment:
Enabled: true
Lint/DeprecatedClassMethods:
Enabled: true
Lint/DuplicateBranch:
Enabled: true
Lint/DuplicateMethods:
Enabled: true
Lint/EmptyBlock:
Enabled: true
Lint/EmptyFile:
Enabled: true
Lint/HashNewWithKeywordArgumentsAsDefault:
Enabled: true
Lint/LiteralAsCondition:
Enabled: true
Lint/NonAtomicFileOperation:
Enabled: true
Lint/ParenthesesAsGroupedExpression:
Enabled: true
Lint/RedundantSafeNavigation:
Enabled: true
Lint/RedundantStringCoercion:
Enabled: true
Lint/SafeNavigationChain:
Enabled: true
Lint/ShadowingOuterLocalVariable:
Enabled: true
Lint/SharedMutableDefault:
Enabled: true
Lint/SymbolConversion:
Enabled: true
Exclude:
- "app/models/setting.rb"
- "db/dev_seeds/settings.rb"
Lint/UselessAssignment:
Enabled: true
Lint/UselessDefined:
Enabled: true
Lint/Void:
Enabled: true
Naming/BlockForwarding:
Enabled: true
Exclude:
- "app/controllers/application_controller.rb"
- "app/controllers/management/base_controller.rb"
- "app/controllers/subscriptions_controller.rb"
Naming/PredicateMethod:
Enabled: true
Exclude:
- "app/models/local_census_records/import.rb"
- "app/models/user.rb"
- "app/models/verification/management/email.rb"
- "config/initializers/foundation_form_builder.rb"
Naming/RescuedExceptionsVariableName:
Enabled: true
Naming/VariableName:
Enabled: true
Performance/BlockGivenWithExplicitBlock:
Enabled: true
Performance/CompareWithBlock:
Enabled: true
Performance/DoubleStartEndWith:
Enabled: true
Performance/EndWith:
Enabled: true
Performance/StartWith:
Enabled: true
Performance/Sum:
Enabled: true
Rails/ActionControllerFlashBeforeRender:
Enabled: true
Rails/ActiveRecordCallbacksOrder:
Enabled: true
Rails/AddColumnIndex:
Enabled: true
Rails/CompactBlank:
Enabled: true
Rails/CreateTableWithTimestamps:
Enabled: true
Exclude:
- "db/migrate/201[5-8]*"
- "db/migrate/*install_audited.rb"
- "db/migrate/*create_active_storage_variant_records.active_storage.rb"
Rails/Date:
Enabled: true
Rails/DurationArithmetic:
Enabled: true
Rails/DynamicFindBy:
Enabled: true
Whitelist:
- find_by_domain
- find_by_slug_or_id
- find_by_slug_or_id!
- find_by_manager_login
Rails/EnumHash:
Enabled: true
Rails/EnumSyntax:
Enabled: true
Rails/EnumUniqueness:
Enabled: true
Rails/EnvironmentComparison:
Enabled: true
Rails/FindBy:
Enabled: true
Include:
- "**/*.rb"
Exclude:
- "config/initializers/ahoy.rb"
Rails/FindEach:
Enabled: true
Rails/HasAndBelongsToMany:
Enabled: true
Rails/HasManyOrHasOneDependent:
Enabled: true
Severity: refactor
Rails/HttpStatus:
Enabled: true
Rails/I18nLocaleAssignment:
Enabled: true
Include:
- "**/*.rb"
Rails/InverseOf:
Enabled: true
Exclude:
- "app/models/related_content.rb"
Rails/NotNullColumn:
Enabled: true
Exclude:
- "db/migrate/201[5-7]*"
Rails/OutputSafety:
Enabled: true
Severity: warning
Exclude:
- app/helpers/text_with_links_helper.rb
Rails/Pick:
Enabled: true
Rails/PluckId:
Enabled: true
Rails/PluralizationGrammar:
Enabled: true
Rails/Presence:
Enabled: true
Rails/RedundantActiveRecordAllMethod:
Enabled: true
Rails/RedundantTravelBack:
Enabled: true
Rails/RelativeDateConstant:
Enabled: true
Rails/RequestReferer:
Enabled: true
Rails/ResponseParsedBody:
Enabled: true
Rails/ReversibleMigration:
Enabled: true
Rails/SafeNavigation:
Enabled: true
ConvertTry: true
Rails/SaveBang:
Enabled: true
Severity: refactor
Rails/SelectMap:
Enabled: true
Rails/SkipsModelValidations:
Enabled: true
ForbiddenMethods:
- update_attribute
Exclude:
- app/models/tenant.rb
- app/lib/acts_as_paranoid_aliases.rb
Rails/TimeZone:
Enabled: true
Rails/UniqBeforePluck:
Enabled: true
Rails/UniqueValidationWithoutIndex:
Enabled: true
Severity: refactor
Rails/UnknownEnv:
Enabled: true
Environments:
- development
- test
- production
- preproduction
- staging
Rails/Validation:
Enabled: true
Rails/WhereEquals:
Enabled: true
Rails/WhereMissing:
Enabled: true
Rails/WhereNot:
Enabled: true
Rails/WhereNotWithMultipleConditions:
Enabled: true
Rails/WhereRange:
Enabled: true
RSpec/AroundBlock:
Enabled: true
RSpec/BeEq:
Enabled: true
RSpec/BeforeAfterAll:
Enabled: true
RSpec/BeNil:
Enabled: true
EnforcedStyle: be
RSpec/ChangeByZero:
Enabled: true
RSpec/ContextMethod:
Enabled: true
RSpec/DescribedClass:
Enabled: true
EnforcedStyle: explicit
RSpec/Dialect:
Enabled: true
PreferredMethods:
background: :before
given: :let
given!: :let!
feature: :describe
RSpec/EmptyExampleGroup:
Enabled: true
Exclude:
- spec/factories/**/*
RSpec/EmptyHook:
Enabled: true
RSpec/EmptyLineAfterExample:
Enabled: true
RSpec/EmptyLineAfterExampleGroup:
Enabled: true
Exclude:
- spec/factories/**/*
RSpec/EmptyOutput:
Enabled: true
RSpec/ExampleWording:
Enabled: true
RSpec/ExcessiveDocstringSpacing:
Enabled: true
RSpec/ExpectInLet:
Enabled: true
RSpec/Focus:
Enabled: true
RSpec/HookArgument:
Enabled: true
RSpec/InstanceVariable:
Enabled: true
Exclude:
- spec/controllers/concerns/has_orders_spec.rb
- spec/form_builders/translatable_form_builder_spec.rb
RSpec/LetBeforeExamples:
Enabled: true
RSpec/LetSetup:
Enabled: true
RSpec/MetadataStyle:
Enabled: true
RSpec/MissingExpectationTargetMethod:
Enabled: true
RSpec/NotToNot:
Enabled: true
RSpec/OverwritingSetup:
Enabled: true
RSpec/ReceiveMessages:
Enabled: true
RSpec/RepeatedExample:
Enabled: true
RSpec/RepeatedExampleGroupBody:
Enabled: true
RSpec/RepeatedExampleGroupDescription:
Enabled: true
RSpec/ScatteredLet:
Enabled: true
RSpec/ScatteredSetup:
Enabled: true
RSpec/SpecFilePathFormat:
Enabled: true
RSpec/SpecFilePathSuffix:
Enabled: true
RSpec/UndescriptiveLiteralsDescription:
Enabled: true
RSpec/VerifiedDoubleReference:
Enabled: true
RSpec/VoidExpect:
Enabled: true
RSpecRails/HaveHttpStatus:
Enabled: true
RSpecRails/InferredSpecType:
Enabled: true
RSpecRails/NegationBeValid:
Enabled: true
RSpecRails/TravelAround:
Enabled: true
Security/Eval:
Enabled: true
Security/JSONLoad:
Enabled: true
Security/Open:
Enabled: true
Security/YAMLLoad:
Enabled: true
Style/AccessorGrouping:
Enabled: true
Style/AndOr:
Enabled: true
Style/ArgumentsForwarding:
Enabled: true
Exclude:
- "bin/setup"
Style/ArrayCoercion:
Enabled: true
Style/ArrayIntersect:
Enabled: true
Style/BlockDelimiters:
Enabled: true
Style/CaseLikeIf:
Enabled: true
Style/ClassCheck:
Enabled: true
Style/ClassVars:
Enabled: true
Style/CollectionMethods:
Enabled: true
Style/ComparableBetween:
Enabled: true
Style/DigChain:
Enabled: true
Style/EmptyStringInsideInterpolation:
Enabled: true
Style/FileRead:
Enabled: true
Style/FileWrite:
Enabled: true
Style/HashConversion:
Enabled: true
Style/HashExcept:
Enabled: true
Style/HashSlice:
Enabled: true
Style/HashSyntax:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: true
Style/IdenticalConditionalBranches:
Enabled: true
Style/IfWithBooleanLiteralBranches:
Enabled: true
Style/InverseMethods:
Enabled: true
Style/InvertibleUnlessCondition:
Enabled: true
InverseMethods:
:blank?: :present?
:include?: ~
:present?: :blank?
:zero?: ~
Style/KeywordArgumentsMerging:
Enabled: true
Style/LineEndConcatenation:
Enabled: true
Style/MapIntoArray:
Enabled: true
Style/MapToHash:
Enabled: true
Style/MethodDefParentheses:
Enabled: true
Style/MinMaxComparison:
Enabled: true
Style/MutableConstant:
Enabled: true
Style/NegatedIfElseCondition:
Enabled: true
Style/Not:
Enabled: true
Style/OrAssignment:
Enabled: true
Style/PercentLiteralDelimiters:
Enabled: true
Style/Proc:
Enabled: true
Style/RaiseArgs:
Enabled: true
Style/RedundantArgument:
Enabled: true
Style/RedundantArrayFlatten:
Enabled: true
Style/RedundantBegin:
Enabled: true
Style/RedundantCondition:
Enabled: true
Style/RedundantFileExtensionInRequire:
Enabled: true
Style/RedundantFreeze:
Enabled: true
Style/RedundantInterpolation:
Enabled: true
Style/RedundantParentheses:
Enabled: true
Style/RedundantRegexpArgument:
Enabled: true
Style/RedundantRegexpCharacterClass:
Enabled: true
Style/RedundantReturn:
Enabled: true
Style/RedundantSelf:
Enabled: true
Style/RedundantStringEscape:
Enabled: true
Style/SafeNavigation:
Enabled: true
Style/SingleLineDoEndBlock:
Enabled: true
Style/SingleLineMethods:
Enabled: true
Style/SoleNestedConditional:
Enabled: true
Style/StringChars:
Enabled: true
Style/StringLiterals:
EnforcedStyle: double_quotes
Style/StringLiteralsInInterpolation:
EnforcedStyle: double_quotes
Style/SuperArguments:
Enabled: true
Exclude:
- "config/initializers/ahoy.rb"
Style/SymbolProc:
Enabled: true
AllowedMethods:
- respond_to
Style/TrailingCommaInArrayLiteral:
Enabled: true
Style/TrailingCommaInHashLiteral:
Enabled: true