We can't simply remove the nesting selector in this case since it's
inside a `:not` pseudo-class. Removing the nesting selector would cause
a syntax error.
This file was generated by a different developer who ignored the nesting
rules. Refactoring it has been in our TODO list for years, but we
haven't done it yet.
Since we want stylelint to check that there are no errors after the
changes in a pull request, but we've still got errors in this file,
we're ignoring them for now.
Since now we aren't just using ESLint in the context of a pull request
(with pronto-eslint), we're also adding the `ignorePatterns` option so
it ignores third-party files.
Note we're using ESLint 8 because ESLint 9 doesn't support our
`.eslintrc` configuration file, which we need because it's required by
pronto-eslint. However, when running pronto-eslint, we're using ESLint 6
(I think); this means that now the eslint command we run in development
and the one run by pronto might behave differently, particularly if we
add rules that have been introduced in ESLint 7 or 8. For now, since we
generated the `.eslintrc` file using ESLint 6.0.1, everything works as
expected in both situations.
We're excluding these files because they use `raw` to render content
than only administrators can edit, and we trust administrators not to
provide unsafe HTML. We should definitely sanitize them at some point
but, at the same time, we should also try to keep compatibility in
installations taking advantage of `raw`.
Also note that ERB Lint does not allow customizing the severity of a
linter; if it ever does, we'll use the severity rule instead of
excluding files.
In commit 9329e4b6e, `try` was added because there was a case where this
partial was rendered and the `current_booth` method didn't exist.
However, that's no longer the case since commit d5c7858f6. Since then,
this partial is only rendered in the officing section, where the
`current_booth` method is defined.
So we can use the safe navigation operator instead of `try`.
In commit 35659d441, we started using an <svg> tag instead of an <img>
tag to render avatars. That meant that the `vertical-align: middle` rule
we've got for images was no longer being applied.
So we're adding it back.
The only places where this icon wasn't rendered correctly were "my
account" and the show action in the users controller. The comments were
not affected because we've got a `float: left` rule for the
`comment-avatar svg` selector, which causes the browser to ignore the
value of the `vertical-align` propertly, and the avatars showing author
information were not affected because the `.author-photo` selector
already had a `vertical-align` rule.
We were doing it most of the time, but in some cases we were clicking
the "Sign out" link instead. These actions aren't the same, just like
using `login_as` is not the same as visiting the sign in page and
submitting the form.
Some of these tests failed sometimes because the user wasn't signed in
after using `login_as`. One possible cause could be that we weren't
adding an expectation after clicking the "Sign out" link.
So using `logout` adds consistency, simplifies the code, and might
reduce the chance of these tests failing in the future (although they
might still fail in the future because some of these tests check the
database after a `visit` call).
In this test, we were signing out after confirming a vote, but we
weren't waiting for the request to finish before using the `login_as`
method. Sometimes this test failed with a screenshot showing that the
user wasn't signed in after the `login_as` call, so this might have been
the cause.
We could use the `logout` method instead, but since we don't have any
other tests that click the "Sign out" link from the officing area, we're
leaving it as it was; we might change it to `logout` in the future if
the test keeps failing once in a while.
Note we're also replacing a `visit` call which my guess is was there
because the "Sign out" link wasn't visible due to the notice covering
it. So we're closing the notice instead.
We use caching in our application in two different ways:
1. Rails.cache.fetch in models/controllers/libraries
2. Fragment caching in the views
When using Rails.cache.fetch, we usually set an expiration date or
provide a precise way to invalidate it. If the code changes and the
information stored in the cache is different from what the new code
would return, it's usually not a big deal because the cache will expire
in an hour or a day. Until commit a4461a1a5, the statistics were an
exception to this rule, but that's no longer the case. The actual
exception to this rule are the i18n translations, but the code caching
them is very simple and hasn't changed for more than three years (when
it was written for the first time).
When using fragment caching, on the other hand, Rails automatically
invalidates the cache when the associated _view code_ changes. That is,
if a view contains cache, the view renders a partial, and the partial
changes, the cache is correctly invalidated. The cache isn't invalidated
when the code in helpers, models or controllers change, though, which
the Rails team considers a compromise solution.
However, we've been moving view partials (and even views) to components,
and the cache isn't invalidated when a component changes (it doesn't
matter whether the component Ruby file or the component ERB file
changes). That means that the cache will keep rendering the HTML
generated by the old code.
So, now, we're clearing the cache when upgrading to a new version of
Consul Democracy, as part of the release tasks. That way, institutions
upgrading to a new version don't have to worry about possible issues
with the cache due to the new code not being executed.
I was thinking of adding it to a Capistrano task, but that would mean
that every time people deploy new code, even if it's a hotfix that
doesn't affect the cache at all, the cache would be cleared, which could
be inconvenient. Doing it in a release, that usually changes thousands
of lines of code, sounds like a good compromise.
The upload-artifact action does not support using the same artifact name
in different jobs (or in different matrix scenarios) since version 4,
which we started using in commit acfaada82. That meant that screenshots
were not uploaded correctly when two or more knapsack nodes failed.
Since we upgraded to Rails 7.0 in commmit 8596f1539, the screenshots
started to be stored in `tmp/capybara`, so the step uploading
screenshots wasn't doing anything.
Having a class named `Poll::Question::Answer` and another class named
`Poll::Answer` was so confusing that no developer working on the project
has ever been capable of remembering which is which for more than a few
seconds.
Furthermore, we're planning to add open answers to polls, and we might
add a reference from the `poll_answers` table to the
`poll_question_answers` table to property differentiate between open
answers and closed answers. Having yet another thing named answer would
be more than what our brains can handle (we know it because we did this
once in a prototype).
So we're renaming `Poll::Question::Answer` to `Poll::Question::Option`.
Hopefully that'll make it easier to remember. The name is also (more or
less) consistent with the `Legislation::QuestionOption` class, which is
similar.
We aren't changing the table or columns names for now in order to avoid
possible issues when upgrading (old code running with the new database
tables/columns after running the migrations but before deployment has
finished, for instance). We might do it in the future.
I've tried not to change the internationalization keys either so
existing translations would still be valid. However, since we have to
change the keys in `activerecord.yml` so methods like
`human_attribute_name` keep working, I'm also changing them in places
where similar keys were used (like `poll_question_answer` or
`poll/question/answer`).
Note that it isn't clear whether we should use `option` or
`question_option` in some cases. In order to keep things simple, we're
using `option` where we were using `answer` and `question_option` where
we were using `question_answer`.
Also note we're adding tests for the admin menu component, since at
first I forgot to change the `answers` reference there and all tests
passed.
We've been ignoring what the Bullet gem reports for at least 6 years
(maybe more), but we were still updating the gem and maintaining the
code in `config/environments/` (which caused conflicts every time we run
`rails app:update` to upgrade to a new Rails version). Maintaining it
isn't a huge effort, but it's infinitely bigger than the benefits we get
from it, which are zero.
Adding `includes` everywhere we query for records would be a huge
maintenance effort and would make the code less readable, so I don't
think it's worth it. We might do it occasionally if we detect a
performance bottleneck.
We could also use a gem to automatically avoid the N+1 queries problem,
like Goldiloader [1], ArLazyPreload [2] or JitPreload [3]. Benchmarks
show that the performance improvements obtained by using these gems is
about less than 10% (it depends a lot on the page being loaded, though),
which IMHO doesn't justify adding yet another gem that patches
ActiveRecord and that could be incompatible with other gems doing so.
There are a couple of open pull requests (at the time of writing,
they've been open for about two years) in the Rails repository [4][5] to
automatically avoid N+1 queries as well. For now, we'll hope something
similar is integrated in Rails itself in the future.
[1] https://github.com/salsify/goldiloader
[2] https://github.com/DmitryTsepelev/ar_lazy_preload
[3] https://github.com/clio/jit_preloader/
[4] Pull request 45231 in https://github.com/rails/rails/
[5] Pull request 45413 in https://github.com/rails/rails/
Just like we do every else (sometimes even on that very same file), we
use the method instead of the instance variable.
We're doing this change now because we're about to modify one of these
files (the poll question answers documents index component).
We added the code indicating the table in commit 673ec075e because back
then we had a `title` column in both the `poll_question_answers` table
and the `poll_question_answer_translations` table.
Since that's no longer the case since commit 7a7877656, we can simplify
the code.
Not sure about when we stopped needing them, but all usages of
require_dependency definitely become obsolete after we started using
Zeitwerk in commit 5f24ee912.
We're also going to rename `Poll::Question::Answer` to
`Poll::Question::Option`, so the conflict of having two `Answer`
classes, that made us add this code in the first place, will not even
exist.
This way we remove a bit of duplication.
These changes also affect the way geozones are rendered in a couple of
minor ways, making them more consistent:
* No empty list of geozones is rendered when there are no geozones
(before these changes, an empty list was rendered in the index action
but not in the show action)
* The text clarifying the geozone restriction is always shown (before
these changes, it was shown in the index action but not in the show
action)
We've added tests for these cases.
The text wasn't gramatically correct in English, since it had
the verb before the subject.
Since I'm not a native English speaker, I'm not sure about the
correct way to mention the Census part. I'm using "residents
in" since it sounds OK to me, but I might be wrong.
Many developers run `bin/rspec` and then are (reasonably) confused when
running the tests takes too long.
So we're clarifying that running the whole test suite should be done
using a CI, and only relevant tests should be run while developing on
your machine.
When this code was added, in commit 1a20a3ce4, we had no validation
rules checking the presence of the start and end dates of a poll. Now we
do, so we don't have to check this condition in the view.
The rows in these tables were using the styles from the `.poll`
selector, and the `position: relative` property defined there caused the
inner borders to disappear in some browsers (like Firefox).
So we're adding the `public` class to the selector; this way, it doesn't
affect elements in the admin section.
Even though it's only necessary to add the `.public` prefix to the
`.poll` selector in one place in order to fix this issue, we're doing it
everywhere for consistency.
We were using a redundant `elsif` instead of an `else`. We were also
using a negative condition in the main `if`, which made the code a bit
harder to read.
Since we usually use `current_user` instead of `user_signed_in?`, we're
also changing that for consistency.Extract component to render the status of a poll
This is consistent with the way we've got partials to render debates,
proposals and legislation processes on their index pages.
Note that, while adding the tests for the status icon, we're keeping one
system test because it also tests the process of voting. We're adding a
new, similar component test, where the voter is created in the database,
so all possible statuses are tested in the component.
With this parameter, Vimeo no longer uses cookies that identifies users
browsing our site.
They do still store some cookies, though; quoting from Vimeo player
parameters overview:
> When DNT is enabled, Vimeo deploys one essential cookie via the
> embeddable player:
> The __cf_bm cookie, which is part of Cloudflare's Bot Management
> service and helps mitigate risk associated with spam and bot traffic.
Not sure whether this counts as essential cookies in our case; they're
essential for Vimeo, but for us, they're third-party cookies, after all.
[1] https://help.vimeo.com/hc/en-us/articles/12426260232977-Player-parameters-overview