Make $civicrm_paths less sensitive to trailing slashes. Add tests.
Overview
--------
Recall that the default value of `imageUploadURL` is `[civicrm.files]/persist/contribute/`. Now, suppose you have one of these two configurations in `civicrm.settings.php`:
```php
// (1) Trailing slash configuration
$civicrm_paths['civicrm.files']['url'] = 'http://tmpd8-clean.bknix:8001/sites/default/files/civicrm/';
$civicrm_paths['civicrm.files']['path'] = '/Users/totten/bknix/build/tmpd8-clean/web/sites/default/files/civicrm/';
// (2) Trimmed slash configuration
$civicrm_paths['civicrm.files']['url'] = 'http://tmpd8-clean.bknix:8001/sites/default/files/civicrm';
$civicrm_paths['civicrm.files']['path'] = '/Users/totten/bknix/build/tmpd8-clean/web/sites/default/files/civicrm';
```
You could inspect to see if the URL is generated correctly by running these commands:
```
$ cv api setting.get return=imageUploadURL
$ cv url -c imageUploadURL
$ cv url -d "[civicrm.files]/persist/contribute/"
$ cv path -c imageUploadDir
$ cv path -d "[civicrm.files]/persist/contribute/"
```
Before
------
Under either configuration (trailing-slash or trimmed-slash), you'll find that paths are generated properly (`cv path ...` or `Civi::paths()->getPath(...)`).
For generating URLs (`cv url ...` or `Civi::paths()->getUrl(...)`), only the trailing-slash cfg works. The trimmed-slash cfg leads to a bad URL with a missing slash.
```
[bknix-max:~/bknix/build/tmpd8prj-clean/web] cv api setting.get return=imageUploadURL
{
"is_error": 0,
"version": 3,
"count": 1,
"id": 1,
"values": {
"1": {
"imageUploadURL": "[civicrm.files]/persist/contribute/"
}
}
}
[bknix-max:~/bknix/build/tmpd8prj-clean/web] cv url -c imageUploadURL
"http://tmpd8prj-clean.bknix:8001/sites/default/files/civicrmpersist/contribute"
[bknix-max:~/bknix/build/tmpd8prj-clean/web] cv url -d "[civicrm.files]/persist/contribute/"
"http://tmpd8prj-clean.bknix:8001/sites/default/files/civicrmpersist/contribute/"
```
This is surprising because the path expression (`[civicrm.files]/persist/contribute`) includes a slash... but it disappears in the final computation.
After
-----
Both configurations work, for paths and for URLs.