Commit Graph

397 Commits

Author SHA1 Message Date
Javi Martín
a6d470ded6 Setup the database before a visit in investments test
This way we avoid possible issues that might be caused by calling the
`update!` method after the browser had already started.
2025-04-01 14:53:27 +02:00
Javi Martín
1b8a079727 Don't reload records in system tests
As mentioned in commits like a586ba806, a7664ad81, 006128da5, b41fbfa52
and c480cdd91, accessing the database after starting the browser with
the `visit` method sometimes results in database corruption and failing
tests on our CI due to the process running the test accessing the
database after the process running the browser has started.

For example, one of these tests has recently failed on our CI:

```
3) Users Create a level 3 user with email from scratch
   Failure/Error: expect(user.reload).to be_confirmed
     expected `#<User id: 2060, email: "pepe@gmail.com", created_at:
     "2025-03-12 19:51:03.688867000 +0100", updated_...d_debates: true,
     recommended_proposals: true, subscriptions_token: nil,
     registering_from_web: false>.confirmed?` to be truthy, got false
```

IMHO this is also a bad practice for system tests, since these tests
should be checking what users experience.

So we're modifying the tests to check the results of users interaction
from the point of view of the users. For example, instead of checking
that a user is now level 3 verified in the database, we're checking that
the user interface states that the user is level 3 verified.

Note we're adding an offset when editing the map marker by clicking on
`map-location` with `.click(x: 30, y: 30)`. This way we make sure that
both the latitude and longitude change from the original values; we used
to clicking in the middle (no offset), which didn't change the longitude
and changed the latitude just by coincidence.

Also note we aren't changing tests with the `:no_js` tag, since these
tests don't run a real browser in a separate process. In the future, we
should also change most of these tests so they don't access the database
and they use a real browser.
2025-04-01 14:53:26 +02:00
Javi Martín
a28967817e Split some system tests checking the database
As mentioned in commits like a586ba806, a7664ad81, 006128da5, b41fbfa52
and c480cdd91, accessing the database after starting the browser with
the `visit` method sometimes results in database corruption and failing
tests on our CI due to the process running the test accessing the
database after the process running the browser has started.

IMHO this is also a bad practice for system tests, since these tests
should be checking what users experience.

In these cases, however, I haven't been able to test the user
experience. For example, it looks like failed census calls for
unregistered users aren't displayed anywhere and can only be accessed by
manually checking the database. Similarly, there's no interface showing
that all the options from a poll have been deleted (which makes sense,
since we only display options in the context of their poll) or a place
showing the responsible name for a proposal.

So we're splitting the tests in two, with the controller test running
the database checks.
2025-04-01 14:53:26 +02:00
Javi Martín
71742f72b0 Remove obsolete "let" blocks in tests setup
These blocks are no longer used:

* `allowed_phase_list` isn't used since commit 04605d5d5
* `level_two_user` isn't used since commit 26d14cbd0
* `heading` in `budgets/stats_spec` was added in c2457e36a but never
  used
* `translatable` was added in 44d137a4c but it's overwritten in all the
  contexts.
* `annotation` isn't used since commit 79d00e7b9
* `admin` in `tags/budget_investments_spec` isn't used since 8a2e15980
* `budget` in `welcome_spec` was added in 87be6f302 but never used
2025-03-26 16:42:04 +01:00
Javi Martín
2239b8fdca Remove obsolete questions index in the admin area
We removed the link to this page in commit 83e8d6035 because poll
questions don't really make sense without a poll.

However, this page also contained information about successful
proposals, which might be interesting so administrators don't have to
navigate to the public area in order to find and create questions based
on successful proposals.

So we're keeping the part about successful proposals and linking it from
the proposals part of the admin area.

Note we're using translation keys like `successful_proposals_tab`, which
don't make sense anymore, for the successful proposals. We're doing so
because we've already got translations for these keys and, if we renamed
them, we'd lose the existing translations and our translators would have
to add them again.

Also note we're changing one poll question test a little bit so we
create the question from a successful proposal using the new page. There
are other tests checking how to create a question from the
admin/proposals#show action and other tests checking what happens when
accessing a successful proposal in the admin section, so we don't lose
any test coverage by changing an existing test instead of adding a new
one.

