Commit Graph

4457 Commits

Author SHA1 Message Date
Senén Rodero Rodríguez
87339451de Reset columns_selector before caching the page
This will allow to initialize this module again without duplicating
columns checkboxes and without breaking the page.
2020-08-12 10:10:58 +02:00
Senén Rodero Rodríguez
137e0f5a64 Remove description for screen readers
It was being duplicated when restoring a page by using browser
history. With this solution we will avoid to have screen readers
descriptions more than once inside any sociual share button.
2020-08-12 10:07:35 +02:00
Senén Rodero Rodríguez
6b17452bd5 Fix "Publish comment" button when restoring a page from browser cache
We need to use page body event delegation so it will work with any
element even with the ones added through ajax, in this case the
annotation comments box form. By doing this way we do not need
this code on the server response anymore.

Furthermore JS events defined at ajax responses are not part of
application javascript and are lost when restoring a page from
browser cache, you can try to apply the same event delegation
technique to the `erb` file and it wont work just because events
added dinamically are not treated the same than `application.js`
code.

To reproduce the error:

  1. Load an annotatable draft version
  2. Move to any other page
  3. Go back

Now "Publish comment" button wont work.
2020-08-12 10:07:35 +02:00
Senén Rodero Rodríguez
fc0625df8b Destroy Annotator app before storing page into brwoser cache
If we do not destroy annotator app before storing the page at
browser cache we will unnecesarily initialize annotations twice (or
more) duplicating Annotator HTML markup and causing
unexpected  errors.

Without this commit you will find an error when restoring a page with
annotator, you can click on any annotation and you will see the annotation
comments are being loaded twice.

IMO this is an idempotency issue within Annotator JS library.
2020-08-12 10:07:35 +02:00
Senén Rodero Rodríguez
da658f3d8c Hack datepicker to make it work with Turbolinks 5.x
Patch extracted from here the comments on turbolinks issue 253 and
converted to vanilla javascript.

The hide action over datepickers ensures us that opened datepickers
will be closed before leving the page. Previously if you open any
datepicker and then move to previous page you will keep seeing the
datepicker in the restored page.
2020-08-12 10:07:35 +02:00
Javi Martín
0270c4c962 Hide unsaved changes warning after undoing them
This way showing the warning is consistent with warning users when
they're leaving the page.
2020-08-05 14:10:22 +02:00
Javi Martín
cfc60b5de4 Warn for changes just in markdown editor
This is the reason why this feature was implemented in the first
place: it's easy to open the editor, make some changes, close it, and
continue without realizing the changes have not been saved.

In the rest of the forms, this functionality is quite lacking. For
starters, some forms warn if there are unsaved changes, while some forms
don't, which is highly inconsistent and disorients users.

Furthermore, we were having problems with this feature after upgrading
Turbolinks, particularly in forms using CKEditor. In these cases, a lot
of hacking needs to be done in order to make this feature work properly,
since CKEditor adds some formatting automatically, and if this is done
after the form is serialized, we'll get some unexpected behavior. On the
other hand, comparing the value of a textarea against its `defaultValue`
property will work on every edge case, including using the browser's
back button or reloading the page.

Finally, users are used to the way web forms work, and aren't used to be
asked for confirmation when they change their mind and decide to leave
the page without saving the changes. Asking them for confirmation will
be annoying in most cases. Besides that, if they accidentally leave the
page, they can use the browser's back button and they'll recover the
unsaved changes.

It's true this won't happen it they accidentally close the browser's
window, but our WatchFormChanges functionality didn't work in this case
either. Using the "beforeunload" event adds more problems than it
solves, since it doesn't support custom messages (or, to be more
precise, modern browsers ignore custom messages), and it doesn't get
along with turbolinks.

Co-Authored-By: Senén Rodero Rodríguez <senenrodero@gmail.com>
2020-08-05 14:10:22 +02:00
Javi Martín
f68553dc00 Extract method to fill in markdown editor in specs 2020-08-05 14:10:22 +02:00
Javi Martín
7b96180a76 Upgrade Turbolinks to version 5.2.1
We didn't upgrade Turbolinks when we upgraded to Rails 5 so we didn't
upgrade too many things at the same time, and postponed it... until now
:).

