Commit Graph

9759 Commits

Author SHA1 Message Date
Javi Martín
75b03791b1 Extract component to render an execution
Note that, in order to be consistent with the name of the component,
we're renaming the `budget-execution` class to
`budget-executions-investment`.
2024-11-07 14:21:55 +01:00
Javi Martín
764d22f57a Use flex instead of an equalizer in executions
Just like we did in commits like f2e32b44b, a8537f7e1 and be9fc2265,
we're replacing a buggy JavaScript solution with one using just CSS.

Besides, we've had a failure in our test suite caused by an image not
being displayed on the page, with the message:

```
Failures:

1) Executions Images renders last milestone's image if investment has multiple milestones
   with images associated
   Failure/Error: expect(page).to have_css("img[alt='Second image']")
     expected to find visible css "img[alt='Second image']" but there were no matches.
     Also found "", which matched the selector but not all filters.

   # ./spec/system/budgets/executions_spec.rb:135:in `block (3 levels) in <top (required)>'
```

The text "matched the selector but not all filters" means that the
element was present on the page but wasn't visible. One possible cause
is that the equalizer was adjusting the height of the element containing
the image before the image was loaded.

Note that, after these changes, all investments on the same row will
have the same height but, unlike with Foundation's equalizer,
investments on different rows might have different heights.
2024-11-07 14:21:55 +01:00
Javi Martín
1e063e88c2 Extract component to render heading executions
Note we're adding the `budgets-executions-heading` HTML class, which is
consistent to what we do in other components.
2024-11-07 14:21:55 +01:00
Javi Martín
e3a2a42534 Move investments executions view to a component
Note that we're changing the component so it uses `polymorphic_path`;
that way we don't have to pass the `@budget` variable to the component.
We could also use `budget_investment_path investment.budget, investment`
instead.
2024-11-07 14:21:55 +01:00
Javi Martín
1057f41d61 Fix indentation in investments executions partial
We accidentally introduced the wrong indentation in commit 8376efce3.
2024-11-07 14:21:55 +01:00
Javi Martín
6e5ef9795e Track ahoy visits on the server side
In commit 96ae69fe9, we stopped using cookies to track Ahoy visits and
started using a combination of the IP and the browser agent instead.

However, since we're still using the legacy logic from Ahoy 1.x to track
visits (which we had to add in commit b5220effd), this way of tracking
visits doesn't work and counts every page visited by a user as an
independent visit.

Maybe we could migrate existing data, which uses the `visitor_id` column
so it uses the new `visit_token` and `visitor_token` columns, but
there's no mention in the Ahoy documentation regarding how to do so.

While deciding what to do about this, we found something interesting.

For two years, we've been seeing random failures in the
`system/admin/tenants_spec.rb` tests, with messages like:

```
1) Tenants Create Tenant with subdomain
     Failure/Error:
       raise TenantNotFound, <<~EXCEPTION_MESSAGE
         Could not set search path to schemas, they may be invalid:
           "#{tenant}" #{full_search_path}.
         Original error: #{exception.class}: #{exception}
       EXCEPTION_MESSAGE

     Apartment::TenantNotFound:
       Could not set search path to schemas, they may be invalid:
         "earth" "public", "shared_extensions".
       Original error:
         ActiveRecord::StatementInvalid: Could not find schema earth
