==TODONE
[] Introduce MediaWikiServices to MobileFrontend (819064d)
[] Make a Config service for retrieving the Config object (and use it in MobileContext) (819064d)
==TODO
~~Audit `MobileContext#getMFConfig` calls, especially those that are outside of `MobileContext` and `MobileFrontendHooks`~~
~~Audit `MobileContext::setInstance` calls~~
~~Make MobileContext construction via Services and inject Config via constructor (6b03ac3)~~
See T143875.
* Extract:
[] the `MobileFrontend.DeviceFormFactorDetector` service and class (T143891)
[] the `PageBlacklistService` class (and service)
[] the `MobileFrontendRequest` object
[] Discuss action/controller terminology with the team (@Jhernandez)
…
---
From email:
> After some discussion of the [Dependency Injection RFC](https://phabricator.wikimedia.org/T384) at this year's MediaWiki Dev Summit, [a top-level service locator/dependency injection container](https://github.com/wikimedia/mediawiki/blob/master/includes/MediaWikiServices.php#L69), the `MediaWikiServices` class, was added to the MediaWiki codebase in April, along with with [a helpful note about migrating hook handlers to allow unit testing](https://github.com/wikimedia/mediawiki/blob/master/docs/injection.txt#L212-L224) (testing in isolation). That `MediaWikiServices` is a service locator provides us the path to migrate from what we have to loosely-coupled, more readily testable objects.
>
> The classes that would benefit from this the most are: the MobileContext singleton and [god object](https://en.wikipedia.org/wiki/God_object); and the `MobileFrontendHooks` class, which relies on global state, by way of `MobileContext`, and groups together many disparate [hook handlers that often do far too much](https://github.com/wikimedia/mediawiki-extensions-MobileFrontend/blob/master/includes/MobileFrontend.hooks.php#L84-L139). These two classes include a lot of application and business – non-profit? – logic, which is mostly exercised in our acceptance tests and by hand, with the former doubling as integration tests. That isn't to downplay our suite of acceptance tests. However, they're slow, expensive, and unreliable. While we should be able to depend on our acceptance tests, we shouldn't have to depend on them to test business logic when we have the facility to write fast, cheap unit tests.
>
> As for `MobileContext` and `MobileFrontendHooks`: I'd like to propose a goal and a plan for migrating each to make use of `MediaWikiServices` wherever necessary.
>
> In no particular order, `MobileContext` should be split into:
>
> * a `DeviceService` class, which provides information about the UA
> * a `FeaturesService` class, which provides information about the current features enabled in MobileFrontend
> * a `MobileFrontendRequest`, which proxies the main Request object, providing useful accessor methods (e.g. `MobileFrontendRequest#getMobileAction`)
> * a `PageBlacklistService` class, which tests whether or not a title or category is blacklisted
> * a number of actions – controllers, I guess – which correspond to the setting or unsetting of the `mf_useformat`, `stopMobileRedirect`, and `disableImages` cookies
> * a number of functions for manipulating URLs so that they conform with [`$wgMobileUrlTemplate`](https://github.com/wikimedia/mediawiki-extensions-MobileFrontend/#wgmobileurltemplate)
>
>For each of the above, we'd:
>
> * make an exhaustive list of the clients of the methods
> * cover the associated methods with tests
> * extract the methods and their dependencies, providing a compatibility layer so that the tests still pass
> * migrate the tests to unit tests
> * migrate the clients of the methods
>
>For `MobileFrontendHooks`, there are some hook handlers than can be migrated by following the helpful note above verbatim, creating a class per hook, obeying the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle) (SRP). For those hook handlers that do too much, they can be broken into separate classes, i.e. creating multiple classes per hook, which are then grouped by namespace, e.g. `MobileFrontend\Images\MakeGlobalVariablesScriptHookHandler` and `MobileFrontend\Wikibase\MakeGlobalVariablesScriptHookHandler`. Regardless, to migrate a hook we'd:
>
> * cover the hook with tests
> * extract the hook, following the helpful note, and providing a compatibility layer so that the tests still pass
> * migrate the tests to unit tests
>
>It's important to remember that both classes can be migrated method by method. I'll be writing up epics for the high-level goal of migrating these classes, including examples, and I imagine we'll create task for each method (or couple of methods) as we investigate them.