Finally, note that we've removing the `search` method in poll question
because we no longer use it. This currently makes the
`author_visible_name` database column useless; we aren't removing it
right now because we don't want to risk a possible data loss in a patch
release (we're about to release version 2.3.1), but we might remove it
in the future.
2025-03-26 16:42:04 +01:00
Javi Martín
1dcfc38e41 Add missing expectations after refreshing the page
This way we know for sure the page has finished refreshing.

Note that, for now, we aren't adding a check after every call to the
`refresh` method because sometimes the page remains identical after
refreshing. Not sure what we should do in these cases.
2025-03-26 16:27:08 +01:00
Javi Martín
f63be041c1 Add missing expectations to confirm the page has changed
After a `visit`, we were checking for content or filling in fields that
were already there before the `visit`, so we weren't 100% sure that the
request had finished before the test continued.

In the case of the verification tests, we were clicking the submit
buttons over and over without and then checking or interacting with
elements that were already there. Even though the button was disabled
between requests, meaning there wouldn't be simultaneous requests, it
was possible to interact with a form field before waiting for the
request to finish.

Some of these tests have recently failed on our CI, and it might be
because of that:

```
1) Admin budgets Edit Changing name for current locale will update the
   slug if budget is in draft phase
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

1) Budgets creation wizard Creation of a multiple-headings budget by
   steps
   Failure/Error: expect(page).to have_content "Heading created
   successfully!"

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

1) Custom information texts Show custom texts instead of default ones
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

1) Users Regular authentication Sign in Avoid username-email collisions
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

2) Verify Letter Code verification 6 tries allowed
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

2) Valuation budget investments Valuate Finish valuation
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)

1) Users Delete a level 2 user account from document verification page
   Failure/Error: raise ex, cause: cause

   Selenium::WebDriver::Error::UnknownError:
     unknown error: unhandled inspector error: {"code":-32000,
     "message":"Node with given id does not belong to the document"}
       (Session info: chrome=134.0.6998.35)
```
2025-03-26 16:27:08 +01:00
Javi Martín
533d2198ee Use refresh instead of visiting the current page
This way it's more obvious what's going on.

Note that, in this case, the expectations were **not** true before
visiting the page, so we aren't fixing a flaky test.
2025-03-26 16:27:08 +01:00
Javi Martín
5206708c01 Fix wrong expectation in information texts test
The expectation that there isn't a link with the text "Español" wasn't
updated in commit f7417d647, when the tests were updated after switching
the user interface from a list of links to a select field.

We're also adding an additional expectation after the `visit` to make
sure the request has finished before selecting English from the selector
(which probably doesn't make sense because it's the only option, but
changing it is out of the scope of this commit).
2025-03-26 16:27:08 +01:00
Javi Martín
f913ca75c6 Add missing expectations before opening the last email
We weren't checking that the requests had finished before checking the
last sent email. That's probably why one of these tests has recently
failed on our CI:

```
1) System Emails Preview Pending #send_pending
  Failure/Error: email = open_last_email

  RuntimeError:
    No email has been sent!
```
2025-03-26 16:27:08 +01:00
Javi Martín
fde5be293d Move mailer tests to the right file
These tests were testing mailer methods, but were inside a file for
system tests.

We're moving them now because these tests use the `open_last_email`
method, and we're looking for places where using this method might
result in a flaky test when used inside a system test.
2025-03-26 16:27:08 +01:00
Javi Martín
3a9263f6e6 Check flash messages in some system tests
This way it's more clear what the user experience is during the process.

Note this did not result in flaky tests, since the tests continue by
clicking links, that are only present after the request has finished.
However, we're adding expectations so we don't have to think whether the
tests could be flaky and because this way we're also testing the user
experience; it would be strange for a user if they were redirected to a
page without a flash message.
2025-03-26 16:27:08 +01:00
Javi Martín
548e282564 Don't click two places at the same time
Quoting from commit 57bda006b5:

> When clicking the button "Search", the link "newest" is already
> present, so capybara might click the "newest" link before the "Search"
> request is finished, leading to unexpected results.
>
> Checking the page to make sure the "Search" request has finished
> before clicking the "newest" link solves the problem.

We're doing the same thing for the other tests that click the "Search"
button and then clicked on a link. We're also making sure the language
selector changes before clicking it again.
2025-03-26 16:27:08 +01:00
Javi Martín
40d89ee47c Add missing expectations before calls to visit
There were many cases where we were clicking on a link or (most of the
time) a button and then calling the `visit` method. In the past, it
worked just fine because clicking on buttons usually results in non-AJAX
requests, meaning that the test waited for the request to finish before
continuing.

That's no longer the case, though. In the last few months/years (not
sure since when) we're getting sporadic failures because the test
doesn't wait for the request to finish before making another request
with the `visit` method. This sometimes results in flaky tests.