```

And we've found one of the causes: the AJAX requests done by Ahoy to
track visits. Sometimes a test that creates or updates a tenant finishes
but the Ahoy AJAX request to, say, `earth.lvh.me/ahoy/visits`, is
handled by the next test, when the `earth` schema no longer exists, thus
raising an `Apartment::TenantNotFound` exception.

So by disabling these AJAX requests and tracking the visits in the
server instead, we're killing two birds in one stone: we're fixing the
bug regarding the visits count and we're reducing the flakiness in our
test suite. It looks like we're also removing the "phantom ahoy cookie"
we were getting since the mentioned commit b5220effd: an ahoy cookie was
quickly set and unset in the browser.

Note that, even though we aren't migrating any data, we're still adding
the new fields, because some tests started to fail because, when
tracking visits in the server without cookies, Ahoy expects the Visit
model to have a `visit_token` field.
2024-11-07 12:04:46 +01:00
Javi Martín
45851c74bd Include voter initialization in officing voters lock
For reasons that might or might not affect production installations, the
test checking simultaneous requests to create poll voters in the
officing voters controller wasn't behaving as expected.

The expected behavior, since commit 9a8bfac5b, is that the second
request reaching the `with_lock` part of the code waits for the first
request to finish and so this second request raises an
`ActiveRecord::RecordInvalid` exception when trying to save a voter with
the same poll and the same user as the first one.

However, 95% of the time that wasn't the case. Instead, when entering
the `@user.with_lock` block, the second request would replace its
`@voter` object with the `@voter` object saved in the same request, so
the second call to `save!` would succeed as it would simply update the
existing record.

This is a behavior that we could accept if it were consistent and
happened 100% of the time, but that isn't the case. 5% of the time, we
do get the `ActiveRecord::RecordInvalid` exception. So 5% of the time we
got a failure in the test:

```
  1) Officing::VotersController POST create does not create two records
     with two simultaneous requests
     Failure/Error: @user.with_lock { @voter.save! }

     ActiveRecord::RecordInvalid:
       Validation failed: User User has already voted
     # ./app/controllers/officing/voters_controller.rb:25:in `block in create'
     # ./app/controllers/officing/voters_controller.rb:25:in `create'
     # ./app/controllers/application_controller.rb:50:in `switch_locale'
     # ./spec/controllers/officing/voters_controller_spec.rb:15:in `block (5 levels) in <top (required)>'
