Merge branch 'master' into admin-newsletter-emails

This commit is contained in:
María Checa
2018-02-14 16:07:13 +01:00
35 changed files with 559 additions and 897 deletions

View File

@@ -43,3 +43,10 @@ After executing rspec you can see the seed used, add it as an option to rspec, f
### Other things to watch for ### Other things to watch for
- Time related issues (current time, two time or date comparisons with miliseconds/time when its not needed) - Time related issues (current time, two time or date comparisons with miliseconds/time when its not needed)
- https://semaphoreci.com/community/tutorials/how-to-deal-with-and-eliminate-flaky-tests - https://semaphoreci.com/community/tutorials/how-to-deal-with-and-eliminate-flaky-tests
### Final thoughts
The true objective of this issue is not "to fix" a flaky spec, but to change a spec that randomly fails into one that we can trust when it passes (or fails).
That means you've to think "What are we testing here?" and "Can we test the same thing in another way?" or "Are we already testing this somewhere else at least partially?".
Sometimes the fix is to re-write the entire tests with a different approach, or to extend an existing spec. Tests are sometimes written without taking a look at other tests files neither near scenarios.

View File

@@ -16,15 +16,231 @@ AllCops:
# to ignore them, so only the ones explicitly set in this file are enabled. # to ignore them, so only the ones explicitly set in this file are enabled.
DisabledByDefault: true DisabledByDefault: true
Rails:
Enabled: true
Metrics/LineLength: Metrics/LineLength:
Max: 100 Max: 100
Layout/IndentationConsistency: Layout/IndentationConsistency:
EnforcedStyle: rails EnforcedStyle: rails
Layout/EndOfLine:
EnforcedStyle: lf
Bundler/DuplicatedGem:
Enabled: true
Bundler/InsecureProtocolSource:
Enabled: true
Bundler/OrderedGems:
Enabled: true
Gemspec/DuplicatedAssignment:
Enabled: true
Gemspec/OrderedDependencies:
Enabled: true
Gemspec/RequiredRubyVersion:
Enabled: true
Performance/Caller:
Enabled: true
Performance/CaseWhenSplat:
Enabled: true
Performance/Casecmp:
Enabled: true
Performance/CompareWithBlock:
Enabled: true
Performance/Count:
Enabled: true
Performance/Detect:
Enabled: true
Performance/DoubleStartEndWith:
Enabled: true
Performance/EndWith:
Enabled: true
Performance/FixedSize:
Enabled: true
Performance/FlatMap:
Enabled: true
Performance/HashEachMethods:
Enabled: true
Performance/LstripRstrip:
Enabled: true
Performance/RangeInclude:
Enabled: true
Performance/RedundantBlockCall:
Enabled: true
Performance/RedundantMatch:
Enabled: true
Performance/RedundantMerge:
Enabled: true
Performance/RedundantSortBy:
Enabled: true
Performance/RegexpMatch:
Enabled: true
Performance/ReverseEach:
Enabled: true
Performance/Sample:
Enabled: true
Performance/Size:
Enabled: true
Performance/StartWith:
Enabled: true
Performance/StringReplacement:
Enabled: true
Performance/TimesMap:
Enabled: true
Performance/UnfreezeString:
Enabled: true
Performance/UriDefaultParser:
Enabled: true
Rails/ActionFilter:
Enabled: true
Rails/ActiveSupportAliases:
Enabled: true
Rails/ApplicationJob:
Enabled: true
Rails/ApplicationRecord:
Enabled: true
Rails/Blank:
Enabled: true
Rails/CreateTableWithTimestamps:
Enabled: true
Rails/Date:
Enabled: true
Rails/Delegate:
Enabled: true
Rails/DelegateAllowBlank:
Enabled: true
Rails/DynamicFindBy:
Enabled: true
Rails/EnumUniqueness:
Enabled: true
Rails/EnvironmentComparison:
Enabled: true
Rails/Exit:
Enabled: true
Rails/FilePath:
Enabled: true
Rails/FindBy:
Enabled: true
Rails/FindEach:
Enabled: true
Rails/HasAndBelongsToMany:
Enabled: true
Rails/HasManyOrHasOneDependent:
Enabled: true
Rails/HttpPositionalArguments:
Enabled: true
Rails/InverseOf:
Enabled: true
Rails/LexicallyScopedActionFilter:
Enabled: true
Rails/NotNullColumn:
Enabled: true
Rails/Output:
Enabled: true
Rails/OutputSafety:
Enabled: true
Rails/PluralizationGrammar:
Enabled: true
Rails/Presence:
Enabled: true
Rails/Present:
Enabled: true
Rails/ReadWriteAttribute:
Enabled: true
Rails/RedundantReceiverInWithOptions:
Enabled: true
Rails/RelativeDateConstant:
Enabled: true
Rails/RequestReferer:
Enabled: true
Rails/ReversibleMigration:
Enabled: true
Rails/SafeNavigation:
Enabled: true
Rails/SaveBang:
Enabled: true
Rails/ScopeArgs:
Enabled: true
Rails/SkipsModelValidations:
Enabled: true
Rails/TimeZone:
Enabled: true
Rails/UniqBeforePluck:
Enabled: true
Rails/UnknownEnv:
Enabled: true
Rails/Validation:
Enabled: true
RSpec/AlignLeftLetBrace: RSpec/AlignLeftLetBrace:
Enabled: false Enabled: false
@@ -102,7 +318,7 @@ RSpec/InstanceSpy:
Enabled: true Enabled: true
RSpec/InstanceVariable: RSpec/InstanceVariable:
Enabled: false Enabled: true
RSpec/InvalidPredicateMatcher: RSpec/InvalidPredicateMatcher:
Enabled: true Enabled: true
@@ -186,3 +402,15 @@ RSpec/VerifiedDoubles:
RSpec/VoidExpect: RSpec/VoidExpect:
Enabled: true Enabled: true
Security/Eval:
Enabled: true
Security/JSONLoad:
Enabled: true
Security/MarshalLoad:
Enabled: true
Security/YAMLLoad:
Enabled: true

View File

