As far as possible I think the code is clearer if we use CRUD actions
rather than custom actions. This will make it easier to add the action
to remove votes in the next commit.
Note that we are adding this line as we need to validate it that a vote
can be created on a comment by the current user:
```authorize! :create, Vote.new(voter: current_user, votable: @comment)```
We have done it this way and not with the following code as you might
expect, as this way two votes are created instead of one.
```load_and_authorize_resource through: :comment, through_association: :votes_for```
This line tries to load the resource @comment and through the association
"votes_for" it tries to create a new vote associated to that debate.
Therefore a vote is created when trying to authorise the resource and
then another one in the create action, when calling @comment.vote.
As far as possible I think the code is clearer if we use CRUD actions
rather than custom actions. This will make it easier to add the action
to remove votes in the next commit.
Note that we are adding this line as we need to validate it that a vote
can be created on a debate by the current user:
```authorize! :create, Vote.new(voter: current_user, votable: @debate)```
We have done it this way and not with the following code as you might
expect, as this way two votes are created instead of one.
```load_and_authorize_resource through: :debate, through_association: :votes_for```
This line tries to load the resource @debate and through the association
"votes_for" it tries to create a new vote associated to that debate.
Therefore a vote is created when trying to authorise the resource and
then another one in the create action, when calling @debate.vote_by (which
is called by @debate.register_vote).
We originally added the `cached_votes_up > 0` in commit 4ce95e273
because back then `cached_votes_up` was used in the denominator. That's
no longer the case, and it doesn't make sense to mark a debate with 1
vote and 10 flags as conflictive but not doing it when the debate has no
votes and 1000 flags.
We're fixing the bug right now because we're about to change the
affected line in order to apply a new rubocop rule.
This rule was added in rubocop-rspec 2.11.0. We aren't adding it
because, out of 3 offenses, this cop can only correct 2 automatically.
Not sure how to correct the other one since it uses `.and change`.
This rule was added in rubocop-rspec 2.9.0.
We were using `be_nil` 50% of the time, and `be nil` the rest of the
time. No strong preference for either one, but IMHO we don't lose
anything be being consistent.
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
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.
We were already applying these rules in most cases.
Note we aren't enabling the `MultilineArrayLineBreaks` rule because
we've got places with many elements whire it isn't clear whether
having one element per line would make the code more readable.
We were using two different sets of extensions but, since the markdown
code is always written by administrators, IMHO it makes sense to be
consistent and always render markdown code the same way.
* Add Tables option to Redcarpet in Legislation draft
* Allow table tags in Admin Legislation Sanitizer
* Add Test to render markdown tables in Legislation drafts
* Add Test for Admin Legislation Sanitizer
We include test for image, table and h1 to h6 tags and additional tests to strengthen the allowed and disallowed parameters
* Add Table from markdown test in System and Factories
* Add test to render tables for admin user
* Remove comment line about Redcarpet options
* Edit custom css for legislation draft table to make it responsive
This methods performs much better when we need to load a lot of
globalized models translations and returns the best fallback translation
for the current language.
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>
These tests were failing with Ruby 3.0 because we were getting an error
when loading the `translations` association of the dummy class:
```
NameError:
uninitialized constant
DummyBanner::#<Class:0x000055630e4dccd8>::Translation
```
Specifying the `class_name` of the `translations` association solves the
issue.
It has been detected that for the :pt-BR, :zh-CN and :zh-TW locales,
the translate button was being displayed, but when requesting the
translation, the remote translation validation failed due to:
'''
validates :locale, inclusion: { in: ->(_) {
RemoteTranslations::Microsoft::AvailableLocales.available_locales }}
'''
That available_locales method did not contemplate these 3 languages
in the format used by the application.
To solve this problem the api response is mapped to return all
locales in the format expected by the application.
Add remote translation model test to ensure that a remote translation
is valid when its locale is pt-BR.
Co-Authored-By: Javi Martín <35156+javierm@users.noreply.github.com>
When accessing the valuation area, we were only displaying the
investments directly assigned to the current valuator, but we weren't
displaying the investments assigned to that valuator's group.
Using the `assigned_investments_ids` method, which takes the valuator
group into account, solves the issue.
We've also found an issue on our development machines: since we don't
have a unique index per `investment_id` and `valuator_id` in the
`budget_valuator_assignments` table, we've found duplicate records on
this table. When that happened, we were displaying the same investment
several times.
Since now we no longer join this table in the query returning the
investment, this issue is also solved, and we're adding a test for it.
We can now remove the call to the `distinct` method when calculating the
number of investments per heading.
To get the heading where a user voted, we were relying on the
`balloted_heading_id` field.
Our guess is this was done so the total number of users is the same as
the sum of users who voted on a heading. That is, if 2000 people voted
just on the "All city" heading, 1000 voted just on the "North district"
heading, and 500 people voted on both, instead of showing "3500 people
voted in total, 2500 voted in all city, 1500 voted in north district",
we show something like "3500 people voted in total, 2250 voted in all
city, and 1250 voted in north district".
However, this approach has some disadvantages.
The first disadvantage is, the stats aren't correct. In the case above,
2500 voted on the "All city heading", so the statistics for this heading
don't show reality.
The second one is we weren't considering the last heading where users
voted inside the budget being displayed, but the last heading where
users voted, period. That means that, if all the people above voted on a
later budget, the stats for the budget above would become "3500 people
voted in total, 0 voted in all city, and 0 voted in north district".
That also means we were including headings from previous budgets in the
statistics for more recent budgets when people hadn't voted on the
recent ones.
So we're removing the `balloted_heading_id` since its data is lost once
people vote on a new budget. And, in order to show the right stats and
simplify the code, we're no longer trying to add votes just to one
heading when users vote on several headings.
Co-Authored-By: Julian Nicolas Herrero <microweb10@gmail.com>
It was added in rubocop-performance 1.13.0. We were already applying it
in most places.
We aren't adding it for performance reasons but in order to make the
code more consistent.
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/
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.