* Added ConditionalHeaderUtil, a conditional request helper class meant
for composition into Handler. I evaluated the composer package
micheh/psr7-cache for this role but I decided that I prefer DIY
code rather than some rather ugly glue.
* Check conditional request headers prior to entry into
Handler::execute(). Contrary to what was previously documented, use
the results of getLastModified() and getETag() to set headers in the
response. This is convenient and can be overridden in the Handler if
desired by overriding a one-line function.
* Instead of locking up header parsing inside ConditionalHeaderUtil as
was done in micheh/psr7-cache, make a start on a new reusable header
parsing framework, with recursive descent parsers for HTTP-date and
IfNoneMatch.
Change-Id: I260809081cad7701df8620ab03834158670d4230
Add public, protected or private to function missing a visibility
Enable the tests folder for the phpcs sniff
Change-Id: Ibefce76ea9984c47e08c94889ea2eafca7565e2c
This replaces the static Language methods getFallbackFor(),
getFallbacksFor(), and getFallbacksIncludingSiteLanguage(). There is
100% unit and integration test coverage for the new class.
One deliberate functional change: I changed one place where we threw
MWException to InvalidArgumentException.
Bug: T201405
Depends-On: Ie7a89f6ed7d52a0bc01672019ff92e7ee105a1f3
Change-Id: I49222eb55f1feec5b1dcd40f364cffe0c8801855
The previous code to allow relative paths (via "path": true) was
limited to only string values, which led to needing a non-static
registration callback function.
Bug: T231855
Change-Id: I4e82f38627f2f0d50d8b05a8c02b5a35342f6526
This patch fixes the documentation of newFromText and makeTitleSafe to
no longer state incorrectly that any Title they return is guaranteed to
be valid. That has never been true.
It also makes canExist() checks a lot stricter, to match the assumptions
of current callers, namely that the title can exist as a wiki page.
Finally, it replaces several existing calls to isValid() with calls to
canExist().
Bug: T229705
Change-Id: I2a483136ec6acca49afb5eb32cb94616672b8fb2
These are static methods that have to do with processing language names
and codes. I didn't include fallback behavior, because that would mean a
circular dependency with LocalisationCache.
In the new class, I renamed AS_AUTONYMS to AUTONYMS, and added a class
constant DEFINED for 'mw' to match the existing SUPPORTED and ALL. I
also renamed fetchLanguageName(s) to getLanguageName(s).
There is 100% test coverage for the code in the new class.
This was previously committed as 2e52f48c2e and reverted because it
depended on e4468a1d6b, which had to be reverted for performance
issues. There should be no changes other than rebasing.
Bug: T201405
Change-Id: Ifa346c8a92bf1eb57dc5e79458b32b7b26f1ee8a
This removes Language::$dataCache without deprecation, because 1) I
don't know of a way to properly simulate it in the new paradigm, and 2)
I found no direct access to the member outside of the Language and
LanguageTest classes.
An earlier version of this patch (e4468a1d6b) had to be reverted
because of a massive slowdown on test runs. Based on some local testing,
this should fix the problem. Running all tests in languages is slowed
down by only around 20% instead of a factor of five, and memory usage is
actually reduced greatly (~350 MB -> ~200 MB). The slowdown is still not
great, but I assume it's par for the course for converting things to
services and is acceptable. If not, I can try to optimize further.
Bug: T231220
Bug: T231198
Bug: T231200
Bug: T201405
Change-Id: Ieadbd820379a006d8ad2d2e4a1e96241e172ec5a
The use case is code that uses search internally, but wants to allow
a development setup where search is proxied via some public API and
the actual querying is performed on a production server, instead of
having to set up all the search services + staging content locally.
Also fix a small logic error in SearchResultSet::shrink.
Change-Id: I83931c1a19c1cb747380e17a4aff3b1fadd5fcf3
T233537 made RESTBagOStuff work with the Kask external session
storage service, but broke backward compatibility. Add optional
values to the RESTBagOStuff $params constructor parameter to
support communicating with Kask, and to allow using HMAC. The
new values are:
serialization_type: legacy (default), PHP, or JSON
hmac_key: HMAC key to use for protecting the serialized blob
If these new values are not specified, behavior remains
unchanged (PHP serialization with no HMAC protection).
Bug: T233963
Change-Id: Ia2625c04e08cfe9616569500f1d613be73c170a2
assertEquals( false, … ) still succeeds when the actual value is 0, null,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.
Note this patch previously also touched assertSame( false ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertFalse()
and assertSame( false ) are functionally identical.
Change-Id: Ic5f1c7d504e7249002d3184520012e03313137b4
The code previously here did not work well as it merely forwarded the
hash from the current web request. This had numerous issues:
1. It was often null because requests for stylesheets do not cary
a version hash.
2. When requested by JavaScript, the version hash would be a
combination-hash of many unrelated modules, thus when requested as
part of different batches, it would produce different urls which
is not ideal.
The impact of this is minimal currently because we basically never use
these urls, as SVGs are almost always embedded instead of ref'ed by url.
PNG urls are only generated for non-JS modules and then only used in older
browsers not supporting SVG. And, even after all that, for the edge case
of an SVG being ref'ed by url, they would be stored in LocalStorage by
mw.loader with the name+version of the module the image belonged to, not
the version hash of the batch request it came with.
Which means that, yes, localstorage key for "somemodule+someversion" would
have different values for different users, based on which batch the value
came with, because the image urls were using the version hash of the batch
request from ResourceLoaderContext. This is weird, but didn't cause bugs
or inefficiencies because the user would never be exposed to the other
possible urls for that image because we always check LocalStorage first.
It did cause fragmentation server-side in Varnish, though.
This is all fixed now by always including a version, and setting it to
the version of the module. This means there is no more Varnish fragmentation
for these. And it means that browsers are now allowed to cache the images
served from these urls for 30+ days (immutable) instead of only 5min,
which is what happened when they didn't have a version parameter (or set to
null).
Bug: T233343
Change-Id: I4af7fda03698ed4c288d154e7787fb2f3cbbe6c5
assertEquals( null, … ) still succeeds when the actual value is 0, false,
an empty string, even an empty array. All these should be reported as a
failure, I would argue.
Note this patch previously also touched assertSame( null ). I reverted
these. The only benefit would have been consistency within this codebase,
but there is no strict reason to prefer one over the other. assertNull()
and assertSame( null ) are functionally identical.
Change-Id: I92102e833a8bc6af90b9516826abf111e2b79aac
The variable is also read in a few other places, such as to
export the value from api.php (siteinfo) and load.php (mw.config)
but those requests don't need to be held back by this extra
logic.
Alternatively, if we really want to require this for all consumption,
we should probably let PathRouter provide the value and require
consumers to use it. E.g. services->getPathRouter->getArticlePath,
or something like that.
As easy first step, I'm moving it to PathRouter, called from
WebRequest::getPathInfo which is still called on all index.php
requests for any wiki page action in any namespace (incl Special)
when the wiki uses anything other than the default 'index.php?title='
article path.
Test Plan:
* Set '$wgArticlePath = 'bla';`
* View /mediawiki/index.php/Main_Page, and observe the fatal
error message (same as before this change).
Bug: T189966
Change-Id: Id06c2557e2addb58faeef0b6f7767a65b8de55a5
assertSame() is guaranteed to never do any magic type conversion.
This can be critical when accidentially comparing empty strings (a
value PHP considers to be "falsy") to false, 0, 0.0, null, and such.
Change-Id: I2e2685c5992cae252f629a68ffe1a049f2e5ed1b
assertSame() is guaranteed to not do any type conversion. This can be
critical when acciden tially comparing, for example, 0 to 0.0.
Change-Id: Iffcc9bda69573623ba14af655dcd697d0fcce525
Just handle a HEAD request as a GET request, if no specific HEAD handler
exists. This is simple and similar to what the rest of MediaWiki does in
response to a HEAD request.
Bug: T226043
Change-Id: I7b2bd657c20b56844459874131a3d85fabe7db3d
* Add ResponseFactory::createLocalizedHttpError(), which generates a
JSON response body from a MessageValue
* ResponseFactory::__construct() accepts an array of TextFormatter
objects. For ease of testing, the array may be empty. The integrated
ResponseFactory has a TextFormatter for English, and one for
$wgContLang if that is different.
* Use createLocalizedHttpError() to show helpful error messages for
errors generated by Router.
Change-Id: I897a0aee42227916c568333ab384966f1b87f599
Parameter validation is based on parameter definitions like those in the
Action API, using the new ParamValidator library. Handlers should use
the provided Handler methods to access parameters rather than fetching
them directly from the RequestInterface.
Body validation allows the handler to have the (non-form-data) body of a
request parsed and validated. The only validator included in this patch
ignores the body entirely; future patches may implement validation for
JSON bodies based on JSON schemas, or the like.
Bug: T223239
Change-Id: I3c37ea2b432840514b6bff90007c8403989225d5
100% unit test coverage for FileJournal and NullFileJournal. 100%
integration test coverage for DBFileJournal. Unit tests for
DBFileJournal once it supports injection.
I removed FileJournal and NullFileJournal from the list of classes that
FileBackendTest tests. It doesn't actually test them, it just happens to
run code from them without checking its correctness at all.
Depends-On: Ic22075bb5e81b7c2c4c1b8647547aa55306a10a7
Change-Id: I46d10ab7b87c23937aa04d7ec1922abfcf3bd611
This code didn't work because the $GLOBALS array is exposed by reference.
Once this reference was broken by unset(), the rest just manipulated a
local array that happens to be called "GLOBALS". It must not be unset or
re-assigned. It can only be changed in-place.
Before this, the execution of a MediaWikiUnitTestCase test stored a
copy of GLOBALS in unitGlobals, then lost the GLOBALS pointer and
created a new variable called "GLOBALS". As such, the tearDown() function
didn't do what it meant to do, either – which then results in odd
failures like T230023
Rewrite it as follows:
* In setup, store the current GLOBALS keys and values, then reduce
GLOBALS to only the whitelisted keys and values.
* In teardown, restore the original state.
* As optimisation, do this from setUpBeforeClass as well, so that
there are relatively few globals to reset between tests.
(Thanks @Simetrical!)
The following tests were previously passing by accident under
MediaWikiUnitTestCase but actually did depend on global config.
* MainSlotRoleHandlerTest (…, ContentHandler, $wgContentHandlers)
* SlotRecordTest (…, ContentHandler, $wgContentHandlers)
* WikiReferenceTest (wfParseUrl, $wgUrlProtocols)
* DifferenceEngineSlotDiffRendererTest (DifferenceEngine, wfDebug, …)
* SlotDiffRendererTest (…, ContentHandler, $wgContentHandlers)
* FileBackendDBRepoWrapperTest (wfWikiID, "Backend domain ID not provided")
* JpegMetadataExtractorTest (…, wfDebug, …, LoggerFactory, …)
* ParserFactoryTest (…, wfDebug, …, LoggerFactory, InvalidArgumentException)
* MediaWikiPageNameNormalizerTest (…, wfDebug, …, LoggerFactory, …)
* SiteExporterTest (SiteImporter, wfLogWarning, …)
* SiteImporterTest (Site::newForType, $wgSiteTypes)
* ZipDirectoryReaderTest (…, wfDebug, …, LoggerFactory, …)
Bug: T230023
Change-Id: Ic22075bb5e81b7c2c4c1b8647547aa55306a10a7
This is just a shortcut for a commonly-used pattern, when you want to
create a mock that's never supposed to have methods called.
Change-Id: Ia7267e3d3108c1ff94485f7e44bf409808a762be
100% coverage except for one bit of the code that I didn't understand.
Unit tests to come, together with rewrite as a service.
Change-Id: Ib01758d994a9e5587a4fcb5edc3d80010ef05615
100% test coverage of code that appears to be working and used, in both
LockManagerGroupFactory and also LockManagerGroup. Where possible I
wrote it as unit tests. One preexisting code path seems to be broken and
I marked the test as skipped. Two methods look unused and perhaps not
especially helpful, so I didn't write tests for them yet in case we want
to just get rid of them instead.
Change-Id: Iaa7354f31c451b87773468609c674a3bf1d4382f