```

So we're changing the `with_lock` block so it includes the
initialization of the object. This way, we get the
`ActiveRecord::RecordInvalid` exception 100% of the time.

Note that in commit 9a8bfac5b we also rescued the
`ActionDispatch::IllegalStateError` exceptions. I'm not why we were
getting those exceptions when running the tests, and I'm not sure
whether we keep getting after these changes, but it doesn't really
matter. The reason is that in Consul Democracy 2.3.0 we're going to add
a unique index to the `poll_voters` table, which (according to the tests
done in the past) will make both the `@user.lock` block and rescuing the
`ActionDispatch::IllegalStateError` unnecessary.

So, in other words, these changes will never make it to production
because this part of the code will be changed again before releasing
version 2.3.0.
2024-11-07 11:15:15 +01:00
Sebastia
d242170771 Merge pull request #5057 from consuldemocracy/only_manage_tenants
Add an option to enable the "Multitenancy management mode"
2024-11-06 14:59:50 +01:00
taitus
2938ced41c Add collection_field helper to BaseObject
Add a helper method in BaseObject to define fields with `connection_type`,
reducing code duplication and giving more context about the type of fields.
2024-11-06 13:51:28 +01:00
taitus
a426537b4c Add helper method to define collection and object by id fields in QueryType
- Introduce `collection_and_object_by_id_fields` in QueryType to avoid duplication.
2024-11-06 13:51:28 +01:00
taitus
d3b253dfc7 Add object_by_id_field helper to BaseObject and replace argument definitions
- Created `object_by_id_field` method in `BaseObject` to simplify the declaration of fields
with an `id` argument.
- Replaced all instances of `field ... do` blocks with `object_by_id_field` where fields require
an `id` argument across multiple types.
2024-11-06 13:51:28 +01:00
Sebastia
1c684c3daf Merge pull request #5752 from consuldemocracy/dependabot/bundler/sassc-embedded-1.80.1
Bump sassc-embedded from 1.70.1 to 1.80.1
2024-11-06 13:16:42 +01:00
dependabot[bot]
64bcedc8b2 Bump sassc-embedded from 1.70.1 to 1.80.1
Note: Since we update to 1.80.1 deprecation warnings are appear when execute the assets:precompile command.
In order to silence this deprecation, we add silence_deprecation option in sass.rb initializer.

The code has also been updated to remove the deprecation warnings that appeared related to the function
darken(), lighten() and "Using / for division" instead of the function calc().

Bumps [sassc-embedded](https://github.com/sass-contrib/sassc-embedded-shim-ruby) from 1.70.1 to 1.80.1.
- [Commits](https://github.com/sass-contrib/sassc-embedded-shim-ruby/compare/v1.70.1...v1.80.1)

---
updated-dependencies:
- dependency-name: sassc-embedded
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-06 13:01:58 +01:00
taitus
93b35fcecc Redirect root path requests to the tenants administration
When the `multitenancy_management_mode` is enabled.

In order to avoid infinite redirects when regular users try to access
the admin section, we're redirecting to the account page in this case.
Otherwise, the admin section would redirect to the root path, which
would redirect to the admin section, which would redirect to the root
path, and so on.
2024-11-06 11:17:58 +01:00
taitus
a5911f5c6a Modify admin layout to only manage tenants and admins
We only want to render the account link and login items in the header.
And we want only render the Multitenancy and Administrators sections in
the admin sidebar.

We include the administrators management so it's possible to give
permissions to other users to manage tenants.

In order to restrict access to other sections by typing the URL or
following a link, we're only enabling the rest of the routes when we
aren't in the multitenancy management mode.
2024-11-06 11:17:53 +01:00
taitus
1e6901ec34 Add render method to notification item component 2024-11-06 11:07:00 +01:00
CoslaJohn
424cedc0c8 Restrict access to admin functions by IP
There are many possible ways to implement this feature:

* Adding a custom middleware
* Using rack-attack with a blocklist
* Using routes constraints

We're choosing to use a controller concern with a redirect because it's
what we do to handle unauthorized cancancan exceptions.
2024-10-30 15:59:50 +01:00
Javi Martín
07202fea10 Add and apply Style/RedundantBegin rubocop rule
We're about to add code which might fall into the `RedundantBegin`
category, so we're adding the rule in order to prevent that.
2024-10-30 15:57:44 +01:00
Nicolas Fourre
a81fba71f0 fix(social-login): social button fill space when option are turn off 2024-10-28 21:25:22 +01:00
Javi Martín
3931b43b87 Move omniauth form partial to a component
This way we simplify the view a little bit and replace some slow system
tests with faster component tests.
2024-10-28 21:23:56 +01:00
Javi Martín
fc5103881d Use a switch to toggle visibility to valuators
Using a checkbox wasn't very intuitive because checkboxes are
checked/unchecked when clicked on even if there's an error in the
request. Usually, when checkboxes appear on a form, they don't send any
information to the server unless we click a button to send the form.

So we're using a switch instead of a checkbox, like we did to
enable/disable phases in commit 46d8bc4f0.

Note that, since we've got two switches that match the default
`dom_id(record) .toggle-switch` selector, we need to find a way to
differentiate them. We're adding the `form_class` option for that.

Also note that we're now using a separate action and removing the
JavaScript in the `update` action which assumed that AJAX requests to
this action were always related to updating the `visible_to_valuators`
attribute.
2024-10-28 13:41:55 +01:00
Javi Martín
00d7299e9e Extract component for visible to valuators toggling 2024-10-28 13:41:55 +01:00
Javi Martín
958c13061f Fix duplicate HTML visible to valuator IDs 2024-10-28 13:41:55 +01:00
Javi Martín
173b1bb07c Make it possible to select investments without JavaScript 2024-10-28 13:41:55 +01:00
Javi Martín
54a48d63e1 Use separate actions to select/deselect investments
This is consistent to what we usually do. Also, we're applying the same
criteria mentioned in commit 72704d776:

> We're also making these actions idempotent, so sending many requests
> to the same action will get the same result, which wasn't the case
> with the `toggle` action. Although it's a low probability case, the
> `toggle` action could result in [selecting an investment] when trying
> to [deselect] it if someone else has [deselected it] it between the
> time the page loaded and the time the admin clicked on the
> "[Selected]" button.
2024-10-28 13:41:50 +01:00
Javi Martín
463112c2ea Use a switch to toggle investment selection
Just like it happened with proposals, the button to select/deselect an
investment wasn't very intuitive; for example, it wasn't obvious that
pressing a button saying "selected" would deselect the investment.

So we're using a switch control, like we do to enable/disable features
since commit fabe97e50.

Note that we're making the text of the switch smaller than in other
places because the text in the investments table it is also smaller
(we're using `font-size: inherit` for that purpose). That made the
button look weird because we were using rems instead of ems for the
width of the button, so we're adjusting that as well.

Also note we're changing the width of the switch to `6em` instead of
`6.25em` (which would be 100px if 1em is 16px). We're doing so because
we used 100 for the minimum width because it's a round number, so
now we're using another round number.
2024-10-28 13:40:27 +01:00
Javi Martín
f72daff71f Simplify JavaScript to toggle investment selection
We don't need to replace the whole row, since the changes only affect
the button. Therefore, we don't need to depend on an `inserted` event to
decide which columns to render in that row.
2024-10-28 13:39:49 +01:00
Javi Martín
9e5566cee4 Use a button to toggle investment selection
As mentioned in commit 5311daadf, using buttons for non-GET requests has
several advantages over using links.
2024-10-28 13:39:49 +01:00
Javi Martín
cf0d8258ed Use abilities to allow toggling investment selection
We were checking it in the view, meaning that it was possible to toggle
the selection by sending a custom request even when the investment
wasn't feasible.
2024-10-28 13:39:49 +01:00
Javi Martín
95f36ed52f Simplify code to toggle investment selection
This way it'll be easier to change the link/button used to toggle the
selection.

Note that the conditions in the view seem to be different because we no
longer include the `selected?` condition when rendering the link/button.
However, an investment can only be selected if it's feasible and its
valuation is finished, so writing something like this would have been
redundant:

```ruby
can?(:toggle_selection, investment) &&
  (selected? || investment.feasible? && investment.valuation_finished?)
