There were already some menu items to customization pages under the "Site content" menu. It therefore makes sense to move "Custom images" and "Custom content blocks" (which were previously
located under "Settings") to "Site content" as well.
We applied the Capybara/SpecificMatcher in commit f52a86b46. However,
this rule doesn't convert methods finding <a> tags to methods finding
links because <a> tags only count as links when they've got the `href`
attribute. For instance, in the `xss_spec.rb` file we check what happens
when clicking on an anchor tag because we're testing that the `href`
attribute has been removed and so we can't use `click_link`.
So, basically, we can't enable a rule to automatically detect when we're
using `have_css` instead of `have_link`, but we should still do it
because `have_link` adds an extra check which affects accessibility
since it makes sure the tag has the `href` attribute and so it's
recognizable as a link by screen readers.
Note we're excluding a few files:
* Configuration files that weren't generated by us
* Migration files that weren't generated by us
* The Gemfile, since it includes an important comment that must be on
the same line as the gem declaration
* The Budget::Stats class, since the heading statistics are a mess and
having shorter lines would require a lot of refactoring
We were already using it in most places.
Note that enabling this rule means we've got to change a few lines in
order to follow the LineEndStringConcatenationIndentation rule. In the
link list tests, the easiest way to do so was to use heredoc instead,
which IMHO improves readability over the previous version.
For the HashAlignment rule, we're using the default `key` style (keys
are aligned and values aren't) instead of the `table` style (both keys
and values are aligned) because, even if we used both in the
application, we used the `key` style a lot more. Furthermore, the
`table` style looks strange in places where there are both very long and
very short keys and sometimes we weren't even consistent with the
`table` style, aligning some keys without aligning other keys.
Ideally we could align hashes to "either key or table", so developers
can decide whether keeping the symmetry of the code is worth it in a
case-per-case basis, but Rubocop doesn't allow this option.
Note that in the budgets wizard test we now create district with no
associated geozone, so the text "all city" will appear in the districts
table too, meaning we can't use `within "section", text: "All city" do`
anymore since it would result in an ambiguous match.
Co-Authored-By: Julian Herrero <microweb10@gmail.com>
Co-Authored-By: Javi Martín <javim@elretirao.net>
The test that was not passing sometimes since commit 915999db4 because
we no longer created the budget before visiting the page that loads it.
So now we're forcing its creation with `let!`.
This is consistent with the component for balloting stats. We're about
to change both components, and the changes are easier to follow if
they're similar.
We're also using consistent names in methods.
We're also moving the tests, but we're keeping one system test in order
to test the controller and the navigation to get to this page.
Note we're slightly changing the order of the methods in the component;
the order of the instance variables was `user_`, `vote_`, `vote_`,
`user_`, which was hard to follow.
We don't need groups to create headings since commit 20b1085dc, and
`let!` was used as a substitute for instance variables in commit
91c21b098, but it isn't necessary in this case.
We were getting a warning with Ruby 2.7:
```
ruby/gems/2.7.0/gems/capybara-3.37.1/lib/capybara/session.rb:377:
warning: Using the last argument as keyword parameters is deprecated;
maybe ** should be added to the call
```
On Ruby 3.0, the test failed with `Unable to find fieldset
{:text=>"Draft phase"}` and we were also getting another warning:
```
Locator Hash:{:text=>"Draft phase"} for selector :fieldset must be an
instance of String or Symbol. This will raise an error in a future
version of Capybara
```
Note we could use `acts_as_paranoid` with the `without_default_scope`
option, but we aren't doing so because it isn't possible to consider
deleted records in uniqueness validations with the paranoia gem [1].
I've added tests for these cases so we don't accidentally add
`acts_as_paranoid` in the future.
Also note we're extracting a `RowComponent` because, when
enabling/disabling a tenant, we're also enabling/disabling the link
pointing to its URL, and so we need to update the URL column after the
AJAX call.
[1] See issues 285 and 319 in https://github.com/rubysherpas/paranoia/
In general, we don't use links inside admin tables because we don't know
where the link will point to, and use "view" actions/links instead.
However, in this case, we're showing a URL, so it's perfectly obvious
where the link will point to. And so it makes sense to use the URL as a
link instead of using a "view" action/link.
Some institutions using CONSUL have expressed interest in this feature
since some of their tenants might already have their own domains.
We've considered many options for the user interface to select whether
we're using a subdomain or a domain, like having two separate fields,
using a check box, ... In the end we've chosen radio buttons because
they make it easier to follow a logical sequence: first you decide
whether you're introducing a domain or subdomain, and then you enter it.
We've also considered hiding this option and assuming "if it's got a
dot, it's a domain". However, this wouldn't work with nested subdomains
and it wouldn't work with domains which are simply machine names.
Note that a group of radio buttons (or check boxes) is difficult to
style when the text of the label might expand over more than one line
(as is the case here on small screens); in this case, most solutions
result in the second line of the label appearing immediately under the
radio button, instead of being aligned with the first line of the label.
That's why I've added a container for the input+label combination.
We're using the "tenants" subfolder for consistency with the folder
structure we use in ActiveStorage and because some CONSUL installations
might have folders inside the `data` folder which might conflict with
the folders created by tenants.
Note that the Python scripts have a lot of duplication, meaning we need
to change all of them. I'm not refactoring them because I'm not familiar
enough with these scripts (or with Python, for that matter).
Also note that the scripts folder is still shared by all tenants,
meaning it isn't possible to have different scripts for different
tenants. I'm not sure how this situation should be handled; again, I'm
not familiar enough with this feature.
On my machine, seeding a tenant takes about one second, so skipping this
action when it isn't necessary makes tests creating tenants faster
(although creating a tenant still takes about 3-4 seconds on my
machine).
Note we aren't allowing to delete a tenant because it would delete all
its data, so this action is a very dangerous one. We might need to add a
warning when creating a tenant, indicating the tenant cannot be
destroyed. We can also add an action to delete a tenant which forces the
admin to write the name of the tenant before deleting it and with a big
warning about the danger of this operation.
For now, we're letting administrators of the "main" (default) tenant to
create other tenants. However, we're only allowing to manage tenants
when the multitenancy configuration option is enabled. This way the
interface won't get in the way on single-tenant applications.
We've thought about creating a new role to manage tenants or a new URL
out of the admin area. We aren't doing so for simplicity purposes and
because we want to keep CONSUL working the same way it has for
single-tenant installations, but we might change it in the future.
There's also the fact that by default we create one user with a known
password, and if by default we create a new role and a new user to
handle tenants, the chances of people forgetting to change the password
of one of these users increases dramatically, particularly if they
aren't using multitenancy.
They were added in Rubocop 1.24.0.
Even if we were already applying FileRead everywhere, this is something
we've manually fixed in the past. Another reason to add it is that these
rules are deeply related.
This rule was added in Rubocop 1.18.0, but we didn't add it back then.
Since we're applying it most of the time, we might as well be consistent
and apply it everywhere.
We were rendering the `new` action, but that action doesn't exist.
Before commit ec861ca8e, we were rendering the `edit` action of an
answer, which was confusing as well.
Note that, when adding an invalid document, `@answer.documents` contains
that invalid document (which is not present in the database). Since
we're rendering the index, this new document would appear in the list of
the documents that can be deleted; to avoid that, we're kind of
"reloading" the answer object in the component by finding the record in
the database. We aren't using `@answer.reload` because doing so would
remove the validation errors.
Note that the `create` action doesn't create an image but updates an
answer instead. We're removing the references to `:create` in the
abilities since it isn't used.
In the future we might change the form to add an image to an answer
because it's been broken for ages since it shows all the attached
images.