Note upgrading Turbolinks fixes an issue with foundation's sticky when
using the browser's back and forward buttons. We're adding tests for
these scenarios.

Co-authored-by: Senén Rodero Rodríguez <senenrodero@gmail.com>
2020-08-05 14:10:22 +02:00
Javi Martín
983bf49b38 Simplify code related to Foundation's sticky
In the past we had huge problems trying to make it work with Turbolinks.
However, after updating foundation-rails in commit 58071fd6, these hacks
aren't necessary anymore.

We're adding a test for the scenario of visiting a page using
Turbolinks, which was missing, so we're sure we aren't breaking
anything.

Note the sticky will still not work after using the browser back button.
We haven't been able to make it work with turbolinks-classic; we'll fix
this issue when upgrading turbolinks.
2020-08-05 11:34:57 +02:00
Senén Rodero Rodríguez
fde6fb4d97 Initialize only visible maps when page is loaded
Its known that initializing a map when it is inside a hidden element
wont work when hidden element is shown, so its makes sense to
avoid initialization of hidden maps.

When a map lives within a hidden layer we need to initialize the
map after the event of showing that hidden layer, in our case when
admin settings tab is shown.
2020-08-05 11:34:57 +02:00
Julian Herrero
46c78fc3ef Do not delete users when deleting legislation answers
When a legislation process is deleted, everything related will be
deleted, including the answers. This `dependent: :destroy` was causing
that users accounts were being accidentally deleted.
2020-07-27 14:32:22 +02:00
Javier Martín
c03ada579d Merge pull request #4061 from consul/ballot_race_condition
Fix race condition with ballot lines
2020-07-27 13:01:37 +02:00
Javier Martín
54095d7928 Merge pull request #4064 from consul/remove_google_plus
Remove Google plus share button
2020-07-21 13:03:59 +02:00
Javier Martín
7ee3eecae3 Merge pull request #3980 from consul/erased-users
Filter erased users and show erase reason in admin
2020-07-17 23:00:12 +02:00
decabeza
f72f255d15 Filter erased users and show erase reason in admin 2020-07-17 22:21:52 +02:00
decabeza
e3539544a8 Remove google plus share button 2020-07-17 16:24:20 +02:00
Javi Martín
d9eeb1ad15 Improve test checking order by relevance
The test wasn't working when postgres used the English dictionary
because in English the word "what" was ignored (or, at least, not given
enough relevance) while searching. When we wrote the test, it passed
because back then we always used the Spanish dictionary. However, when
we switched to a dictionary based on the default locale (in commit
d99875cd), we had to force this test to keep using the Spanish
dictionary.

Using the Spanish dictionary in a test where all texts are in English is
strange to say the least ;). So here we're making the test a bit easier
to understand.

Since now we're only using the `:spanish_search` tag in one test, I've
decided to remove it and simply add it to that test's setup.
2020-07-14 14:49:39 +02:00
Javier Martín
ae0fb131d4 Merge pull request #4028 from consul/rails5.2_compatibility
Add Rails 5.2 compatibility
2020-07-14 13:40:30 +02:00
Javi Martín
057679248f Use be_not_found instead of be_missing
We were getting a deprecation message in Rails 5.2:

The missing? predicate is deprecated and will be removed in Rails 6.0.
Please use not_found? as provided by Rack::Response::Helpers
2020-07-14 12:32:14 +02:00
Javi Martín
d2d517059d Fix race condition with ballot lines
With two concurrent requests, it's possible to create two ballot lines
when only one of them should be created.

The reason is the code validating the line is not thread safe:

```
if ballot.amount_available(investment.heading) < investment.price.to_i
  errors.add(:money, "insufficient funds")
end
```

If the second request executes this code after the first request has
executed it but before the first request has saved the record to the
database, both records will pass this validation and both will be saved
to the database.

So we need to introduce a lock. Now when the second request tries to
lock the ballot, it finds it's already locked by the first request, and
will wait for the transaction of the first request to finish before
checking whether there are sufficient funds.