@@ -1,112 +1,11 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config` # `rubocop --auto-gen-config`
# on 2018-01-06 19:20:18 +0100 using RuboCop version 0.52.1. # on 2018-02-10 21:25:09 +0100 using RuboCop version 0.52.1.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
# Offense count: 40
# Cop supports --auto-correct.
# Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
# SupportedHashRocketStyles: key, separator, table
# SupportedColonStyles: key, separator, table
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/AlignHash:
Exclude:
- 'spec/controllers/legislation/annotations_controller_spec.rb'
- 'spec/features/admin/banners_spec.rb'
# Offense count: 64
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_parameter, with_fixed_indentation
Layout/AlignParameters:
Enabled: false
# Offense count: 11
# Cop supports --auto-correct.
Layout/ClosingParenthesisIndentation:
Exclude:
- 'spec/features/site_customization/custom_pages_spec.rb'
- 'spec/models/legislation/annotation_spec.rb'
- 'spec/rails_helper.rb'
# Offense count: 37
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: leading, trailing
Layout/DotPosition:
Exclude:
- 'app/controllers/admin/poll/officer_assignments_controller.rb'
- 'app/controllers/admin/poll/polls_controller.rb'
- 'app/controllers/admin/poll/recounts_controller.rb'
- 'app/controllers/officing/residence_controller.rb'
- 'app/controllers/officing/results_controller.rb'
- 'app/models/poll/officer.rb'
- 'app/models/tag_cloud.rb'
- 'app/models/verification/management/managed_user.rb'
- 'lib/merged_comment_tree.rb'
# Offense count: 8
# Cop supports --auto-correct.
Layout/EmptyLineAfterMagicComment:
Exclude:
- 'bin/rspec'
- 'bin/spring'
- 'spec/features/debates_spec.rb'
- 'spec/features/proposal_ballots_spec.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/mailers/devise_mailer_spec.rb'
- 'spec/models/debate_spec.rb'
- 'spec/models/proposal_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/EmptyLinesAroundMethodBody:
Exclude:
- 'lib/graph_ql/api_types_creator.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
Layout/ExtraSpacing:
Exclude:
- 'spec/factories.rb'
- 'spec/models/proposal_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
Layout/FirstParameterIndentation:
Exclude:
- 'app/controllers/users_controller.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
Layout/IndentArray:
EnforcedStyle: consistent
# Offense count: 10
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: special_inside_parentheses, consistent, align_braces
Layout/IndentHash:
Exclude:
- 'spec/controllers/legislation/annotations_controller_spec.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
Layout/IndentHeredoc:
Exclude:
- 'spec/factories.rb'
- 'spec/models/legislation/draft_version_spec.rb'
# Offense count: 10 # Offense count: 10
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle. # Configuration parameters: EnforcedStyle.
@@ -118,673 +17,20 @@ Layout/IndentationConsistency:
- 'spec/models/legislation/draft_version_spec.rb' - 'spec/models/legislation/draft_version_spec.rb'
- 'spec/models/proposal_spec.rb' - 'spec/models/proposal_spec.rb'
# Offense count: 59 # Offense count: 1225
# Cop supports --auto-correct.
# Configuration parameters: Width, IgnoredPatterns.
Layout/IndentationWidth:
Enabled: false
# Offense count: 6
# Cop supports --auto-correct.
Layout/LeadingCommentSpace:
Exclude:
- 'Capfile'
- 'app/controllers/budgets/ballot/lines_controller.rb'
- 'spec/features/budgets/ballots_spec.rb'
- 'spec/features/comments/poll_questions_spec.rb'
- 'spec/support/common_actions.rb'
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line
Layout/MultilineArrayBraceLayout:
Exclude:
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/helpers/search_helper.rb'
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line
Layout/MultilineHashBraceLayout:
Exclude:
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/models/budget/investment.rb'
- 'app/models/debate.rb'
- 'app/models/proposal.rb'
- 'app/models/spending_proposal.rb'
# Offense count: 17
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symmetrical, new_line, same_line
Layout/MultilineMethodCallBraceLayout:
Exclude:
- 'app/controllers/legislation/annotations_controller.rb'
- 'app/controllers/users_controller.rb'
- 'app/models/comment.rb'
- 'app/models/organization.rb'
- 'app/models/user.rb'
- 'spec/features/site_customization/custom_pages_spec.rb'
- 'spec/models/legislation/annotation_spec.rb'
- 'spec/rails_helper.rb'
# Offense count: 59
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented, indented_relative_to_receiver
Layout/MultilineMethodCallIndentation:
Exclude:
- 'app/controllers/admin/poll/officer_assignments_controller.rb'
- 'app/controllers/admin/poll/polls_controller.rb'
- 'app/controllers/admin/poll/recounts_controller.rb'
- 'app/controllers/officing/residence_controller.rb'
- 'app/controllers/officing/results_controller.rb'
- 'app/models/poll/officer.rb'
- 'app/models/tag_cloud.rb'
- 'app/models/verification/management/managed_user.rb'
- 'lib/merged_comment_tree.rb'
- 'spec/models/comment_spec.rb'
- 'spec/models/debate_spec.rb'
- 'spec/models/proposal_spec.rb'
- 'spec/models/user_spec.rb'
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: aligned, indented
Layout/MultilineOperationIndentation:
Exclude:
- 'app/helpers/users_helper.rb'
- 'app/helpers/valuation_helper.rb'
- 'app/models/user.rb'
- 'app/models/verification/letter.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/SpaceAfterColon:
Exclude:
- 'spec/features/admin/site_customization/pages_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
Layout/SpaceBeforeFirstArg:
Exclude:
- 'spec/factories.rb'
# Offense count: 33
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets.
# SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBrackets: space, no_space
Layout/SpaceInsideArrayLiteralBrackets:
Exclude:
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/helpers/admin_helper.rb'
- 'app/helpers/budgets_helper.rb'
- 'app/helpers/geozones_helper.rb'
- 'app/helpers/proposals_helper.rb'
- 'app/helpers/valuation_helper.rb'
- 'app/models/budget/investment.rb'
- 'app/models/budget/investment/milestone.rb'
- 'app/models/legislation/process.rb'
- 'app/models/legislation/proposal.rb'
- 'app/models/poll/question/answer.rb'
- 'app/models/proposal.rb'
- 'spec/factories.rb'
- 'spec/lib/graphql_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/SpaceInsideRangeLiteral:
Exclude:
- 'app/models/legislation/annotation.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
Layout/SpaceInsideReferenceBrackets:
Exclude:
- 'app/helpers/settings_helper.rb'
# Offense count: 39
Lint/AmbiguousBlockAssociation:
Exclude:
- 'spec/controllers/comments_controller_spec.rb'
- 'spec/controllers/debates_controller_spec.rb'
- 'spec/controllers/legislation/annotations_controller_spec.rb'
- 'spec/controllers/legislation/answers_controller_spec.rb'
- 'spec/lib/cache_spec.rb'
- 'spec/models/comment_spec.rb'
- 'spec/models/debate_spec.rb'
- 'spec/models/proposal_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/shared/models/map_validations.rb'
# Offense count: 3
Lint/DuplicateMethods:
Exclude:
- 'app/models/budget/result.rb'
- 'lib/comment_tree.rb'
- 'lib/email_digest.rb'
# Offense count: 2
Lint/HandleExceptions:
Exclude:
- 'app/controllers/legislation/annotations_controller.rb'
- 'spec/lib/graphql_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: runtime_error, standard_error
Lint/InheritException:
Exclude:
- 'app/controllers/concerns/feature_flags.rb'
# Offense count: 1
Lint/LiteralAsCondition:
Exclude:
- 'app/models/budget/investment.rb'
# Offense count: 3
# Cop supports --auto-correct.
Lint/StringConversionInInterpolation:
Exclude:
- 'app/models/poll/partial_result.rb'
# Offense count: 15
# Cop supports --auto-correct.
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
Exclude:
- 'app/controllers/admin/spending_proposals_controller.rb'
- 'app/models/ahoy/data_source.rb'
- 'lib/graph_ql/api_types_creator.rb'
- 'lib/graph_ql/query_type_creator.rb'
- 'spec/controllers/concerns/has_orders_spec.rb'
- 'spec/factories.rb'
- 'spec/spec_helper.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
Lint/UnusedMethodArgument:
Exclude:
- 'app/controllers/organizations/registrations_controller.rb'
- 'app/controllers/users/registrations_controller.rb'
- 'app/mailers/mailer.rb'
- 'app/models/abilities/everyone.rb'
# Offense count: 335
Lint/UselessAssignment:
Enabled: false
# Offense count: 2
Lint/Void:
Exclude:
- 'app/controllers/polls_controller.rb'
- 'app/models/setting.rb'
# Offense count: 86
Metrics/AbcSize:
Max: 77
# Offense count: 513
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 1242
# Offense count: 11
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 266
# Offense count: 13
Metrics/CyclomaticComplexity:
Max: 10
# Offense count: 25
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https # URISchemes: http, https
Metrics/LineLength: Metrics/LineLength:
Max: 248 Max: 248
# Offense count: 71 # Offense count: 4
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 68
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 273
# Offense count: 3
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 7
# Offense count: 8
Metrics/PerceivedComplexity:
Max: 11
# Offense count: 10
Naming/AccessorMethodName:
Exclude:
- 'app/controllers/application_controller.rb'
- 'app/controllers/concerns/commentable_actions.rb'
- 'app/controllers/management/proposals_controller.rb'
- 'app/controllers/management/spending_proposals_controller.rb'
- 'app/controllers/proposals_controller.rb'
- 'lib/merged_comment_tree.rb'
# Offense count: 2
# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts, AllowedAcronyms.
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
Naming/FileName:
Exclude:
- 'Capfile'
- 'Gemfile'
# Offense count: 10
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros.
# NamePrefix: is_, has_, have_
# NamePrefixBlacklist: is_, has_, have_
# NameWhitelist: is_a?
# MethodDefinitionMacros: define_method, define_singleton_method
Naming/PredicateName:
Exclude:
- 'spec/**/*'
- 'app/controllers/concerns/has_filters.rb'
- 'app/controllers/concerns/has_orders.rb'
- 'app/helpers/banners_helper.rb'
- 'app/helpers/debates_helper.rb'
- 'app/models/budget/ballot.rb'
- 'app/models/user.rb'
# Offense count: 95
# Configuration parameters: EnforcedStyle.
# SupportedStyles: snake_case, normalcase, non_integer
Naming/VariableNumber:
Enabled: false
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect.
Performance/HashEachMethods:
Exclude:
- 'app/models/ahoy/data_source.rb'
# Offense count: 6
# Cop supports --auto-correct. # Cop supports --auto-correct.
Performance/RedundantMatch: Performance/RedundantMatch:
Exclude: Exclude:
- 'app/controllers/valuation/budget_investments_controller.rb' - 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb' - 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/helpers/embed_videos_helper.rb'
# Offense count: 18
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/FindBy:
Exclude:
- 'app/models/budget/ballot.rb'
- 'app/models/concerns/relationable.rb'
- 'app/models/geozone.rb'
- 'app/models/legislation/question.rb'
- 'app/models/officing/residence.rb'
- 'app/models/poll/booth.rb'
- 'app/models/poll/voter.rb'
- 'app/models/setting.rb'
- 'app/models/signature.rb'
- 'app/models/user.rb'
- 'app/models/verification/email.rb'
- 'app/models/verification/management/email.rb'
- 'app/models/verification/residence.rb'
# Offense count: 1
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
Exclude:
- 'app/models/poll.rb'
# Offense count: 52
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasManyOrHasOneDependent:
Enabled: false
# Offense count: 37
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: spec/**/*, test/**/*
Rails/HttpPositionalArguments:
Exclude:
- 'spec/controllers/admin/api/stats_controller_spec.rb'
- 'spec/controllers/concerns/has_filters_spec.rb'
- 'spec/controllers/concerns/has_orders_spec.rb'
- 'spec/controllers/debates_controller_spec.rb'
- 'spec/controllers/graphql_controller_spec.rb'
- 'spec/controllers/legislation/annotations_controller_spec.rb'
- 'spec/controllers/legislation/answers_controller_spec.rb'
- 'spec/controllers/management/sessions_controller_spec.rb'
- 'spec/controllers/pages_controller_spec.rb'
- 'spec/controllers/users/registrations_controller_spec.rb'
# Offense count: 71
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/InverseOf:
Enabled: false
# Offense count: 28
# Configuration parameters: Include.
# Include: app/controllers/**/*.rb
Rails/LexicallyScopedActionFilter:
Exclude:
- 'app/controllers/admin/banners_controller.rb'
- 'app/controllers/admin/poll/officer_assignments_controller.rb'
- 'app/controllers/admin/poll/polls_controller.rb'
- 'app/controllers/admin/tags_controller.rb'
- 'app/controllers/concerns/search.rb'
- 'app/controllers/debates_controller.rb'
- 'app/controllers/legislation/proposals_controller.rb'
- 'app/controllers/management/proposals_controller.rb'
- 'app/controllers/moderation/comments_controller.rb'
- 'app/controllers/moderation/debates_controller.rb'
- 'app/controllers/moderation/proposals_controller.rb'
- 'app/controllers/proposals_controller.rb'
- 'app/controllers/users/registrations_controller.rb'
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
# Offense count: 19
Rails/OutputSafety:
Exclude:
- 'app/controllers/admin/legislation/draft_versions_controller.rb'
- 'app/controllers/admin/legislation/processes_controller.rb'
- 'app/controllers/admin/legislation/questions_controller.rb'
- 'app/controllers/budgets/investments_controller.rb'
- 'app/controllers/direct_uploads_controller.rb'
- 'app/controllers/spending_proposals_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/helpers/documents_helper.rb'
- 'app/helpers/text_with_links_helper.rb'
- 'app/helpers/valuation_helper.rb'
# Offense count: 7
# Cop supports --auto-correct.
Rails/Presence:
Exclude:
- 'app/controllers/concerns/commentable_actions.rb'
- 'app/controllers/users/sessions_controller.rb'
- 'app/helpers/welcome_helper.rb'
- 'app/models/legislation/proposal.rb'
- 'app/models/proposal.rb'
- 'app/models/valuator.rb'
# Offense count: 72
# Configuration parameters: Blacklist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
Enabled: false
# Offense count: 4
# Configuration parameters: Environments.
# Environments: development, test, production
Rails/UnknownEnv:
Exclude:
- 'lib/census_api.rb'
- 'lib/sms_api.rb'
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: braces, no_braces, context_dependent
Style/BracesAroundHashParameters:
Exclude:
- 'app/models/concerns/searchable.rb'
- 'spec/features/budgets/investments_spec.rb'
- 'spec/features/proposals_spec.rb'
# Offense count: 126
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle.
# SupportedStyles: nested, compact
Style/ClassAndModuleChildren:
Enabled: false
# Offense count: 5
Style/ClassVars:
Exclude:
- 'app/models/concerns/measurable.rb'
- 'app/models/organization.rb'
- 'app/models/user.rb'
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
# SupportedStyles: assign_to_condition, assign_inside_condition
Style/ConditionalAssignment:
Exclude:
- 'app/controllers/admin/poll/booth_assignments_controller.rb'
- 'app/controllers/admin/poll/questions_controller.rb'
- 'app/controllers/comments_controller.rb'
- 'app/controllers/management/spending_proposals_controller.rb'
- 'app/controllers/spending_proposals_controller.rb'
- 'app/controllers/verification/sms_controller.rb'
- 'lib/graph_ql/api_types_creator.rb'
# Offense count: 19
Style/DateTime:
Exclude:
- 'app/models/user.rb'
- 'spec/controllers/admin/api/stats_controller_spec.rb'
- 'spec/factories.rb'
- 'spec/features/admin/banners_spec.rb'
- 'spec/models/ahoy/data_source_spec.rb'
# Offense count: 1
Style/DoubleNegation:
Exclude:
- 'app/models/flag.rb'
# Offense count: 6
# Cop supports --auto-correct.
Style/Encoding:
Exclude:
- 'spec/features/debates_spec.rb'
- 'spec/features/proposal_ballots_spec.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/mailers/devise_mailer_spec.rb'
- 'spec/models/debate_spec.rb'
- 'spec/models/proposal_spec.rb'
# Offense count: 61
# Configuration parameters: MinBodyLength.
Style/GuardClause:
Enabled: false
# Offense count: 49
# Cop supports --auto-correct.
Style/IfUnlessModifier:
Enabled: false
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'app/models/comment.rb'
- 'app/models/concerns/followable.rb'
- 'app/models/direct_message.rb'
- 'lib/graph_ql/api_types_creator.rb'
# Offense count: 10
Style/MixinUsage:
Exclude:
- 'lib/census_api.rb'
- 'lib/local_census.rb'
- 'spec/features/comments/budget_investments_spec.rb'
- 'spec/features/comments/debates_spec.rb'
- 'spec/features/comments/legislation_annotations_spec.rb'
- 'spec/features/comments/legislation_questions_spec.rb'
- 'spec/features/comments/polls_spec.rb'
- 'spec/features/comments/proposals_spec.rb'
- 'spec/features/comments/topics_spec.rb'
- 'spec/rails_helper.rb'
# Offense count: 1
Style/MultilineBlockChain:
Exclude:
- 'app/controllers/valuation/spending_proposals_controller.rb'
# Offense count: 1
# Cop supports --auto-correct.
Style/MultilineIfThen:
Exclude:
- 'app/controllers/management/users_controller.rb'
# Offense count: 13
# Cop supports --auto-correct.
Style/MutableConstant:
Exclude:
- 'app/models/activity.rb'
- 'app/models/budget/reclassified_vote.rb'
- 'app/models/legislation/draft_version.rb'
- 'app/models/poll/partial_result.rb'
- 'app/models/proposal.rb'
- 'app/models/signature_sheet.rb'
- 'app/models/site_customization/content_block.rb'
- 'app/models/site_customization/image.rb'
- 'app/models/site_customization/page.rb'
- 'lib/graph_ql/api_types_creator.rb'
- 'lib/tag_sanitizer.rb'
- 'lib/wysiwyg_sanitizer.rb'
# Offense count: 54
# Cop supports --auto-correct.
# Configuration parameters: Strict.
Style/NumericLiterals:
MinDigits: 9
# Offense count: 20
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle.
# SupportedStyles: predicate, comparison
Style/NumericPredicate:
Exclude:
- 'spec/**/*'
- 'app/controllers/users_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/helpers/banners_helper.rb'
- 'app/helpers/debates_helper.rb'
- 'app/helpers/votes_helper.rb'
- 'app/models/budget/ballot.rb'
- 'app/models/concerns/conflictable.rb'
- 'app/models/concerns/taggable.rb'
- 'app/models/debate.rb'
- 'app/models/lock.rb'
- 'app/models/user.rb'
- 'app/models/verification/management/email.rb'
- 'lib/score_calculator.rb'
# Offense count: 2
# Cop supports --auto-correct.
Style/ParallelAssignment:
Exclude:
- 'lib/active_model/dates.rb'
- 'spec/support/common_actions.rb'
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, exploded
Style/RaiseArgs:
Exclude:
- 'app/controllers/management/base_controller.rb'
- 'app/controllers/users/omniauth_callbacks_controller.rb'
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/valuation/spending_proposals_controller.rb'
# Offense count: 2
# Cop supports --auto-correct.
Style/RedundantBegin:
Exclude:
- 'app/controllers/graphql_controller.rb'
- 'app/models/legislation/annotation.rb'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
- 'app/controllers/related_contents_controller.rb'
- 'app/helpers/embed_videos_helper.rb'
- 'app/models/poll/question/answer/video.rb'
- 'spec/customization_engine_spec.rb'
# Offense count: 6
# Cop supports --auto-correct.
Style/RescueModifier:
Exclude:
- 'app/controllers/budgets/investments_controller.rb'
- 'app/controllers/concerns/search.rb'
- 'app/controllers/verification/sms_controller.rb'
- 'app/models/concerns/measurable.rb'
# Offense count: 11 # Offense count: 11
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: implicit, explicit
Style/RescueStandardError:
Exclude:
- 'app/controllers/graphql_controller.rb'
- 'app/controllers/related_contents_controller.rb'
- 'app/helpers/locales_helper.rb'
- 'app/models/legislation/annotation.rb'
- 'lib/local_census.rb'
- 'lib/manager_authenticator.rb'
- 'lib/tasks/emails.rake'
- 'spec/shared/features/nested_documentable.rb'
- 'spec/shared/features/nested_imageable.rb'
# Offense count: 15
# Cop supports --auto-correct.
# Configuration parameters: ConvertCodeThatCanStartToReturnNil.
Style/SafeNavigation:
Exclude:
- 'app/controllers/legislation/draft_versions_controller.rb'
- 'app/controllers/sandbox_controller.rb'
- 'app/controllers/verification/letter_controller.rb'
- 'app/helpers/users_helper.rb'
- 'app/models/concerns/galleryable.rb'
- 'app/models/concerns/imageable.rb'
- 'app/models/legislation/proposal.rb'
- 'app/models/proposal.rb'
- 'app/models/signature.rb'
- 'app/models/user.rb'
# Offense count: 31
# Cop supports --auto-correct.
# Configuration parameters: WordRegex.
# SupportedStyles: percent, brackets
Style/WordArray:
EnforcedStyle: percent
MinSize: 8
# Offense count: 10
RSpec/DescribeClass: RSpec/DescribeClass:
Exclude: Exclude:
- 'spec/customization_engine_spec.rb' - 'spec/customization_engine_spec.rb'
@@ -794,6 +40,7 @@ RSpec/DescribeClass:
- 'spec/lib/graphql_spec.rb' - 'spec/lib/graphql_spec.rb'
- 'spec/lib/tasks/communities_spec.rb' - 'spec/lib/tasks/communities_spec.rb'
- 'spec/lib/tasks/dev_seed_spec.rb' - 'spec/lib/tasks/dev_seed_spec.rb'
- 'spec/lib/tasks/map_location_spec.rb'
- 'spec/lib/tasks/settings_spec.rb' - 'spec/lib/tasks/settings_spec.rb'
- 'spec/models/abilities/organization_spec.rb' - 'spec/models/abilities/organization_spec.rb'
- 'spec/views/welcome/index.html.erb_spec.rb' - 'spec/views/welcome/index.html.erb_spec.rb'
@@ -806,6 +53,17 @@ RSpec/DescribedClass:
- 'spec/controllers/concerns/has_filters_spec.rb' - 'spec/controllers/concerns/has_filters_spec.rb'
- 'spec/controllers/concerns/has_orders_spec.rb' - 'spec/controllers/concerns/has_orders_spec.rb'
# Offense count: 6
RSpec/ExpectActual:
Exclude:
- 'spec/routing/**/*'
- 'spec/features/admin/budget_investments_spec.rb'
# Offense count: 830
# Configuration parameters: AssignmentOnly.
RSpec/InstanceVariable:
Enabled: false
# Offense count: 1 # Offense count: 1
# Configuration parameters: IgnoreSymbolicNames. # Configuration parameters: IgnoreSymbolicNames.
RSpec/VerifiedDoubles: RSpec/VerifiedDoubles:

View File

@@ -7,10 +7,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased](https://github.com/consul/consul/compare/v0.13...consul:master) ## [Unreleased](https://github.com/consul/consul/compare/v0.13...consul:master)
### Added ### Added
- Missing polls button on help page https://github.com/consul/consul/pull/2452
- New legislation processes section on help page https://github.com/consul/consul/pull/2452
### Changed ### Changed
- Show investment links only on phase balloting or later https://github.com/consul/consul/pull/2386
### Deprecated ### Deprecated
### Removed ### Removed
### Fixed ### Fixed
- Improve spec boot time and clean up logs https://github.com/consul/consul/pull/2444
- Flaky spec: random investments order scenario https://github.com/consul/consul/pull/2454
- Flaky spec: users without email should not receive emails https://github.com/consul/consul/pull/2453
- Flaky spec: missing comment on legislation annotation https://github.com/consul/consul/pull/2455
- Flaky spec: Residence Assigned officers error https://github.com/consul/consul/pull/2458
### Security ### Security
## [0.13.0](https://github.com/consul/consul/compare/v0.12...v0.13) - 2018-02-05 ## [0.13.0](https://github.com/consul/consul/compare/v0.12...v0.13) - 2018-02-05

View File

@@ -60,7 +60,7 @@ end
group :development, :test do group :development, :test do
gem 'bullet', '~> 5.7.0' gem 'bullet', '~> 5.7.0'
gem 'byebug', '~> 9.1.0' gem 'byebug', '~> 10.0.0'
gem 'factory_bot_rails', '~> 4.8.2' gem 'factory_bot_rails', '~> 4.8.2'
gem 'faker', '~> 1.8.7' gem 'faker', '~> 1.8.7'
gem 'i18n-tasks', '~> 0.9.20' gem 'i18n-tasks', '~> 0.9.20'

View File

@@ -71,7 +71,7 @@ GEM
bullet (5.7.1) bullet (5.7.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
uniform_notifier (~> 1.11.0) uniform_notifier (~> 1.11.0)
byebug (9.1.0) byebug (10.0.0)
cancancan (2.1.2) cancancan (2.1.2)
capistrano (3.10.1) capistrano (3.10.1)
airbrussh (>= 1.0.0) airbrussh (>= 1.0.0)
@@ -497,7 +497,7 @@ DEPENDENCIES
ancestry (~> 3.0.1) ancestry (~> 3.0.1)
browser (~> 2.5.2) browser (~> 2.5.2)
bullet (~> 5.7.0) bullet (~> 5.7.0)
byebug (~> 9.1.0) byebug (~> 10.0.0)
cancancan (~> 2.1.2) cancancan (~> 2.1.2)
capistrano (~> 3.10.1) capistrano (~> 3.10.1)
capistrano-bundler (~> 1.2) capistrano-bundler (~> 1.2)

View File

@@ -101,7 +101,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
end end
def load_investment def load_investment
@investment = Budget::Investment.where(budget_id: @budget.id).find(params[:id]) @investment = Budget::Investment.by_budget(@budget).find(params[:id])
end end
def load_admins def load_admins

View File

@@ -95,7 +95,7 @@ module Budgets
def set_random_seed def set_random_seed
if params[:order] == 'random' || params[:order].blank? if params[:order] == 'random' || params[:order].blank?
seed = rand(-100..100) / 100.0 seed = params[:random_seed] || session[:random_seed] || rand(-100000..100000)
params[:random_seed] ||= Float(seed) rescue 0 params[:random_seed] ||= Float(seed) rescue 0
else else
params[:random_seed] = nil params[:random_seed] = nil

View File

@@ -1,6 +1,8 @@
module BudgetInvestmentsHelper module BudgetInvestmentsHelper
def budget_investments_sorting_options def budget_investments_sorting_options
Budget::Investment::SORTING_OPTIONS.map { |so| [t("admin.budget_investments.index.sort_by.#{so}"), so] } Budget::Investment::SORTING_OPTIONS.map do |so|
[t("admin.budget_investments.index.sort_by.#{so}"), so]
end
end end
def budget_investments_advanced_filters(params) def budget_investments_advanced_filters(params)

View File

@@ -1,5 +1,9 @@
module BudgetsHelper module BudgetsHelper
def show_links_to_budget_investments(budget)
['balloting', 'reviewing_ballots', 'finished'].include? budget.phase
end
def heading_name_and_price_html(heading, budget) def heading_name_and_price_html(heading, budget)
content_tag :div do content_tag :div do
concat(heading.name + ' ') concat(heading.name + ' ')
@@ -53,7 +57,7 @@ module BudgetsHelper
end end
def investment_tags_select_options(budget) def investment_tags_select_options(budget)
Budget::Investment.where(budget_id: budget).tags_on(:valuation).order(:name).select(:name).distinct Budget::Investment.by_budget(budget).tags_on(:valuation).order(:name).select(:name).distinct
end end
def budget_published?(budget) def budget_published?(budget)

View File

@@ -6,9 +6,9 @@ module EmbedVideosHelper
def embedded_video_code def embedded_video_code
link = @proposal.video_url link = @proposal.video_url
title = t('proposals.show.embed_video_title', proposal: @proposal.title) title = t('proposals.show.embed_video_title', proposal: @proposal.title)
if link.match(/vimeo.*/) if link =~ /vimeo.*/
server = "Vimeo" server = "Vimeo"
elsif link.match(/youtu*.*/) elsif link =~ /youtu*.*/
server = "YouTube" server = "YouTube"
end end

View File

@@ -10,12 +10,12 @@ module Ahoy
# chart # chart
def add(name, collection) def add(name, collection)
collections.push data: collection, name: name collections.push data: collection, name: name
collection.each{ |k, v| add_key k } collection.each_key{ |key| add_key key }
end end
def build def build
data = { x: [] } data = { x: [] }
keys.each do |k| shared_keys.each do |k|
# Add the key with a valid date format # Add the key with a valid date format
data[:x].push k.strftime("%Y-%m-%d") data[:x].push k.strftime("%Y-%m-%d")
@@ -36,12 +36,12 @@ module Ahoy
@collections ||= [] @collections ||= []
end end
def keys def shared_keys
@keys ||= [] @shared_keys ||= []
end end
def add_key(key) def add_key(key)
keys.push(key) unless keys.include? key shared_keys.push(key) unless shared_keys.include? key
end end
end end

View File

@@ -81,6 +81,7 @@ class Budget
scope :by_admin, ->(admin_id) { where(administrator_id: admin_id) } scope :by_admin, ->(admin_id) { where(administrator_id: admin_id) }
scope :by_tag, ->(tag_name) { tagged_with(tag_name) } scope :by_tag, ->(tag_name) { tagged_with(tag_name) }
scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) } scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) }
scope :by_budget, ->(budget) { where(budget: budget) }
scope :for_render, -> { includes(:heading) } scope :for_render, -> { includes(:heading) }
@@ -102,8 +103,8 @@ class Budget
end end
def self.scoped_filter(params, current_filter) def self.scoped_filter(params, current_filter)
budget = Budget.find_by(id: params[:budget_id]) || Budget.find_by(slug: params[:budget_id]) budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id])
results = Investment.where(budget_id: budget.id) results = Investment.by_budget(budget)
results = limit_results(budget, params, results) if params[:max_per_heading].present? results = limit_results(budget, params, results) if params[:max_per_heading].present?
results = results.where(group_id: params[:group_id]) if params[:group_id].present? results = results.where(group_id: params[:group_id]) if params[:group_id].present?

View File

@@ -1,6 +1,6 @@
<%= link_to "#advanced_filters_content", <%= link_to "#advanced_filters_content",
data: {toggle: "advanced_filters"}, data: {toggle: "advanced_filters"},
class: "advanced-filters float-right" do %> class: "advanced-filters float-right clear" do %>
<%= t("admin.budget_investments.index.advanced_filters") %> <%= t("admin.budget_investments.index.advanced_filters") %>
<% end %> <% end %>

View File

@@ -57,13 +57,13 @@
</div> </div>
</div> </div>
<div id="budget_info"> <div id="budget_info" class="budget-info">
<div class="row margin-top"> <div class="row margin-top">
<div class="small-12 column"> <div class="small-12 column">
<div id="groups_and_headings" class="groups-and-headings"> <div id="groups_and_headings" class="groups-and-headings">
<% current_budget.groups.each do |group| %> <% current_budget.groups.each do |group| %>
<h2><%= group.name %></h2> <h2 id="<%= group.name.parameterize %>"><%= group.name %></h2>
<ul class="no-bullet"> <ul class="no-bullet">
<% group.headings.order_by_group_name.each do |heading| %> <% group.headings.order_by_group_name.each do |heading| %>
<li class="heading small-12 medium-4 large-2"> <li class="heading small-12 medium-4 large-2">
@@ -89,15 +89,20 @@
</div> </div>
<p> <p>
<% show_links = show_links_to_budget_investments(current_budget) %>
<% if show_links %>
<%= link_to budget_investments_path(current_budget.id) do %> <%= link_to budget_investments_path(current_budget.id) do %>
<small><%= t("budgets.index.investment_proyects") %></small> <small><%= t("budgets.index.investment_proyects") %></small>
<% end %><br> <% end %><br>
<% end %>
<%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unfeasible') do %> <%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unfeasible') do %>
<small><%= t("budgets.index.unfeasible_investment_proyects") %></small> <small><%= t("budgets.index.unfeasible_investment_proyects") %></small>
<% end %><br> <% end %><br>
<% if show_links %>
<%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unselected') do %> <%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unselected') do %>
<small><%= t("budgets.index.not_selected_investment_proyects") %></small> <small><%= t("budgets.index.not_selected_investment_proyects") %></small>
<% end %> <% end %>
<% end %>
</p> </p>
<% end %> <% end %>
@@ -132,7 +137,7 @@
</div> </div>
</div> </div>
<div class="small-12 medium-3 column table" data-equalizer-watch> <div class="small-12 medium-3 column table" data-equalizer-watch>
<div class="table-cell align-middle"> <div id="budget_<%= budget.id %>_results" class="table-cell align-middle">
<%= link_to t("budgets.index.see_results"), <%= link_to t("budgets.index.see_results"),
budget_results_path(budget.id), budget_results_path(budget.id),
class: "button expanded" %> class: "button expanded" %>

View File

@@ -5,7 +5,7 @@
<h1><%= t("proposals.new.start_new") %></h1> <h1><%= t("proposals.new.start_new") %></h1>
<div data-alert class="callout primary"> <div data-alert class="callout primary">
<%= link_to help_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %> <%= link_to help_path(anchor: "proposals"), title: t('shared.target_blank_html'), target: "_blank" do %>
<%= t("proposals.new.more_info")%> <%= t("proposals.new.more_info")%>
<% end %> <% end %>
</div> </div>

View File

@@ -16,6 +16,16 @@
<%= link_to t("pages.help.menu.budgets"), "#budgets", class: "button hollow expanded" %> <%= link_to t("pages.help.menu.budgets"), "#budgets", class: "button hollow expanded" %>
</li> </li>
<% end %> <% end %>
<% if feature?(:polls) %>
<li>
<%= link_to t("pages.help.menu.polls"), "#polls", class: "button hollow expanded" %>
</li>
<% end %>
<% if feature?(:legislation) %>
<li>
<%= link_to t("pages.help.menu.processes"), "#processes", class: "button hollow expanded" %>
</li>
<% end %>
<li> <li>
<%= link_to t("pages.help.menu.other"), "#other", class: "button hollow expanded" %> <%= link_to t("pages.help.menu.other"), "#other", class: "button hollow expanded" %>
</li> </li>

View File

@@ -0,0 +1,20 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="processes" data-magellan-target="processes">
<%= t("pages.help.processes.title") %>
</h3>
<p>
<% link = link_to(t("pages.help.processes.link"), legislation_processes_path) %>
<%= t("pages.help.processes.description", link: link).html_safe %>
</p>
<ul class="features">
<li>
<% link = link_to(t("pages.help.processes.link"), legislation_processes_path) %>
<% sign_up_link = t("pages.help.processes.sign_up", org: setting['org_name']) %>
<% sign_up = link_to(sign_up_link, new_user_registration_path) %>
<%= t("pages.help.processes.feature", link: link, sign_up: sign_up).html_safe %>
</li>
</ul>
</div>
</div>

View File

@@ -33,6 +33,10 @@
<% if feature?(:polls) %> <% if feature?(:polls) %>
<%= render "pages/help/polls" %> <%= render "pages/help/polls" %>
<% end %> <% end %>
<% if feature?(:legislation) %>
<%= render "pages/help/processes" %>
<% end %>
</div> </div>
<div class="small-12 medium-4 large-3 column more-info-sidebar"> <div class="small-12 medium-4 large-3 column more-info-sidebar">
<%= render "pages/help/sidebar" %> <%= render "pages/help/sidebar" %>

View File

@@ -5,7 +5,7 @@
<h1><%= t("proposals.new.start_new") %></h1> <h1><%= t("proposals.new.start_new") %></h1>
<div data-alert class="callout primary"> <div data-alert class="callout primary">
<%= link_to help_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %> <%= link_to help_path(anchor: "proposals"), title: t('shared.target_blank_html'), target: "_blank" do %>
<%= t("proposals.new.more_info")%> <%= t("proposals.new.more_info")%>
<% end %> <% end %>
</div> </div>

View File

@@ -5,7 +5,8 @@
<td> <td>
<% if can? :destroy, budget_investment %> <% if can? :destroy, budget_investment %>
<%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment),
method: :delete, class: "button hollow alert expanded" %> method: :delete, class: "button hollow alert expanded",
data: {confirm: "#{t('users.show.delete_alert')}"} %>
<% end %> <% end %>
</td> </td>
</tr> </tr>

View File

@@ -741,6 +741,7 @@ en:
no_private_messages: "This user doesn't accept private messages." no_private_messages: "This user doesn't accept private messages."
private_activity: This user decided to keep the activity list private. private_activity: This user decided to keep the activity list private.
send_private_message: "Send private message" send_private_message: "Send private message"
delete_alert: "Are you sure you want to delete your investment project? This action can't be undone"
proposals: proposals:
send_notification: "Send notification" send_notification: "Send notification"
retire: "Retire" retire: "Retire"

View File

@@ -11,7 +11,9 @@ en:
debates: "Debates" debates: "Debates"
proposals: "Proposals" proposals: "Proposals"
budgets: "Participatory budgets" budgets: "Participatory budgets"
polls: "Polls"
other: "Other information of interest" other: "Other information of interest"
processes: "Processes"
debates: debates:
title: "Debates" title: "Debates"
description: "In the %{link} section you can present and share your opinion with other people on issues of concern to you related to the city. It is also a place to generate ideas that through the other sections of %{org} lead to concrete actions by the City Council." description: "In the %{link} section you can present and share your opinion with other people on issues of concern to you related to the city. It is also a place to generate ideas that through the other sections of %{org} lead to concrete actions by the City Council."
@@ -47,6 +49,12 @@ en:
feature_1_link: "register in %{org_name}" feature_1_link: "register in %{org_name}"
feature_2: "All registered voters over the age of 16 can vote." feature_2: "All registered voters over the age of 16 can vote."
feature_3: "The results of all votes are binding on the municipal government." feature_3: "The results of all votes are binding on the municipal government."
processes:
title: "Processes"
description: "In the %{link} section, citizens participate in the drafting and modification of regulations affecting the city and can give their opinion on municipal policies in previous debates."
link: "processes"
feature: "To participate in a process you have to %{sign_up} and check the %{link} page periodically to see which regulations and policies are being discussed and consulted."
sign_up: "sign up on %{org}"
faq: faq:
title: "Technical problems?" title: "Technical problems?"
description: "Read the FAQs and solve your questions." description: "Read the FAQs and solve your questions."

View File

@@ -740,6 +740,7 @@ es:
no_private_messages: "Este usuario no acepta mensajes privados." no_private_messages: "Este usuario no acepta mensajes privados."
private_activity: Este usuario ha decidido mantener en privado su lista de actividades. private_activity: Este usuario ha decidido mantener en privado su lista de actividades.
send_private_message: "Enviar un mensaje privado" send_private_message: "Enviar un mensaje privado"
delete_alert: "¿Estás seguro de que deseas borrar tu proyecto de gasto? Esta acción no se puede deshacer"
proposals: proposals:
send_notification: "Enviar notificación" send_notification: "Enviar notificación"
retire: "Retirar" retire: "Retirar"

View File

@@ -11,7 +11,9 @@ es:
debates: "Debates" debates: "Debates"
proposals: "Propuestas" proposals: "Propuestas"
budgets: "Presupuestos participativos" budgets: "Presupuestos participativos"
polls: "Votaciones"
other: "Otra información de interés" other: "Otra información de interés"
processes: "Procesos legislativos"
debates: debates:
title: "Debates" title: "Debates"
description: "En la sección de %{link} puedes exponer y compartir tu opinión con otras personas sobre temas que te preocupan relacionados con la ciudad. También es un espacio donde generar ideas que a través de las otras secciones de %{org} lleven a actuaciones concretas por parte del Ayuntamiento." description: "En la sección de %{link} puedes exponer y compartir tu opinión con otras personas sobre temas que te preocupan relacionados con la ciudad. También es un espacio donde generar ideas que a través de las otras secciones de %{org} lleven a actuaciones concretas por parte del Ayuntamiento."
@@ -47,6 +49,12 @@ es:
feature_1_link: "registrarte en %{org_name}" feature_1_link: "registrarte en %{org_name}"
feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años." feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años."
feature_3: "Los resultados de todas las votaciones son vinculantes para el gobierno municipal." feature_3: "Los resultados de todas las votaciones son vinculantes para el gobierno municipal."
processes:
title: "Procesos legislativos"
description: "En la sección de %{link} la ciudadanía participa en la elaboración y modificación de normativa que afecta a la ciudad y puede dar su opinión sobre las políticas municipales en debates previos."
link: "procesos legislativos"
feature: "Para participar en un proceso hay que %{sign_up} y consultar la página de %{link} periódicamente para saber qué normativas y políticas se están debatiendo y consultando."
sign_up: "registrarse en %{org}"
faq: faq:
title: "¿Problemas técnicos?" title: "¿Problemas técnicos?"
description: "Lee las preguntas frecuentes y resuelve tus dudas." description: "Lee las preguntas frecuentes y resuelve tus dudas."

View File

@@ -124,9 +124,15 @@ section "Creating Users" do
moderator = create_user('mod@consul.dev', 'mod') moderator = create_user('mod@consul.dev', 'mod')
moderator.create_moderator moderator.create_moderator
moderator.update(residence_verified_at: Time.current,
confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1",
verified_at: Time.current, document_number: unique_document_number)
manager = create_user('manager@consul.dev', 'manager') manager = create_user('manager@consul.dev', 'manager')
manager.create_manager manager.create_manager
manager.update(residence_verified_at: Time.current,
confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1",
verified_at: Time.current, document_number: unique_document_number)
valuator = create_user('valuator@consul.dev', 'valuator') valuator = create_user('valuator@consul.dev', 'valuator')
valuator.create_valuator valuator.create_valuator
@@ -154,7 +160,6 @@ section "Creating Users" do
document_number: unique_document_number, document_type: "1") document_number: unique_document_number, document_type: "1")
verified = create_user('verified@consul.dev', 'verified') verified = create_user('verified@consul.dev', 'verified')
verified.update(residence_verified_at: Time.current, verified.update(residence_verified_at: Time.current,
confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1",
verified_at: Time.current, document_number: unique_document_number) verified_at: Time.current, document_number: unique_document_number)

View File

@@ -2,11 +2,14 @@ require 'rails_helper'
feature 'Admin budget investments' do feature 'Admin budget investments' do
let(:budget) { create(:budget) }
let(:administrator) do
create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
end
background do background do
admin = create(:administrator) admin = create(:administrator)
login_as(admin.user) login_as(admin.user)
@budget = create(:budget)
end end
context "Feature flag" do context "Feature flag" do
@@ -28,8 +31,8 @@ feature 'Admin budget investments' do
context "Index" do context "Index" do
scenario 'Displaying investments' do scenario 'Displaying investments' do
budget_investment = create(:budget_investment, budget: @budget, cached_votes_up: 77) budget_investment = create(:budget_investment, budget: budget, cached_votes_up: 77)
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_content(budget_investment.title) expect(page).to have_content(budget_investment.title)
expect(page).to have_content(budget_investment.heading.name) expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content(budget_investment.id) expect(page).to have_content(budget_investment.id)
@@ -52,9 +55,9 @@ feature 'Admin budget investments' do
end end
scenario 'Displaying assignments info' do scenario 'Displaying assignments info' do
budget_investment1 = create(:budget_investment, budget: @budget) budget_investment1 = create(:budget_investment, budget: budget)
budget_investment2 = create(:budget_investment, budget: @budget) budget_investment2 = create(:budget_investment, budget: budget)
budget_investment3 = create(:budget_investment, budget: @budget) budget_investment3 = create(:budget_investment, budget: budget)
valuator1 = create(:valuator, user: create(:user, username: 'Olga'), description: 'Valuator Olga') valuator1 = create(:valuator, user: create(:user, username: 'Olga'), description: 'Valuator Olga')
valuator2 = create(:valuator, user: create(:user, username: 'Miriam'), description: 'Valuator Miriam') valuator2 = create(:valuator, user: create(:user, username: 'Miriam'), description: 'Valuator Miriam')
@@ -64,7 +67,7 @@ feature 'Admin budget investments' do
budget_investment2.valuator_ids = [valuator1.id, valuator2.id] budget_investment2.valuator_ids = [valuator1.id, valuator2.id]
budget_investment3.update(administrator_id: admin.id) budget_investment3.update(administrator_id: admin.id)
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
within("#budget_investment_#{budget_investment1.id}") do within("#budget_investment_#{budget_investment1.id}") do
expect(page).to have_content("No admin assigned") expect(page).to have_content("No admin assigned")
@@ -84,18 +87,18 @@ feature 'Admin budget investments' do
end end
scenario "Filtering by budget heading", :js do scenario "Filtering by budget heading", :js do
group1 = create(:budget_group, name: "Streets", budget: @budget) group1 = create(:budget_group, name: "Streets", budget: budget)
group2 = create(:budget_group, name: "Parks", budget: @budget) group2 = create(:budget_group, name: "Parks", budget: budget)
group1_heading1 = create(:budget_heading, group: group1, name: "Main Avenue") group1_heading1 = create(:budget_heading, group: group1, name: "Main Avenue")
group1_heading2 = create(:budget_heading, group: group1, name: "Mercy Street") group1_heading2 = create(:budget_heading, group: group1, name: "Mercy Street")
group2_heading1 = create(:budget_heading, group: group2, name: "Central Park") group2_heading1 = create(:budget_heading, group: group2, name: "Central Park")
create(:budget_investment, title: "Realocate visitors", budget: @budget, group: group1, heading: group1_heading1) create(:budget_investment, title: "Realocate visitors", budget: budget, group: group1, heading: group1_heading1)
create(:budget_investment, title: "Change name", budget: @budget, group: group1, heading: group1_heading2) create(:budget_investment, title: "Change name", budget: budget, group: group1, heading: group1_heading2)
create(:budget_investment, title: "Plant trees", budget: @budget, group: group2, heading: group2_heading1) create(:budget_investment, title: "Plant trees", budget: budget, group: group2, heading: group2_heading1)
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_link("Realocate visitors") expect(page).to have_link("Realocate visitors")
expect(page).to have_link("Change name") expect(page).to have_link("Change name")
@@ -130,10 +133,10 @@ feature 'Admin budget investments' do
user = create(:user, username: 'Admin 1') user = create(:user, username: 'Admin 1')
administrator = create(:administrator, user: user) administrator = create(:administrator, user: user)
create(:budget_investment, title: "Realocate visitors", budget: @budget, administrator: administrator) create(:budget_investment, title: "Realocate visitors", budget: budget, administrator: administrator)
create(:budget_investment, title: "Destroy the city", budget: @budget) create(:budget_investment, title: "Destroy the city", budget: budget)
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_link("Realocate visitors") expect(page).to have_link("Realocate visitors")
expect(page).to have_link("Destroy the city") expect(page).to have_link("Destroy the city")
@@ -159,12 +162,12 @@ feature 'Admin budget investments' do
user = create(:user) user = create(:user)
valuator = create(:valuator, user: user, description: 'Valuator 1') valuator = create(:valuator, user: user, description: 'Valuator 1')
budget_investment = create(:budget_investment, title: "Realocate visitors", budget: @budget) budget_investment = create(:budget_investment, title: "Realocate visitors", budget: budget)
budget_investment.valuators << valuator budget_investment.valuators << valuator
create(:budget_investment, title: "Destroy the city", budget: @budget) create(:budget_investment, title: "Destroy the city", budget: budget)
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_link("Realocate visitors") expect(page).to have_link("Realocate visitors")
expect(page).to have_link("Destroy the city") expect(page).to have_link("Destroy the city")
@@ -193,13 +196,13 @@ feature 'Admin budget investments' do
'under_valuation' => 'Under valuation', 'under_valuation' => 'Under valuation',
'valuation_finished' => 'Valuation finished' } 'valuation_finished' => 'Valuation finished' }
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).not_to have_link(filters_links.values.first) expect(page).not_to have_link(filters_links.values.first)
filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) }
filters_links.each_pair do |current_filter, link| filters_links.each_pair do |current_filter, link|
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: current_filter) visit admin_budget_budget_investments_path(budget_id: budget.id, filter: current_filter)
expect(page).not_to have_link(link) expect(page).not_to have_link(link)
@@ -210,55 +213,55 @@ feature 'Admin budget investments' do
end end
scenario "Filtering by assignment status" do scenario "Filtering by assignment status" do
assigned = create(:budget_investment, title: "Assigned idea", budget: @budget, administrator: create(:administrator)) assigned = create(:budget_investment, title: "Assigned idea", budget: budget, administrator: create(:administrator))
valuating = create(:budget_investment, title: "Evaluating...", budget: @budget) valuating = create(:budget_investment, title: "Evaluating...", budget: budget)
valuating.valuators.push(create(:valuator)) valuating.valuators.push(create(:valuator))
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_admin') visit admin_budget_budget_investments_path(budget_id: budget.id, filter: 'without_admin')
expect(page).to have_content("Evaluating...") expect(page).to have_content("Evaluating...")
expect(page).not_to have_content("Assigned idea") expect(page).not_to have_content("Assigned idea")
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_valuator') visit admin_budget_budget_investments_path(budget_id: budget.id, filter: 'without_valuator')
expect(page).to have_content("Assigned idea") expect(page).to have_content("Assigned idea")
expect(page).not_to have_content("Evaluating...") expect(page).not_to have_content("Evaluating...")
end end
scenario "Filtering by valuation status" do scenario "Filtering by valuation status" do
valuating = create(:budget_investment, budget: @budget, title: "Ongoing valuation", administrator: create(:administrator)) valuating = create(:budget_investment, budget: budget, title: "Ongoing valuation", administrator: create(:administrator))
valuated = create(:budget_investment, budget: @budget, title: "Old idea", valuation_finished: true) valuated = create(:budget_investment, budget: budget, title: "Old idea", valuation_finished: true)
valuating.valuators.push(create(:valuator)) valuating.valuators.push(create(:valuator))
valuated.valuators.push(create(:valuator)) valuated.valuators.push(create(:valuator))
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'under_valuation') visit admin_budget_budget_investments_path(budget_id: budget.id, filter: 'under_valuation')
expect(page).to have_content("Ongoing valuation") expect(page).to have_content("Ongoing valuation")
expect(page).not_to have_content("Old idea") expect(page).not_to have_content("Old idea")
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_finished') visit admin_budget_budget_investments_path(budget_id: budget.id, filter: 'valuation_finished')
expect(page).not_to have_content("Ongoing valuation") expect(page).not_to have_content("Ongoing valuation")
expect(page).to have_content("Old idea") expect(page).to have_content("Old idea")
visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'all') visit admin_budget_budget_investments_path(budget_id: budget.id, filter: 'all')
expect(page).to have_content("Ongoing valuation") expect(page).to have_content("Ongoing valuation")
expect(page).to have_content("Old idea") expect(page).to have_content("Old idea")
end end
scenario "Filtering by tag" do scenario "Filtering by tag" do
create(:budget_investment, budget: @budget, title: 'Educate the children', tag_list: 'Education') create(:budget_investment, budget: budget, title: 'Educate the children', tag_list: 'Education')
create(:budget_investment, budget: @budget, title: 'More schools', tag_list: 'Education') create(:budget_investment, budget: budget, title: 'More schools', tag_list: 'Education')
create(:budget_investment, budget: @budget, title: 'More hospitals', tag_list: 'Health') create(:budget_investment, budget: budget, title: 'More hospitals', tag_list: 'Health')
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_css(".budget_investment", count: 3) expect(page).to have_css(".budget_investment", count: 3)
expect(page).to have_content("Educate the children") expect(page).to have_content("Educate the children")
expect(page).to have_content("More schools") expect(page).to have_content("More schools")
expect(page).to have_content("More hospitals") expect(page).to have_content("More hospitals")
visit admin_budget_budget_investments_path(budget_id: @budget.id, tag_name: 'Education') visit admin_budget_budget_investments_path(budget_id: budget.id, tag_name: 'Education')
expect(page).not_to have_content("More hospitals") expect(page).not_to have_content("More hospitals")
expect(page).to have_css(".budget_investment", count: 2) expect(page).to have_css(".budget_investment", count: 2)
@@ -267,8 +270,8 @@ feature 'Admin budget investments' do
end end
scenario "Filtering by tag, display only valuation tags" do scenario "Filtering by tag, display only valuation tags" do
investment1 = create(:budget_investment, budget: @budget, tag_list: 'Education') investment1 = create(:budget_investment, budget: budget, tag_list: 'Education')
investment2 = create(:budget_investment, budget: @budget, tag_list: 'Health') investment2 = create(:budget_investment, budget: budget, tag_list: 'Health')
investment1.set_tag_list_on(:valuation, 'Teachers') investment1.set_tag_list_on(:valuation, 'Teachers')
investment2.set_tag_list_on(:valuation, 'Hospitals') investment2.set_tag_list_on(:valuation, 'Hospitals')
@@ -276,14 +279,14 @@ feature 'Admin budget investments' do
investment1.save investment1.save
investment2.save investment2.save
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"]) expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"])
end end
scenario "Filtering by tag, display only valuation tags of the current budget" do scenario "Filtering by tag, display only valuation tags of the current budget" do
new_budget = create(:budget) new_budget = create(:budget)
investment1 = create(:budget_investment, budget: @budget, tag_list: 'Roads') investment1 = create(:budget_investment, budget: budget, tag_list: 'Roads')
investment2 = create(:budget_investment, budget: new_budget, tag_list: 'Accessibility') investment2 = create(:budget_investment, budget: new_budget, tag_list: 'Accessibility')
investment1.set_tag_list_on(:valuation, 'Roads') investment1.set_tag_list_on(:valuation, 'Roads')
@@ -292,15 +295,15 @@ feature 'Admin budget investments' do
investment1.save investment1.save
investment2.save investment2.save
visit admin_budget_budget_investments_path(budget_id: @budget.id) visit admin_budget_budget_investments_path(budget_id: budget.id)
expect(page).to have_select("tag_name", options: ["All tags", "Roads"]) expect(page).to have_select("tag_name", options: ["All tags", "Roads"])
expect(page).not_to have_select("tag_name", options: ["All tags", "Accessibility"]) expect(page).not_to have_select("tag_name", options: ["All tags", "Accessibility"])
end end
scenario "Limiting by max number of investments per heading", :js do scenario "Limiting by max number of investments per heading", :js do
group_1 = create(:budget_group, budget: @budget) group_1 = create(:budget_group, budget: budget)
group_2 = create(:budget_group, budget: @budget) group_2 = create(:budget_group, budget: budget)
parks = create(:budget_heading, group: group_1) parks = create(:budget_heading, group: group_1)
roads = create(:budget_heading, group: group_2) roads = create(:budget_heading, group: group_2)
streets = create(:budget_heading, group: group_2) streets = create(:budget_heading, group: group_2)
@@ -317,7 +320,7 @@ feature 'Admin budget investments' do
create(:budget_investment, heading: streets, cached_votes_up: n, title: "Street with #{n} supports") create(:budget_investment, heading: streets, cached_votes_up: n, title: "Street with #{n} supports")
end end
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
[2, 4, 90, 100, 200, 300].each do |n| [2, 4, 90, 100, 200, 300].each do |n|
expect(page).to have_link("Park with #{n} supports") expect(page).to have_link("Park with #{n} supports")
@@ -357,72 +360,67 @@ feature 'Admin budget investments' do
context 'Search' do context 'Search' do
background do background do
@budget = create(:budget) create(:budget_investment, title: 'Some investment', budget: budget)
@investment_1 = create(:budget_investment, title: "Some investment", budget: @budget) create(:budget_investment, title: 'Some other investment', budget: budget, id: 999999)
@investment_2 = create(:budget_investment, title: "Some other investment", budget: @budget)
end end
scenario "Search investments by title" do scenario "Search investments by title" do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
expect(page).to have_content(@investment_1.title) expect(page).to have_content('Some investment')
expect(page).to have_content(@investment_2.title) expect(page).to have_content('Some other investment')
fill_in 'title_or_id', with: 'Some investment' fill_in 'title_or_id', with: 'Some investment'
click_button 'Search' click_button 'Search'
expect(page).to have_content(@investment_1.title) expect(page).to have_content('Some investment')
expect(page).not_to have_content(@investment_2.title) expect(page).not_to have_content('Some other investment')
end end
scenario 'Search investments by ID' do scenario 'Search investments by ID' do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
expect(page).to have_content(@investment_1.title) expect(page).to have_content('Some investment')
expect(page).to have_content(@investment_2.title) expect(page).to have_content('Some other investment')
fill_in 'title_or_id', with: @investment_2.id fill_in 'title_or_id', with: 999999
click_button 'Search' click_button 'Search'
expect(page).to have_content(@investment_2.title) expect(page).to have_content('Some other investment')
expect(page).not_to have_content(@investment_1.title) expect(page).not_to have_content('Some investment')
end end
end end
context 'Sorting' do context 'Sorting' do
background do background do
@budget = create(:budget) create(:budget_investment, title: 'B First Investment', cached_votes_up: 50, budget: budget)
@investment_1 = create(:budget_investment, title: "BBBB", cached_votes_up: 50, budget: @budget) create(:budget_investment, title: 'A Second Investment', cached_votes_up: 25, budget: budget)
@investment_2 = create(:budget_investment, title: "AAAA", cached_votes_up: 25, budget: @budget) create(:budget_investment, title: 'C Third Investment', cached_votes_up: 10, budget: budget)
@investment_3 = create(:budget_investment, title: "CCCC", cached_votes_up: 10, budget: @budget)
end end
scenario 'Sort by ID' do scenario 'Sort by ID' do
visit admin_budget_budget_investments_path(@budget, sort_by: 'id') visit admin_budget_budget_investments_path(budget, sort_by: 'id')
expect(@investment_1.title).to appear_before(@investment_2.title) expect('B First Investment').to appear_before('A Second Investment')
expect(@investment_2.title).to appear_before(@investment_3.title) expect('A Second Investment').to appear_before('C Third Investment')
end end
scenario 'Sort by title' do scenario 'Sort by title' do
visit admin_budget_budget_investments_path(@budget, sort_by: 'title') visit admin_budget_budget_investments_path(budget, sort_by: 'title')
expect(@investment_2.title).to appear_before(@investment_1.title) expect('A Second Investment').to appear_before('B First Investment')
expect(@investment_1.title).to appear_before(@investment_3.title) expect('B First Investment').to appear_before('C Third Investment')
end end
scenario 'Sort by supports' do scenario 'Sort by supports' do
visit admin_budget_budget_investments_path(@budget, sort_by: 'supports') visit admin_budget_budget_investments_path(budget, sort_by: 'supports')
expect(@investment_3.title).to appear_before(@investment_2.title) expect('C Third Investment').to appear_before('A Second Investment')
expect(@investment_2.title).to appear_before(@investment_1.title) expect('A Second Investment').to appear_before('B First Investment')
end end
end end
context 'Show' do context 'Show' do
background do
@administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))
end
scenario 'Show the investment details' do scenario 'Show the investment details' do
valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org')) valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org'))
@@ -431,7 +429,7 @@ feature 'Admin budget investments' do
price_first_year: 1000, price_first_year: 1000,
feasibility: "unfeasible", feasibility: "unfeasible",
unfeasibility_explanation: 'It is impossible', unfeasibility_explanation: 'It is impossible',
administrator: @administrator) administrator: administrator)
budget_investment.valuators << valuator budget_investment.valuators << valuator
visit admin_budget_budget_investments_path(budget_investment.budget) visit admin_budget_budget_investments_path(budget_investment.budget)
@@ -461,7 +459,7 @@ feature 'Admin budget investments' do
finished_budget = create(:budget, :finished) finished_budget = create(:budget, :finished)
budget_investment = create(:budget_investment, budget_investment = create(:budget_investment,
budget: finished_budget, budget: finished_budget,
administrator: @administrator) administrator: administrator)
visit admin_budget_budget_investments_path(budget_investment.budget) visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title click_link budget_investment.title
@@ -698,15 +696,15 @@ feature 'Admin budget investments' do
context "Selecting" do context "Selecting" do
let!(:unfeasible_bi) { create(:budget_investment, :unfeasible, budget: @budget, title: "Unfeasible project") } let!(:unfeasible_bi) { create(:budget_investment, :unfeasible, budget: budget, title: "Unfeasible project") }
let!(:feasible_bi) { create(:budget_investment, :feasible, budget: @budget, title: "Feasible project") } let!(:feasible_bi) { create(:budget_investment, :feasible, budget: budget, title: "Feasible project") }
let!(:feasible_vf_bi) { create(:budget_investment, :feasible, :finished, budget: @budget, title: "Feasible, VF project") } let!(:feasible_vf_bi) { create(:budget_investment, :feasible, :finished, budget: budget, title: "Feasible, VF project") }
let!(:selected_bi) { create(:budget_investment, :selected, budget: @budget, title: "Selected project") } let!(:selected_bi) { create(:budget_investment, :selected, budget: budget, title: "Selected project") }
let!(:winner_bi) { create(:budget_investment, :winner, budget: @budget, title: "Winner project") } let!(:winner_bi) { create(:budget_investment, :winner, budget: budget, title: "Winner project") }
let!(:undecided_bi) { create(:budget_investment, :undecided, budget: @budget, title: "Undecided project") } let!(:undecided_bi) { create(:budget_investment, :undecided, budget: budget, title: "Undecided project") }
scenario "Filtering by valuation and selection", :js do scenario "Filtering by valuation and selection", :js do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
within('#filter-subnav') { click_link 'Valuation finished' } within('#filter-subnav') { click_link 'Valuation finished' }
expect(page).not_to have_content(unfeasible_bi.title) expect(page).not_to have_content(unfeasible_bi.title)
@@ -744,7 +742,7 @@ feature 'Admin budget investments' do
end end
scenario "Aggregating results", :js do scenario "Aggregating results", :js do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
click_link 'Advanced filters' click_link 'Advanced filters'
within('#advanced_filters') { find(:css, "#advanced_filters_[value='undecided']").set(true) } within('#advanced_filters') { find(:css, "#advanced_filters_[value='undecided']").set(true) }
@@ -769,7 +767,7 @@ feature 'Admin budget investments' do
end end
scenario "Showing the selection buttons", :js do scenario "Showing the selection buttons", :js do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{unfeasible_bi.id}") do within("#budget_investment_#{unfeasible_bi.id}") do
expect(page).not_to have_link('Select') expect(page).not_to have_link('Select')
@@ -793,7 +791,7 @@ feature 'Admin budget investments' do
end end
scenario "Selecting an investment", :js do scenario "Selecting an investment", :js do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{feasible_vf_bi.id}") do within("#budget_investment_#{feasible_vf_bi.id}") do
click_link('Select') click_link('Select')
@@ -811,7 +809,7 @@ feature 'Admin budget investments' do
end end
scenario "Unselecting an investment", :js do scenario "Unselecting an investment", :js do
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
click_link 'Advanced filters' click_link 'Advanced filters'
within('#advanced_filters') { find(:css, "#advanced_filters_[value='selected']").set(true) } within('#advanced_filters') { find(:css, "#advanced_filters_[value='selected']").set(true) }
click_button 'Filter' click_button 'Filter'
@@ -825,7 +823,7 @@ feature 'Admin budget investments' do
expect(page).not_to have_content(selected_bi.title) expect(page).not_to have_content(selected_bi.title)
expect(page).to have_content('There is 1 investment') expect(page).to have_content('There is 1 investment')
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{selected_bi.id}") do within("#budget_investment_#{selected_bi.id}") do
expect(page).to have_link('Select') expect(page).to have_link('Select')
@@ -837,7 +835,7 @@ feature 'Admin budget investments' do
context "Selecting csv" do context "Selecting csv" do
scenario "Downloading CSV file" do scenario "Downloading CSV file" do
investment = create(:budget_investment, :feasible, budget: @budget, investment = create(:budget_investment, :feasible, budget: budget,
price: 100) price: 100)
valuator = create(:valuator, user: create(:user, username: 'Rachel', valuator = create(:valuator, user: create(:user, username: 'Rachel',
email: 'rachel@val.org')) email: 'rachel@val.org'))
@@ -846,7 +844,7 @@ feature 'Admin budget investments' do
admin = create(:administrator, user: create(:user, username: 'Gema')) admin = create(:administrator, user: create(:user, username: 'Gema'))
investment.update(administrator_id: admin.id) investment.update(administrator_id: admin.id)
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
click_link "Download current selection" click_link "Download current selection"
@@ -871,12 +869,12 @@ feature 'Admin budget investments' do
end end
scenario "Downloading CSV file with applied filter" do scenario "Downloading CSV file with applied filter" do
investment1 = create(:budget_investment, :unfeasible, budget: @budget, investment1 = create(:budget_investment, :unfeasible, budget: budget,
title: 'compatible') title: 'compatible')
investment2 = create(:budget_investment, :finished, budget: @budget, investment2 = create(:budget_investment, :finished, budget: budget,
title: 'finished') title: 'finished')
visit admin_budget_budget_investments_path(@budget) visit admin_budget_budget_investments_path(budget)
within('#filter-subnav') { click_link 'Valuation finished' } within('#filter-subnav') { click_link 'Valuation finished' }
click_link "Download current selection" click_link "Download current selection"

View File

@@ -4,6 +4,7 @@ feature 'Budgets' do
let(:budget) { create(:budget) } let(:budget) { create(:budget) }
let(:level_two_user) { create(:user, :level_two) } let(:level_two_user) { create(:user, :level_two) }
let(:allowed_phase_list) { ['balloting', 'reviewing_ballots', 'finished'] }
context 'Index' do context 'Index' do
@@ -77,6 +78,45 @@ feature 'Budgets' do
expect(page).not_to have_css('div#map') expect(page).not_to have_css('div#map')
end end
end end
scenario 'Show investment links only on balloting or later' do
budget = create(:budget)
group = create(:budget_group, budget: budget)
heading = create(:budget_heading, group: group)
allowed_phase_list.each do |phase|
budget.update(phase: phase)
visit budgets_path
expect(page).to have_content(I18n.t("budgets.index.investment_proyects"))
expect(page).to have_content(I18n.t("budgets.index.unfeasible_investment_proyects"))
expect(page).to have_content(I18n.t("budgets.index.not_selected_investment_proyects"))
end
end
scenario 'Not show investment links earlier of balloting ' do
budget = create(:budget)
group = create(:budget_group, budget: budget)
heading = create(:budget_heading, group: group)
phases_without_links = ['drafting','informing']
not_allowed_phase_list = Budget::Phase::PHASE_KINDS -
phases_without_links -
allowed_phase_list
not_allowed_phase_list.each do |phase|
budget.update(phase: phase)
visit budgets_path
expect(page).not_to have_content(I18n.t("budgets.index.investment_proyects"))
expect(page).to have_content(I18n.t("budgets.index.unfeasible_investment_proyects"))
expect(page).not_to have_content(I18n.t("budgets.index.not_selected_investment_proyects"))
end
end
end end
scenario 'Index shows only published phases' do scenario 'Index shows only published phases' do

View File

@@ -560,16 +560,19 @@ feature 'Budget Investments' do
expect(current_url).to include('page=1') expect(current_url).to include('page=1')
end end
scenario 'Each user as a different and consistent random budget investment order', :js do scenario 'Each user has a different and consistent random budget investment order when random_seed is disctint', :js do
(Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) } (Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
r1 = 1
r2 = 2
in_browser(:one) do in_browser(:one) do
visit budget_investments_path(budget, heading: heading) visit budget_investments_path(budget, heading: heading, random_seed: r1)
@first_user_investments_order = investments_order @first_user_investments_order = investments_order
end end
in_browser(:two) do in_browser(:two) do
visit budget_investments_path(budget, heading: heading) visit budget_investments_path(budget, heading: heading, random_seed: r2)
@second_user_investments_order = investments_order @second_user_investments_order = investments_order
end end
@@ -596,6 +599,23 @@ feature 'Budget Investments' do
end end
end end
scenario 'Each user has a equal and consistent budget investment order when the random_seed is equal', :js do
(Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
in_browser(:one) do
visit budget_investments_path(budget, heading: heading, random_seed: '1')
@first_user_investments_order = investments_order
end
in_browser(:two) do
visit budget_investments_path(budget, heading: heading, random_seed: '1')
@second_user_investments_order = investments_order
end
expect(@first_user_investments_order).to eq(@second_user_investments_order)
end
def investments_order def investments_order
all(".budget-investment h3").collect {|i| i.text } all(".budget-investment h3").collect {|i| i.text }
end end

View File

@@ -137,7 +137,8 @@ feature 'Commenting legislation questions' do
end end
scenario 'Turns links into html links' do scenario 'Turns links into html links' do
create :comment, commentable: legislation_annotation, body: 'Built with http://rubyonrails.org/' legislation_annotation = create :legislation_annotation, author: user
legislation_annotation.comments << create(:comment, body: 'Built with http://rubyonrails.org/')
visit legislation_process_draft_version_annotation_path(legislation_annotation.draft_version.process, visit legislation_process_draft_version_annotation_path(legislation_annotation.draft_version.process,
legislation_annotation.draft_version, legislation_annotation.draft_version,

View File

@@ -518,12 +518,15 @@ feature 'Emails' do
end end
context "Users without email" do context "Users without email" do
scenario "should not receive emails" do
scenario "should not receive emails", :js do
user = create(:user, :verified, email_on_comment: true) user = create(:user, :verified, email_on_comment: true)
proposal = create(:proposal, author: user) proposal = create(:proposal, author: user)
user_commenting = create(:user)
comment = create(:comment, commentable: proposal, user: user_commenting)
user.update(email: nil) user.update(email: nil)
comment_on(proposal)
Mailer.comment(comment).deliver_now
expect { open_last_email }.to raise_error "No email has been sent!" expect { open_last_email }.to raise_error "No email has been sent!"
end end

View File

@@ -51,7 +51,10 @@ feature 'Residence' do
click_link "Validate document" click_link "Validate document"
end end
click_button 'Validate document' within("#new_residence") do
click_button "Validate document"
end
expect(page).to have_content(/\d errors? prevented the verification of this document/) expect(page).to have_content(/\d errors? prevented the verification of this document/)
end end

View File

@@ -114,6 +114,29 @@ feature 'Users' do
end end
end end
scenario "Show alert when user wants to delete a budget investment", :js do
user = create(:user, :level_two)
budget = create(:budget, phase: 'accepting')
budget_investment = create(:budget_investment, author_id: user.id, budget: budget)
login_as(user)
visit user_path(user)
expect(page).to have_link budget_investment.title
within("#budget_investment_#{budget_investment.id}") do
page.driver.browser.dismiss_confirm
click_link 'Delete'
end
expect(page).to have_link budget_investment.title
within("#budget_investment_#{budget_investment.id}") do
page.driver.browser.accept_confirm
click_link 'Delete'
end
expect(page).not_to have_link budget_investment.title
end
end end
feature 'Public activity' do feature 'Public activity' do