```

The reason why the previous code was using the `selected?` condition was
to check whether to render the link/button to select or to deselect an
investment. We're now doing that in the Ruby part of the component.
2024-10-28 13:39:42 +01:00
Javi Martín
c78494c100 Extract method to get toggle selection path
This way we simplify the view code.

Since now we only use the `budget` method in one place, we're removing
it.
2024-10-28 13:37:56 +01:00
Javi Martín
fde24870bc Extract component for investment toggle selection
This way it'll be easier to refactor it.
2024-10-28 13:31:34 +01:00
Javi Martín
b9c3e75930 Fix duplicate HTML IDs in investments selection
Since this cell is shown once per row, there were multiple rows with the
same HTML ID on the page.
2024-10-25 17:24:32 +02:00
Javi Martín
73166e164b Simplify HTML for an investment row
Since we define the `data-field` element, we can style each element
individually with CSS.

I'm not sure whether these styles make sense, though. For instance, why
is "Supports" aligned to the center, since it's a number? For now, we're
leaving it as it was.
2024-10-25 17:24:32 +02:00
Javi Martín
607dabbc8a Move admin investments partial to a component
This way it'll be easier to organize the code related to it.
2024-10-25 17:24:32 +02:00
Javi Martín
e4df6426c2 Remove unused JavaScript view in investments admin
This code isn't used since commit c9f31b8e1.

Since we no longer depend on the content of the `#investments` element
being in a separate partial, we're also moving this element to the
partial itself and adding an HTML class to it, like we usually do.

We're also removing the code that loads all the investments in the
`toggle_selection` action, which wasn't needed since commit 3278b3572,
when we stopped rendering all the investments in this action.
2024-10-25 17:24:29 +02:00
Javi Martín
9330cdb304 Extract methods in investment row component
This way we simplify the code a little bit.
2024-10-25 17:19:52 +02:00
Javi Martín
bb42809168 Move investment partial to a component
This way we'll be able to simplify it a little bit.