Note we need to disable transactions during the test; otherwise the
second thread will wait for the first one to finish.

Also note that we need to update a couple of tests because records are
reloaded when they're locked.

In one case, reloading the ballot causes `ballot.user` to be `nil`,
since the user is hidden. So we hide the user after creating all its
associated records (which is the scenario that would take place in real
life).

In the other case, reloading the ballot causes `ballot.user` to reload
as well. So we need to reload the user object used in the test too so it
gets the updates done on `ballot.user`.

I haven't been able to reproduce this behavior in a system test. The
following test works with Rails 5.0, but it stopped working when we
moved to system tests in commit 9427f014. After that commit, for reasons
I haven't been able to debug (reintroducing truncation with
DatabaseClaner didn't seem to affect this test, and neither did
increasing the number of threads in Puma), the two AJAX requests
executed here are no longer simultaneous; the second request waits for
the first one to finish.

scenario "Race conditions with simultaneous requests", :js do
  allow_any_instance_of(Budget::Ballot::Line).to receive(:check_sufficient_funds) do |object|
    allow(object).to receive(:check_sufficient_funds).and_call_original
    object.check_sufficient_funds
    sleep 0.3
  end

  ["First", "Second"].each do |title|
    create(:budget_investment, :selected,
      heading: california,
      price:   california.price,
      title:   title
    )
  end

  login_as(user)
  visit budget_investments_path(budget, heading_id: california.id)

  within(".budget-investment", text: "First") { click_link "Vote" }
  within(".budget-investment", text: "Second") { click_link "Vote" }

  expect(page).to have_link "Remove vote"
  expect(Budget::Ballot::Line.count).to eq 1
end
2020-07-12 22:11:40 +02:00
Julian Herrero
89962ba61a Allow deleting polls with answers including videos
If a poll has a question with an answer containing a related video,
an error was raised because the poll ID was referenced in another
table.
2020-07-09 13:39:15 +02:00
Javi Martín
f427c757ba Use hash conditions instead of SQL's IN
This is what we're doing in most places.
2020-07-08 18:34:58 +02:00
Javi Martín
6fd9a286d7 Don't access the database in after_initialize
Rails 5.2 crashes in the `db:create` task because it tries to run the
`after_initialize` block before the database is created.

The easiest way to solve it is to move the code out of the initializer
and calculate the API type definitions on demand. Note results are still
cached using a class instance variable (not to be confused with a class
variable), and so once definitions are obtained, they will remain
constant until the application is restarted, even in the development
environment.
2020-07-08 18:34:58 +02:00
Javi Martín
9837b1ab74 Remove tasks to upgrade to version 1.1
These tasks are not needed for new installations, and in existing
installations they've already been executed when upgrading to version
1.1.

One of them also raises a warning in Rails 5.2:

DEPRECATION WARNING: Dangerous query method (method whose arguments are
used as raw SQL) called with non-attribute argument(s): "MIN(id) as id".
Non-attribute arguments will be disallowed in Rails 6.0. This method
should not be called with user-provided values, such as request
parameters or model attributes. Known-safe values can be passed by
wrapping them in Arel.sql()
2020-07-08 18:34:58 +02:00
Javi Martín
4f30720593 Fix flagging/unflagging in the admin section
We weren't adding the HTML id our JavaScript expects, and so the page
didn't update the flag element.
2020-07-07 23:39:21 +02:00
Javi Martín
014ccd8374 Use shared specs to flag comments 2020-07-07 23:39:21 +02:00
Javi Martín
3c27df592e Remove test for flagging poll comments
This feature hasn't been implemented and there are no plans to implement
it in the near future.
2020-07-07 23:39:21 +02:00
volcov
09fd3ab44a Fix legislation proposals flag actions
We were treating legislation proposals as if they were proposals,
omitting the "legislation" namespace, and so we were flagging/unflagging
proposals when we wanted to flag/unflag a legislation proposal.
2020-07-07 23:39:21 +02:00
Javi Martín
91da038b27 Extract shared tests to flag/unflag a record 2020-07-07 22:56:17 +02:00
Javi Martín
9937e94fcd Fix flagging debates and comments with AJAX
We weren't using `foundation()` in these cases, so after flagging a
debate or a comment, we had to reload the page before we could unflag
it.