Some of these tests have recently failed in our CI. Here are a few
examples (note the numbers don't follow an order because these tests
failed in different jobs):

```
1) Admin edit translatable records Current locale translation does not
   exist For ActivePoll Shows first available fallback
   Failure/Error: expect(page).to have_content "Sondage en Français"

     expected to find text "Sondage en Français" in "Language: \n
       \nEnglish\nDeutsch\nEspañol\nFrançais\nNederlands\nPortuguês
       brasileiro\n中文\n       Go back to CONSUL DEMOCRACY\nCONSUL
       DEMOCRACY\nADMINISTRATION\nMenu\nNotifications\nMy content\nMy
       account\nSign out\nProposals\nDebates\nComments\nPolls\n
       Collaborative Legislation\nParticipatory budgets\nVoting booths
       \nSignature Sheets\nMessages to users\nSite content\nModerated
       content\nProfiles\nStatistics\nSettings\nProposals dashboard\n×
       \nPolls description updated successfully.\nList of polls\nPolls
       description\nCreate poll\nThere are no polls."

2) Public area translatable records Existing records Update a
   translation With valid data Changes the existing translation
   Failure/Error: expect(page).to have_field "Debate title",
                  with: "Title in English"
     expected to find field "Debate title" that is not disabled but
     there were no matches

2) Admin collaborative legislation Update Edit milestones summary
     Failure/Error: expect(page).to have_content "There is still a long
                                                 journey ahead of us"
       expected to find text "There is still a long journey ahead of us"
        in "Language: \n
        \nEnglish\nDeutsch\nEspañol\nFrançais\nNederlands\nPortuguês
        brasileiro\n中文\n       Go back to CONSUL DEMOCRACY\nCONSUL
        DEMOCRACY\nADMINISTRATION\nMenu\nNotifications\nMy content\nMy
        account\nSign out\nProposals\nDebates\nComments\nPolls\n
        Collaborative Legislation\nParticipatory budgets\nVoting booths
        \nSignature Sheets\nMessages to users\nSite content\nModerated
        content\nProfiles\nStatistics\nSettings\nProposals dashboard\n×
        \nProcess updated successfully. Click to visit\nBack\nAn example
        legislation process\nInformation\nHomepage\nDebate\nProposals\n
        Drafting\nFollowing\n1 language in use\nCurrent language\n
        English\nSummary\n    Format\n    ◢\n Milestone\nManage progress
        bars\nDon't have defined milestones\nCreate new milestone".
        (However, it was found 1 time including non-visible text.)

3) Admin collaborative legislation SDG related list create Collaborative
   Legislation with sdg related list
     Failure/Error:
       within("tr", text: "Legislation process with SDG related content") do
         expect(page).to have_css "td", exact_text: "17"
       end

     Capybara::ElementNotFound:
       Unable to find css "tr"

4) Valuation budget investments Valuate Feasibility can be marked as
   pending
   Failure/Error: expect(find("#budget_investment_feasibility_undecided"))
                  .not_to be_checked

    Capybara::ElementNotFound:
      Unable to find css "#budget_investment_feasibility_undecided"

3) Custom information texts Show custom texts instead of default ones
   Failure/Error:
     within("#section_help") do
       expect(page).to have_content "Custom help with debates"
       expect(page).not_to have_content "Help with debates"
     end

4) Admin budgets Update Deselect all selected staff
   Failure/Error: expect(page).to have_link "Select administrators"
     expected to find link "Select administrators" but there were no
     matches

3) Admin polls SDG related list edit poll with sdg related list
   Failure/Error:
     within("tr", text: "Upcoming poll with SDG related content") do
       expect(page).to have_css "td", exact_text: "17"
     end

   Capybara::ElementNotFound:
     Unable to find css "tr"

4) Admin polls SDG related list create poll with sdg related list
   Failure/Error:
     within("tr", text: "Upcoming poll with SDG related content") do
       expect(page).to have_css "td", exact_text: "17"
     end

   Capybara::ElementNotFound:
     Unable to find css "tr"

5) Admin custom images Image is replaced on admin newsletters
     Failure/Error:
       within(".newsletter-body-content") do
         expect(page).to have_css("img[src*='logo_email_custom.png']")
       end

     Capybara::ElementNotFound:
       Unable to find css ".newsletter-body-content"

6) Admin custom images Image is replaced on front views
     Failure/Error:
       within("#map") do
         expect(page).to
           have_css("img[src*='custom_map.jpg'][alt='Districts list']")
       end

     Capybara::ElementNotFound:
       Unable to find css "#map"
```
2025-03-26 16:27:07 +01:00
taitus
6753505e7c Allow administrators to define the cookies vendors the application uses 2025-01-23 17:03:30 +01:00
taitus
f4c3c4e639 Add cookies methods as support common actions 2025-01-23 16:05:41 +01:00
Javi Martín
1f627d34f1 Make sure polygons contain valid rings
According to the GeoJSON specification [1]:

