When a user recovers a page from browser history where placed a
marker in different map pane (visible map layer) marker was
successfully added to the map but the map center is the one
defined at Settings map properties so the marker was not visible
to the user.
Now when map_location form has valid coordinates we use them
instead of default map center settings. This will avoid the user to
have to rellocate the marker (or find the correct pane where the
marker was added) if already placed.
When using an editable map is better to load marker latitude, longitude and
map zoom from form fields so we can show the marker at latest position defined
by user when the page was restored from browser history.
To reproduce this behavior:
0. Undo this commit
1. Go to new proposal page
2. Place the proposal map marker
3. Go away to any other page
4. Restore new proposal page from browser history.
At this point you should not see the recently placed marker.
The same thing happens when editing a proposal.
If we do not do this a map could be initialized twice times or more
when restoring a page with a map causing weird UI effects and
loading some map layers also twice times or more.
Need to add a maps array to be able to store all initialized
(visible) maps so we can destroy them when needed. Notice that
we are destroying maps also when admin settings tabs changes
(only visible ones), this is again to avoid to re-initialize map more
than once when users navigate through settings tabs, another
option to the settings issue could be to detect if the map was
already initialized to skip uneeded initialization.
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.
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.
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.
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.
Sometimes we define URLs for POST requests which are not defined for GET
requests, such as "/residence", so redirecting to it after signing out
results in a routing error.
So instead of using the request referer, we're using the stored location
devise uses, and we're not storing locations in POST requests.
For reasons I'm not sure about, the homepage (and the welcome pages)
were an exception in our "redirect users to the same page they were"
policy.
I'm not sure about the welcome pages (no test was present indicating
they should behave in a special way), but in the case of the home page,
it was a bit annoying to be redirected to a different place after
signing in.
When signing in from a page containing GET params, like
`/budgets/1/investments?heading_id=4`, we were redirected to a URL
without those GET params; in this case, `/budgets/1/investments`.
Using the request fullpath, as recommended in the devise documentation,
keeps these parameters when redirecting.
Note we're using a new sanitizer. Ideally we'd reuse the
`AdminWYSIWYGSanitizer`, but then code that would be correctly shown by
markdown-it (like the <h1> tag) wouldn't be shown on the web, which is
confusing. Ideally we would configure markdown-it to only allow the tags
present in the `AdminWYSIWYGSanitizer` and provide some kind of help
showing which tags are allowed.
When skipping verification, we cannot apply the validation rule saying
the document number and document type must be unique, because they'll be
`nil` in many cases. So we were skipping the rule, but that makes it
possible for the same user to vote several times (for instance, once in
a booth and once via web).
So we're changing the scope of the uniqueness rule: instead of being
unique per document number, voters are unique per user. The reason we
made them unique per document number was that back in commit 900563e3
(when we added the rule), we hadn't added the relation between users and
poll voters yet.
Up until now, we were assuming the voter was valid, but were not raising
an exception if it wasn't. And in the user interface everything seemed
to be working properly.
We were having this issue when skipping verification, when there could
be voters without a document number, which would be considered invalid.
Raising an exception when failing to save the voter and making sure the
answer and the voter are saved inside a transaction solves the problem.
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>
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>
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.
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.
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.
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.
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
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
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.
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()
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.
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>
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.