We're also adding a test for the fix in commit ea85059d. This test shows
it's necessary to filter the elements with JavaSctipt using `first()` if
we want the same code to work with comments.

Co-Authored-By: taitus <sebastia.roig@gmail.com>
2020-07-07 22:56:17 +02:00
Javier Martín
328ec5e25f Merge pull request #4001 from rockandror/check-session-locale
Discard session[:locale] when is not valid
2020-06-25 22:00:37 +02:00
taitus
ee5ac25cb1 Improve set_locale
We discard session[:locale] as valid locale when it is no longer include in
the :available_locales
2020-06-25 19:45:56 +02:00
Javi Martín
002e9239d0 Simplify code involving Globalize.locale
We don't need to set this value. In commit f2ef27d3 I made a mistake
thinking `Globalize.locale` and `I18n.locale` should always be in sync,
but they're actually automatically in sync when `Globalize.locale` is
`nil`.

So the best way to avoid any issues is not to assign `Globalize.locale`,
and use `Globalize.with_locale` where necessary instead.
2020-06-25 19:37:57 +02:00
Javi Martín
438a751599 Rename admin proposal notifications controller
To be consistent with all the other controllers dealing with hidden
content, we use the word "hidden" in the controller class.
2020-06-16 19:40:04 +02:00
Javi Martín
5d10afdf26 Fix deleting searched managers/moderators/admins
We were deleting managers, moderators and administrators based on their
user ID, instead of their manager/moderator/administrator ID.
2020-06-16 19:09:27 +02:00
Javi Martín
4bb906f0be Apply Layout/SpaceAroundMethodCallOperator rule
This rule was added in rubocop 0.82.
2020-06-16 13:47:38 +02:00
Javi Martín
65604a92c2 Add non-prefixed polymorphic admin routes
These routes are solved in a different way because of an inconsistency:
we define `groups` and `budget_investments`; we should either use the
`budget_` prefix in all places or remove it everywhere.

We can now share code using `polymorphic_path` even with these models.
2020-06-15 11:54:05 +02:00
Javi Martín
7563b7f4d1 Simplify polymorphic routes in shared specs
Now we get rid of the "hierarchy" methods and use standard Rails methods
except in the routes definitions themselves.
2020-06-15 11:54:05 +02:00
Javi Martín
ff93f5a591 Use "resolve" for polymorphic hierarchy paths
In the past, we couldn't use `polymorphic_path` in many places. For
instance, `polymorphic_path(budget, investment)` would return
`budget_budget_investment_path`, while in our routes we had defined
`budget_investment_path`.

With the `resolve` method, introduced in Rails 5.1, we can use symbols
to define we want it to use `investment` instead of `budget_investment`.
It also works with nested resources, so now we can write
`polymorphic_path(investment)`.

This makes the code for `resource_hierarchy_for` almost impossible to
understand. I reached this result after having a look at the internals
of the `resolve` method in order to get its results and then remove the
symbols we include.

Note using this method will not make admin routes compatible with
`polymorphic_path`. Quoting from the Rails documentation:

> This custom behavior only applies to simple polymorphic URLs where a
> single model instance is passed and not more complicated forms, e.g:
> [example showing admin routes won't work]

Also note that now the `admin_polymorphic_path` method will not work for
every model due to inconsistencies in our admin routes. For instance, we
define `groups` and `budget_investments`; we should either use the
`budget_` prefix in all places or remove it everywhere. Right now the
code only works for items with the prefix; it isn't a big deal because
we never call it with an item without the prefix.

Finally, for unknown reasons some routing tests fail if we use
`polymorphic_path`, so we need to redefine that method in those tests
and force the `only_path: true` option.
2020-06-15 11:54:05 +02:00
Javi Martín
334b57501b Simplify uses of polymorphic admin nested routes 2020-06-11 18:39:57 +02:00
Javi Martín
72c2b87227 Wait till CKEditor is ready before checking it
With chromedriver >= 80, the tests are freezing sometimes, particularly
when the same editor is loaded again.

We don't know whether it's a CKEditor issue or a chromedriver issue. In
the past we've had some errors related to CKEditor trying to load the
same instance twice and we aren't sure they have been fixed since we
could never reproduce them.

It could be a coincidence, though. If we modify the views so the only
content of the `<body>` tag is a textarea with the `html-area` class,
chromedriver freezes even if we only access the page once. So maybe
we're only detecting the problem on the second visit because the second
request is faster than the first one.

Since chromedriver no longer hangs after this change, we don't have to
force any chromedriver version anymore.
2020-06-09 13:29:56 +02:00
Javi Martín
8408bfdcf0 Don't use ckeditor.setData in specs
After upgrading to chromedriver 80, tests checking CKEditor's content
were causing chromedriver to hang. That's why we were configuring
webdrivers to use an older chromedriver.

Version 80 of chromedriver introduced several issues regarding frames.
Debugging shows in this case chromedriver froze when we used `setData`
and then `within_frame`. Since adding a `sleep` call made it work, we
think `within_frame` was being executed before `setData` had finished.
The fact that `setData` causes the browser to enter the frame having
CKEditor is probably the reason.

Even though the `setData` method provides a callback when it's finished,
configuring it so the rest of the Ruby code isn't executed until that
happens leads to complex code. Using Capybara's `set` to fill in the
editor is IMHO a bit easier to understand.

After this change, since we're using a method provided by Capybara
instead of executing asynchronous JavaScript code, we don't have to
check CKEditor has been filled anymore. The "Admin Active polls add"
test, which failed on my machine without that check, now passes.
2020-06-09 13:29:56 +02:00
Javi Martín
4d65507cbb Check for exact text in have_ckeditor
If we don't use the `exact` option, tests will pass even if filling in
CKEditor adds the content twice or adds the new content to the existing
content, which has actually happened and has gone mostly unnoticed while
testing several ways to fill in CKEditor with Capybara (particularly,
when using Capybara's `send_keys` method). The problem was detected by
just one test, which checked the original content wasn't present anymore
after updating a record.
2020-06-09 13:29:56 +02:00
Javier Martín
f929108870 Merge pull request #4023 from consul/homepage_confirm_dialog
Don't use confirm dialog in admin homepage form
2020-05-26 18:14:58 +02:00
Senén Rodero Rodríguez
31c0b4360d Improve the way to toggle comment responses
Co-Authored-By: Javi Martín <javim@elretirao.net>
2020-05-26 13:20:26 +02:00
Senén Rodero Rodríguez
dcff7e8a33 Show parent comment responses when a new reply is added
When a user replies to a comment whose responses was hidden at the
moment of reply form submission and although the reply were correctly
added to the DOM it was hidden because was added to a collapsed list.

This solution is about showing all responses of parent comment after adding
the new comment to the DOM so the user can see new reply into the screen.
(This is not applicable to root comments which cannot be collapsed)
2020-05-26 13:20:26 +02:00
Senén Rodero Rodríguez
014fa6eb1c Add mutations observer to initialize user initials added through ajax 2020-05-26 13:20:26 +02:00
Senén Rodero Rodríguez
956f002738 Update parent comment responses count when a new reply is created
Extract the needed portion of code to a new partial to be able to update
only the elements needed when a new comment is added keeping UI properly
updated.
2020-05-26 13:20:26 +02:00
Javi Martín
5bf968d2b2 Don't use confirm dialog in admin homepage form
In this case the confirmation dialog isn't really necessary since the
action to enable/disable the setting can easily be undone.

Furthermore, these tests were failing with Chrome 83, probably because
we use `confirm_dialog` and then we use `visit` without checking the
page in between.

In theory we shouldn't need to check the page in between because the
request generated by `confirm_dialog` is a synchronous one and so
`visit` isn't executed after the previous request has finished, but
apparently this behavior has changed in Chrome 83.

We could add an expectation before executing the `visit` method, but
that wouldn't improve the usability of the application.
2020-05-25 19:28:16 +02:00