> * A linear ring is a closed LineString with four or more positions.
> * The first and last positions are equivalent, and they MUST contain
>   identical values; their representation SHOULD also be identical.
> (...)
> * For type "Polygon", the "coordinates" member MUST be an array of
>   linear ring coordinate arrays.

Note that, for simplicity, right now we aren't checking whether the
coordinates are defined counterclockwise for exterior rings and
clockwise for interior rings, which is what the specification expects.

[1] https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6
2024-12-23 17:35:33 +01:00
CoslaJohn
624e60eab9 Added layer control to map to allow each geozone display to be toggled on/off
Note we're adding a `name` property to the geozones investments sidebar
map even if we don't render the geozones in the map, in order to
simplify the JavaScript function `geozoneLayers`.
2024-12-23 17:35:33 +01:00
CoslaJohn
cb8b0ad6ff Support different colors and headings on each feature
We're making sure each feature contains properties in order to avoid
possible JavaScript errors.

We're also adding a default color to a geozone.
2024-12-23 17:35:33 +01:00
CoslaJohn
5dbe2cbf24 Support FeatureCollection and MultiPolygon in geozones
We're reworking the format validation to correctly interpret feature
collection, feature, and geometry, according to RFC 7946 [1].

Since Leaflet interprets GeoJSON format, we're rendering the GeoJSON as
a layer instead of as a set of points. For that, we're normalizing the
GeoJSON to make sure it contains either a Feature or a
FeatureCollection. We're also adding the Leaflet images to the assets
path so the markers used for point geometries are rendered correctly.

Note we no longer allow a GeoJSON containing a geometry but not a
defined type. Since there might be invalid GeoJSON in existing Consul
Democracy databases, we're normalizing these existing geometry objects
to be part of a feature object.

We're also wrapping the outline points in a FeatureCollection object
because most of the large GIS systems eg ArcGIS, QGIS export geojson as
a complete FeatureCollection.

[1] https://datatracker.ietf.org/doc/html/rfc7946

Co-authored-by: Javi Martín <javim@elretirao.net>
2024-12-23 17:35:33 +01:00
taitus
1cf85560dd Extract poll question option images from shared nested imageable specs to system specs
This is the only it_behaves_like "nested imageable" call where the has_many_images parameter is set to true.

Previously, the shared example skipped or altered expectations based on this parameter. Now, this behavior is
moved to the factory level (:future_poll_question_option).

Since this is an administrative section, a related administrator is created for the user.
2024-11-26 17:58:10 +01:00
taitus
fb98cb61ac Extract budgets from shared nested imageable specs to system specs
Removed `imageable_path_arguments`, `has_many_images`, and `management` parameters
because they are not used by budgets.