Note that the original partial didn't include the whole row and only
the cells. Since, most of the time, we include the whole row in
partials, we're slightly modifying the component.
2024-10-25 17:19:42 +02:00
Javi Martín
02b6302f25 Focus the proposal selection switch after pressing it
Since this button is replaced by a new element in an AJAX call, nothing
was focused after pressing it.

So we're reusing the code we used to enable/disable budget phases, which
already dealt with this issue.
2024-10-25 17:15:40 +02:00
Javi Martín
2acaa14705 Make it possible to select proposals without JavaScript
This way, when JavaScript hasn't loaded (for whatever reason),
administrators can still use this functionality.
2024-10-25 17:12:47 +02:00
Javi Martín
4a2fc50c76 Use separate actions to select/deselect proposals
This is consistent to what we usually do. Also, we're applying the same
criteria mentioned in commit 72704d776:

> We're also making these actions idempotent, so sending many requests
> to the same action will get the same result, which wasn't the case
> with the `toggle` action. Although it's a low probability case, the
> `toggle` action could result in [selecting a proposal] when trying to
> [deselect] it if someone else has [deselected it] it between the time
> the page loaded and the time the admin clicked on the "[Selected]"
> button.
2024-10-25 17:12:47 +02:00
Javi Martín
fec44c146c Use a switch to toggle proposal selection
The button to select/deselect a proposal wasn't very intuitive; for
example, it wasn't obvious that pressing a button saying "selected"
would deselect the proposal.

So we're using a switch control, like we do to enable/disable features
since commit fabe97e50.
2024-10-25 17:12:44 +02:00
Javi Martín
b127bd2f51 Use a button to toggle proposal selection
As mentioned in commit 5311daadf, using buttons for non-GET requests has
several advantages over using links.
2024-10-25 17:10:14 +02:00
Javi Martín
43b6ab00e3 Simplify method to get the toggle selection path 2024-10-25 16:40:34 +02:00
Javi Martín
3febe3f0cc Extract methods in toggle selection component 2024-10-25 16:40:34 +02:00
Javi Martín
3cebce9a29 Extract link to toggle selection to a component 2024-10-25 16:40:32 +02:00
taitus
64e9d28479 Release version 2.2.2 2024-10-15 16:11:09 +02:00
Javi Martín
b870e29170 Disable turbolinks previews in the test environment
When clicking the browser's back button, browsers usually don't reload
the page but show a cached version of the page.

Turbolinks takes this one step further. When clicking on a link to a
page that's already cached, turbolinks displays the cached version of
the page and then it reloads it.

I don't really like this behavior but, since it affects the whole
application and we're about to release a patch version :), for now we're
keeping it this way in the development and production environments.

In the test environment, however, we're disabling these previews because
they might lead to requests leaking between tests.

For example, a test that visits the investments index, then goes to
"check my votes", then clicks on "Go back" and finishes by checking some
content on this page will result in those checks being done against the
cached version of the page. If these checks pass before turbolinks
reloads the page, the "Go back" request will finish during the test that
runs immediately after this one, resulting in unpredictable results.

Disabling the previews solves the issue.
2024-10-15 14:44:26 +02:00
taitus
93189d3ecd Allow use embedded_video_component in legislation proposals
Since the PR "Do not use third-party cookies in embedded videos #5548", the logic from
"embed_videos_helper" was extracted to the "embedded_video_component" and the
"videoable" model concern.

However, during this refactor, the "regex" method, which uses record.class:: to handle
video embeds, was left inaccessible for Legislation Proposals.

This commit fixes the issue by including the concern in the Legislation Proposal model.
2024-10-14 15:24:29 +02:00
Sebastia
d3a039040c Merge pull request #5722 from consuldemocracy/dependabot/bundler/rubocop-rails-2.26.2
Bump rubocop-rails from 2.25.1 to 2.26.2
2024-10-10 15:03:08 +02:00