Hardcoded `path`, `fill_resource_method_name`, `submit_button`, and
`imageable_success_notice`parameters for budgets. These remain fixed for now until dynamic
values are required in the next commits.
2024-11-20 16:27:53 +01:00
Javi Martín
597a21eca9 Add alt attribute to map images
We were using it on the map displayed on the sidebar, but we weren't
using it in the other places were the map is rendered.
2024-11-12 18:25:20 +01:00
Javi Martín
ddaf320d8a Add proper labels to shift date selectors
We were using one label for both date selectors, but it wasn't
associated with any of them.

So we're now rendering one label per control and, just like we only show
one of these date selectors at a time, we're only showing one label at a
time.
2024-11-12 15:58:26 +01:00
Javi Martín
d254fcd7ca Fix missing "for" attribute in user segments label
Since the attribute was missing, the label wasn't correctly associated
with its field.
2024-11-12 15:15:34 +01:00
Javi Martín
3b7948a139 Use a date field to select the date of birth
The default `date_select` used in fields presents an accessibility
issue, because in generates three select controls but only one label.
That means that there are two controls without a label.

So we're using a date field instead. This type is field is supported by
about 99% of the browsers, and we've already got JavaScript code
converting this field to a jQuery UI datepicker in case the browser
doesn't support date fields.

Note that, since we no longer need to parse the three date fields into
one, we can simplify the code in both the models and the tests.

Another slight improvement is that, previously, we couldn't restrict the
month and day controls in order to set the minimum date, so the maximum
selectable date was always the 31st of December of the year set by the
minimum age setting. As seen in the component test, now that we use only
one field, we can set a specific date as the maximum one.
2024-11-12 15:15:34 +01:00
Javi Martín
4102330abc Add labels to investments filters
Note that adding the labels broke the layout because the button was no
longer aligned with the fields, so we're now using a flex layout.

Since we're using labels, we no longer need a placeholder (which wasn't
very informative, by the way) in the text field.
2024-11-11 15:04:40 +01:00
Javi Martín
29968d1d9f Use a button to toggle advanced filters
As mentioned in commit 5311daadf, there are several reasons to use
buttons in these situations.
2024-11-11 15:04:40 +01:00
Javi Martín
5ca65a787f Add an ARIA label to site customization images fields
This way it'll be easier for people using screen readers to know which
field they're on.
2024-11-08 15:03:55 +01:00
Javi Martín
331228cb2a Add proper labels for site customization texts
We were rendering one label and many textarea fields for that label.
This meant that, when switching to a different language, the label
wasn't correctly associated with the textarea.

So we're now rendering one label for each textarea. We could use
`aria-label` or `aria-labelledby` instead, but using a label offers some
advantages like the fact that clicking on the label makes the textarea
take the focus.
2024-11-08 15:03:55 +01:00
Javi Martín
16fc9998c4 Use labels in controls to add and select languages
The absence of labels in these controls made them hard to use,
particularly for people who use screen readers.

Note we're removing the "Choose language" prompt, since we always
automatically choose a language and not choosing a language doesn't
really make sense. The only scenario where the prompt was used took
place when all languages had been removed but, in that case, the "Choose
language" prompt was misleading because there were no languages to
choose from.
2024-11-08 14:22:44 +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
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
76b0971b4a Simplify mark as visible to valuators tests
We were performing 3 requests in order to refresh the page and check the
content was still there. We can use `refresh` instead.

We're also reusing the `investment1` variable in every test, instead of
redifining it in one of them.
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
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
1b46afc95c Check different content in select investments test
Since we were checking something that was already there, if the form
were submitted using an AJAX request (which is the default with Turbo,
although we don't use it yet), there would be a chance that the request
didn't finish before the test does, leading to potential failures in the
next test.

This way we're also checking that the "Filter" button actually does
something when selecting the "Selected" filter.
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
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
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
af0911a8d2 Fix warning in hidden proposals spec
We were checking the proposal video URL, but its value was `nil` since
commit bedcb5bca2. This resulted in a warning:

```
Checking for expected text of nil is confusing and/or pointless since it
will always match. Please specify a string or regexp instead.
spec/system/admin/hidden_proposals_spec.rb:14
```
2024-10-07 16:37:13 +02:00
Javi Martín
8997ed316c Rename variables describing poll options as answers
Since we've renamed the class to `Option`, having variables, methods and
texts refering to it as `answer` was confusing.
2024-06-13 19:13:05 +02:00
Javi Martín
38b38d1fcc Rename Poll::Question::Answer to Poll::Question::Option
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.
2024-06-13 19:13:01 +02:00
Javi Martín
c367f21705 Add buttons to check all/none available languages
Although most Consul Democracy installations will only have a few
available languages using `config.i18n.available_locales`, there's a
chance some installation will keep every language as available and will
enable the desired ones using the admin interface. In these cases,
enabling (or disabling) every language would be tedious, particularly
when casually experimenting in a staging environment or while using the
official Consul Democracy demo.

So we're adding buttons to simplify the process. Since some
installations might have only a couple of available languages, and in
this case these buttons would be pretty much useless, we're only showing
them when there are many languages available.
2024-06-06 16:28:19 +02:00
Javi Martín
78bbf430d5 Add a form to edit available locales
We're using different controls depending on the number of available
locales.

When there are only a few locales, the solution is obvious: radio
buttons to select the default language, and checkboxes to select the
available ones are simple and intuitive.

With many languages, showing two consecutive lists of 30 languages could
be confusing, though, particularly on small devices, where scrolling
through both lists could be hard.

So, in this case, we're rendering a <select> to choose the default
language. For selecting the available languages, however, we're sticking
to checkboxes because all the other existing options (like multiple
selects) are hard to use. We think it's OK because the form doesn't have
any additional fields, and there's only one big list of options to
scroll through.

While testing the application, we noticed that if we use the
`admin-fieldset-separator` styles when there's only one fieldset, it's
harder to notice that there's an additional field to select the default
language. So we're only using the `admin-fieldset-separator` styles when
all the fields are grouped in fieldsets.

Regarding the help text for the fieldset, if we leave the help text
outside the <legend> tag, people using screen readers won't hear about
this content. However, if we include it inside the <legend> tag, some
screen readers might read it every time they move to a different
checkbox (or radio button), which can be annoying. Since I don't think
these help messages are really essential, I'm leaving them out of the
<legend> tag. It's also easier to style them if they're outside the
<legend> tag.

Note we're using `display: table` for the labels, for the reasons
mentioned in commit 923c2a7ee.

Also note that, when there's only one available locale, this section is
useless. In this case, we aren't disabling it for now because there's a
chance people see it in the official Consul Democracy demo and then
wonder why it isn't available on their installation. We might disable it
in the future, though.
2024-06-05 16:10:56 +02:00
Javi Martín
999d5c2f67 Remove redundant "Manage" in admin menu entries
This is the admin section; it's obvious that every link in the menu will
take you to a page to manage something.

We're going to add a new item to either the "Settings" or the "Site
content" section, so it's a good time to improve what's already there.
2024-06-05 16:10:56 +02:00
Julian Herrero
16f844595d Don't use the cache in admin budget stats
In commit e51e03446, we started using the same code to show stats in the
public area and in the admin area. However, in doing so we introduced a
bug, since stats in the public area are only shown after a certain part
of the process has finished, meaning the stats appearing on the page
never change (in theory), so it's perfectly fine to cache them. However,
in the admin area stats can be accessed while the process is still
ongoing, so caching the stats will lead to the wrong results being
displayed.

We've thought about expiring the cache when new supports or ballot lines
are added; however, that means the methods calculating the stats for the
supporting phase would expire when supports are added/removed but the
methods calculating the stats for the voting phase would expire when
ballot lines are added/removed. It gets even more complex because the
`headings` method calculates stats for both the supporting and the
voting phases.

So, since loading stats in the admin section is fast even without the
cache because they only load very basic statistics, we're taking the
simple approach of disabling the cache in this case, so everything works
the same way it did before commit e51e03446.

Co-authored-by: Javi Martín <javim@elretirao.net>
2024-05-20 16:19:41 +02:00
Javi Martín
d25f2e7259 Add missing event name translations
We were always displaying the event names in English.

Note we're changing the `user_supported_budgets` key because it didn't
make much sense; the investments are supported, and not the budgets.

We're also adding "created" to most of the event names in order to make
the texts more explicit, since not all the events refer to created data.
2024-05-09 14:28:32 +02:00