Hygiene: Dependency Injection for Popups

Changes:
 - removed ugly PopupsContext::getInstance
 - removed ugly PopupsContextTestWrapper helper
 - defined all services inside ServiceWirings
 - fixed unit tests to test classes directly or use MediawikiServices

Change-Id: Ie27e28bb07aebe01014848c290369b1b1f098e9b
This commit is contained in:
Piotr Miazga 2017-07-21 19:06:08 +02:00 committed by Jdlrobson
parent 7431854374
commit 3d0c5b1cc3
8 changed files with 118 additions and 155 deletions

View file

@ -132,5 +132,8 @@
"localBasePath": "",
"remoteExtPath": "Popups"
},
"ServiceWiringFiles": [
"includes/ServiceWirings.php"
],
"manifest_version": 1
}

View file

@ -20,14 +20,10 @@
*/
namespace Popups;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use ExtensionRegistry;
use Config;
use Popups\EventLogging\EventLogger;
use Popups\EventLogging\EventLoggerFactory;
use Popups\EventLogging\MWEventLogger;
use Popups\EventLogging\NullLogger;
/**
* Popups Module
@ -89,9 +85,8 @@ class PopupsContext {
* @param EventLogger $eventLogger A logger capable of logging EventLogging
* events
*/
protected function __construct( Config $config, ExtensionRegistry $extensionRegistry,
public function __construct( Config $config, ExtensionRegistry $extensionRegistry,
PopupsGadgetsIntegration $gadgetsIntegration, EventLogger $eventLogger ) {
/** @todo Use MediaWikiServices Service Locator when it's ready */
$this->extensionRegistry = $extensionRegistry;
$this->gadgetsIntegration = $gadgetsIntegration;
$this->eventLogger = $eventLogger;
@ -99,27 +94,6 @@ class PopupsContext {
$this->config = $config;
}
/**
* Get a PopupsContext instance
*
* @return PopupsContext
*/
public static function getInstance() {
if ( !self::$instance ) {
/** @todo Use MediaWikiServices Service Locator when it's ready */
$registry = ExtensionRegistry::getInstance();
$config = MediaWikiServices::getInstance()->getConfigFactory()
->makeConfig( self::EXTENSION_NAME );
$gadgetsIntegration = new PopupsGadgetsIntegration( $config, $registry );
$eventLoggerFactory = new EventLoggerFactory( $config, $registry );
self::$instance = new PopupsContext( $config, $registry,
$gadgetsIntegration, $eventLoggerFactory->get() );
}
return self::$instance;
}
/**
* @param \User $user User whose gadgets settings are being checked
* @return bool
@ -188,16 +162,7 @@ class PopupsContext {
* @return \Psr\Log\LoggerInterface
*/
public function getLogger() {
return LoggerFactory::getInstance( self::LOGGER_CHANNEL );
}
/**
* Get Module config
*
* @return \Config
*/
public function getConfig() {
return $this->config;
return MediaWikiServices::getInstance()->getService( 'Popups.Logger' );
}
/**

View file

@ -20,6 +20,7 @@
*/
namespace Popups;
use MediaWiki\MediaWikiServices;
use User;
use OutputPage;
use Skin;
@ -40,7 +41,9 @@ class PopupsHooks {
*/
static function onGetBetaPreferences( User $user, array &$prefs ) {
global $wgExtensionAssetsPath;
if ( PopupsContext::getInstance()->isBetaFeatureEnabled() !== true ) {
/** @var PopupsContext $context */
$context = MediaWikiServices::getInstance()->getService( 'Popups.Context' );
if ( $context->isBetaFeatureEnabled() !== true ) {
return;
}
$prefs[PopupsContext::PREVIEWS_BETA_PREFERENCE_NAME] = [
@ -65,7 +68,7 @@ class PopupsHooks {
* @param array &$prefs Preferences description array, to be fed to a HTMLForm object
*/
static function onGetPreferences( User $user, array &$prefs ) {
$context = PopupsContext::getInstance();
$context = MediaWikiServices::getInstance()->getService( 'Popups.Context' );
if ( !$context->showPreviewsOptInOnPreferencesPage() ) {
return;
@ -108,17 +111,17 @@ class PopupsHooks {
* @return bool
*/
public static function onBeforePageDisplay( OutputPage &$out, Skin &$skin ) {
$module = PopupsContext::getInstance();
$context = MediaWikiServices::getInstance()->getService( 'Popups.Context' );
$user = $out->getUser();
if ( !$module->areDependenciesMet() ) {
$logger = $module->getLogger();
if ( !$context->areDependenciesMet() ) {
$logger = $context->getLogger();
$logger->error( 'Popups requires the PageImages and TextExtracts extensions. '
. 'If Beta mode is on it requires also BetaFeatures extension' );
return true;
}
if ( !$module->isBetaFeatureEnabled() || $module->shouldSendModuleToUser( $user ) ) {
if ( !$context->isBetaFeatureEnabled() || $context->shouldSendModuleToUser( $user ) ) {
$out->addModules( [ 'ext.popups' ] );
}
@ -129,7 +132,7 @@ class PopupsHooks {
* @param array &$vars Array of variables to be added into the output of the startup module
*/
public static function onResourceLoaderGetConfigVars( array &$vars ) {
$conf = PopupsContext::getInstance()->getConfig();
$conf = MediaWikiServices::getInstance()->getService( 'Popups.Config' );
$vars['wgPopupsSchemaSamplingRate'] = $conf->get( 'PopupsSchemaSamplingRate' );
$vars['wgPopupsBetaFeature'] = $conf->get( 'PopupsBetaFeature' );
$vars['wgPopupsGateway'] = $conf->get( 'PopupsGateway' );
@ -150,11 +153,11 @@ class PopupsHooks {
* @param OutputPage $out OutputPage instance calling the hook
*/
public static function onMakeGlobalVariablesScript( array &$vars, OutputPage $out ) {
$module = PopupsContext::getInstance();
$context = MediaWikiServices::getInstance()->getService( 'Popups.Context' );
$user = $out->getUser();
$vars['wgPopupsShouldSendModuleToUser'] = $module->shouldSendModuleToUser( $user );
$vars['wgPopupsConflictsWithNavPopupGadget'] = $module->conflictsWithNavPopupsGadget(
$vars['wgPopupsShouldSendModuleToUser'] = $context->shouldSendModuleToUser( $user );
$vars['wgPopupsConflictsWithNavPopupGadget'] = $context->conflictsWithNavPopupsGadget(
$user );
}
@ -164,8 +167,9 @@ class PopupsHooks {
* @param array &$wgDefaultUserOptions Reference to default options array
*/
public static function onUserGetDefaultOptions( &$wgDefaultUserOptions ) {
$context = MediaWikiServices::getInstance()->getService( 'Popups.Context' );
$wgDefaultUserOptions[ PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME ] =
PopupsContext::getInstance()->getDefaultIsEnabledState();
$context->getDefaultIsEnabledState();
}
}

View file

@ -0,0 +1,44 @@
<?php
use MediaWiki\MediaWikiServices;
use Popups\PopupsContext;
use Popups\PopupsGadgetsIntegration;
use Popups\EventLogging\EventLoggerFactory;
use Popups\UserPreferencesChangeHandler;
use \MediaWiki\Logger\LoggerFactory;
return [
'Popups.Config' => function ( MediaWikiServices $services ) {
return $services->getService( 'ConfigFactory' )
->makeConfig( PopupsContext::EXTENSION_NAME );
},
'Popups.GadgetsIntegration' => function ( MediaWikiServices $services ) {
return new PopupsGadgetsIntegration(
$services->getService( 'Popups.Config' ),
ExtensionRegistry::getInstance()
);
},
'Popups.EventLogger' => function ( MediaWikiServices $serivces ) {
$factory = new EventLoggerFactory(
$serivces->getService( 'Popups.Config' ),
ExtensionRegistry::getInstance()
);
return $factory->get();
},
'Popups.UserPreferencesChangeHandler' => function ( MediaWikiServices $services ) {
return new UserPreferencesChangeHandler(
$services->getService( 'Popups.Context' )
);
},
'Popups.Logger' => function ( MediaWikiServices $services ) {
return LoggerFactory::getInstance( PopupsContext::LOGGER_CHANNEL );
},
'Popups.Context' => function ( MediaWikiServices $services ) {
return new PopupsContext(
$services->getService( 'Popups.Config' ),
ExtensionRegistry::getInstance(),
$services->getService( 'Popups.GadgetsIntegration' ),
$services->getService( 'Popups.EventLogger' )
);
}
];

View file

@ -20,6 +20,7 @@
*/
namespace Popups;
use MediaWiki\MediaWikiServices;
use User;
use PreferencesForm;
@ -29,10 +30,6 @@ use PreferencesForm;
* @package Popups
*/
class UserPreferencesChangeHandler {
/**
* @var UserPreferencesChangeHandler
*/
private static $instance;
/**
* @var PopupsContext
*/
@ -42,7 +39,7 @@ class UserPreferencesChangeHandler {
* UserPreferencesChangeHandler constructor.
* @param PopupsContext $context Popups context instance
*/
public function __construct( PopupsContext $context ) {
public function __construct( $context ) {
$this->popupsContext = $context;
}
@ -70,10 +67,7 @@ class UserPreferencesChangeHandler {
* @return UserPreferencesChangeHandler
*/
private static function newFromGlobalState() {
if ( self::$instance === null ) {
self::$instance = new UserPreferencesChangeHandler( PopupsContext::getInstance() );
}
return self::$instance;
return MediaWikiServices::getInstance()->getService( 'Popups.UserPreferencesChangeHandler' );
}
/**

View file

@ -18,7 +18,6 @@
* @file
* @ingroup extensions
*/
require_once 'PopupsContextTestWrapper.php';
use Popups\PopupsContext;
@ -35,11 +34,30 @@ class PopupsContextTest extends MediaWikiTestCase {
*/
const ANONYMOUS_USER = 0;
public function tearDown() {
PopupsContextTestWrapper::resetTestInstance();
parent::tearDown();
/**
* Helper method to quickly build Popups Context
* @param ExtensionRegistry|null $registry
* @param \Popups\PopupsGadgetsIntegration|null $integration
* @param \Popups\EventLogging\EventLogger $eventLogger
* @return PopupsContext
*/
protected function getContext( $registry = null, $integration = null, $eventLogger = null ) {
$config = new GlobalVarConfig();
$registry = $registry ?: ExtensionRegistry::getInstance();
if ( $eventLogger === null ) {
$eventLogger = $this->getMockBuilder( \Popups\EventLogging\EventLogger::class )
->getMock();
}
if ( $integration === null ) {
$integration = $this->getMockBuilder( \Popups\PopupsGadgetsIntegration::class )
->disableOriginalConstructor()
->setMethods( [ 'conflictsWithNavPopupsGadget' ] )
->getMock();
$integration->method( 'conflictsWithNavPopupsGadget' )
->willReturn( false );
}
return new PopupsContext( $config, $registry, $integration, $eventLogger );
}
/**
* @covers ::showPreviewsOptInOnPreferencesPage
* @dataProvider provideConfigForShowPreviewsInOptIn
@ -48,32 +66,10 @@ class PopupsContextTest extends MediaWikiTestCase {
*/
public function testShowPreviewsPreferencesPage( $config, $expected ) {
$this->setMwGlobals( $config );
$context = PopupsContext::getInstance();
$context = $this->getContext();
$this->assertEquals( $expected, $context->showPreviewsOptInOnPreferencesPage() );
}
/**
* @covers ::__construct
* @covers ::getConfig
*/
public function testContextAndConfigInitialization() {
$configMock = $this->getMock( Config::class );
$configFactoryMock = $this->getMock( ConfigFactory::class, [ 'makeConfig' ] );
$configFactoryMock->expects( $this->once() )
->method( 'makeConfig' )
->with( PopupsContext::EXTENSION_NAME )
->will( $this->returnValue( $configMock ) );
$mwServices = $this->overrideMwServices();
$mwServices->redefineService( 'ConfigFactory', function () use ( $configFactoryMock ) {
return $configFactoryMock;
} );
$context = PopupsContext::getInstance();
$this->assertSame( $context->getConfig(), $configMock );
}
/**
* @return array
*/
@ -112,7 +108,7 @@ class PopupsContextTest extends MediaWikiTestCase {
$this->setMwGlobals( [
"wgPopupsBetaFeature" => false
] );
$context = PopupsContext::getInstance();
$context = $this->getContext();
$user = $this->getMutableTestUser()->getUser();
$user->setOption( PopupsContext::PREVIEWS_OPTIN_PREFERENCE_NAME, $optIn );
$this->assertEquals( $context->shouldSendModuleToUser( $user ), $expected );
@ -148,14 +144,15 @@ class PopupsContextTest extends MediaWikiTestCase {
$this->setMwGlobals( [
"wgPopupsBetaFeature" => true
] );
$context = PopupsContext::getInstance();
$context = $this->getContext();
$user = $this->getMutableTestUser()->getUser();
$user->setOption( PopupsContext::PREVIEWS_BETA_PREFERENCE_NAME, $optIn );
$this->assertEquals( $context->shouldSendModuleToUser( $user ), $expected );
}
/**
* Check that Page Previews are disabled for anonymous user
* Check tst Page Previews are disabled for anonymous user
* @covers ::shouldSendModuleToUser
* @covers ::isBetaFeatureEnabled
* @dataProvider providerAnonUserHasDisabledPagePreviews
@ -169,7 +166,7 @@ class PopupsContextTest extends MediaWikiTestCase {
"wgPopupsBetaFeature" => $betaFeatureEnabled,
] );
$context = PopupsContext::getInstance();
$context = $this->getContext();
$this->assertEquals( $expected, $context->shouldSendModuleToUser( $user ) );
}
@ -216,7 +213,7 @@ class PopupsContextTest extends MediaWikiTestCase {
$mock->expects( $this->any() )
->method( 'isLoaded' )
->will( new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls( $returnValues ) );
$context = new PopupsContextTestWrapper( new GlobalVarConfig(), $mock );
$context = $this->getContext( $mock );
$this->assertEquals( $expected, $context->areDependenciesMet() );
}
@ -267,27 +264,6 @@ class PopupsContextTest extends MediaWikiTestCase {
]
];
}
/**
* @covers ::getLogger
*/
public function testGetLogger() {
$loggerMock = $this->getMock( \Psr\Log\LoggerInterface::class );
$this->setLogger( PopupsContext::LOGGER_CHANNEL, $loggerMock );
$context = PopupsContext::getInstance();
$this->assertSame( $loggerMock, $context->getLogger() );
}
/**
* @covers ::getInstance
*/
public function testGetInstanceReturnsSameObjectEveryTime() {
$first = PopupsContext::getInstance();
$second = PopupsContext::getInstance();
$this->assertSame( $first, $second );
$this->assertInstanceOf( PopupsContext::class, $first );
}
/**
* @covers ::getDefaultIsEnabledState
@ -296,7 +272,8 @@ class PopupsContextTest extends MediaWikiTestCase {
$this->setMwGlobals( [
'wgPopupsOptInDefaultState' => "2"
] );
$this->assertEquals( "2", PopupsContext::getInstance()->getDefaultIsEnabledState() );
$context = $this->getContext();
$this->assertEquals( "2", $context->getDefaultIsEnabledState() );
}
/**
@ -315,8 +292,7 @@ class PopupsContextTest extends MediaWikiTestCase {
->with( $user )
->willReturn( true );
$context = new PopupsContextTestWrapper( $this->getConfigMock(),
ExtensionRegistry::getInstance(), $integrationMock );
$context = $this->getContext( null, $integrationMock );
$this->assertEquals( true, $context->conflictsWithNavPopupsGadget( $user ) );
}
@ -327,24 +303,9 @@ class PopupsContextTest extends MediaWikiTestCase {
$loggerMock = $this->getMock( \Popups\EventLogging\EventLogger::class );
$loggerMock->expects( $this->once() )
->method( 'log' );
$integrationMock = $this->getMockBuilder( \Popups\PopupsGadgetsIntegration::class )
->disableOriginalConstructor()
->setMethods( [ 'conflictsWithNavPopupsGadget' ] )
->getMock();
$context = new PopupsContextTestWrapper( $this->getConfigMock(),
ExtensionRegistry::getInstance(), $integrationMock, $loggerMock );
$context = $this->getContext( null, null, $loggerMock );
$context->logUserDisabledPagePreviewsEvent();
}
/**
* @return PHPUnit_Framework_MockObject_MockObject|Config
*/
private function getConfigMock() {
$mock = $this->getMockBuilder( 'Config' )
->setMethods( [ 'get', 'has' ] )
->getMock();
return $mock;
}
}

View file

@ -18,7 +18,6 @@
* @file
* @ingroup extensions
*/
require_once 'PopupsContextTestWrapper.php';
use Popups\PopupsContext;
use Popups\PopupsHooks;
@ -31,7 +30,6 @@ use Popups\PopupsHooks;
class PopupsHooksTest extends MediaWikiTestCase {
protected function tearDown() {
PopupsContextTestWrapper::resetTestInstance();
parent::tearDown();
}
@ -63,7 +61,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
* @covers ::onGetPreferences
*/
public function testOnGetPreferencesPreviewsDisabled() {
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->disableOriginalConstructor()
->setMethods( [ 'showPreviewsOptInOnPreferencesPage' ] )
->getMock();
@ -71,7 +69,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'showPreviewsOptInOnPreferencesPage' )
->will( $this->returnValue( false ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
$prefs = [ 'someNotEmptyValue' => 'notEmpty' ];
PopupsHooks::onGetPreferences( $this->getTestUser()->getUser(), $prefs );
@ -84,7 +82,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
*/
public function testOnGetPreferencesNavPopupGadgetIsOn() {
$userMock = $this->getTestUser()->getUser();
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->disableOriginalConstructor()
->setMethods( [ 'showPreviewsOptInOnPreferencesPage', 'conflictsWithNavPopupsGadget' ] )
->getMock();
@ -98,7 +96,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->with( $userMock )
->will( $this->returnValue( true ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
$prefs = [];
PopupsHooks::onGetPreferences( $this->getTestUser()->getUser(), $prefs );
@ -114,7 +112,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
* @covers ::onGetPreferences
*/
public function testOnGetPreferencesPreviewsEnabled() {
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->disableOriginalConstructor()
->setMethods( [ 'showPreviewsOptInOnPreferencesPage', 'conflictsWithNavPopupsGadget' ] )
->getMock();
@ -126,7 +124,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'conflictsWithNavPopupsGadget' )
->will( $this->returnValue( false ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
$prefs = [
'skin' => 'skin stuff',
'someNotEmptyValue' => 'notEmpty',
@ -145,7 +143,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
* @covers ::onGetPreferences
*/
public function testOnGetPreferencesPreviewsEnabledWhenSkinIsNotAvailable() {
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->disableOriginalConstructor()
->setMethods( [ 'showPreviewsOptInOnPreferencesPage', 'conflictsWithNavPopupsGadget' ] )
->getMock();
@ -157,7 +155,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'conflictsWithNavPopupsGadget' )
->will( $this->returnValue( false ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
$prefs = [
'someNotEmptyValue' => 'notEmpty',
'other' => 'notEmpty'
@ -202,7 +200,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
$userOptions = [
'test' => 'not_empty'
];
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->setMethods( [ 'getDefaultIsEnabledState' ] )
->disableOriginalConstructor()
->getMock();
@ -211,7 +209,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'getDefaultIsEnabledState' )
->willReturn( true );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
PopupsHooks::onUserGetDefaultOptions( $userOptions );
$this->assertCount( 2, $userOptions );
@ -231,7 +229,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
$loggerMock->expects( $this->once() )
->method( 'error' );
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->disableOriginalConstructor()
->setMethods( [ 'areDependenciesMet', 'getLogger' ] )
->getMock();
@ -242,7 +240,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'getLogger' )
->will( $this->returnValue( $loggerMock ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
PopupsHooks::onBeforePageDisplay( $outPageMock, $skinMock );
}
@ -279,7 +277,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'addModules' )
->with( [ 'ext.popups' ] );
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->setMethods( [ 'areDependenciesMet', 'isBetaFeatureEnabled', 'shouldSendModuleToUser' ] )
->disableOriginalConstructor()
->getMock();
@ -296,7 +294,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'shouldSendModuleToUser' )
->will( $this->returnValue( $shouldSendModuleToUser ) );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
PopupsHooks::onBeforePageDisplay( $outPageMock, $skinMock );
}
@ -314,7 +312,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->method( 'getUser' )
->willReturn( $user );
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContext::class )
->setMethods( [ 'shouldSendModuleToUser', 'conflictsWithNavPopupsGadget' ] )
->disableOriginalConstructor()
->getMock();
@ -327,7 +325,7 @@ class PopupsHooksTest extends MediaWikiTestCase {
->with( $user )
->willReturn( false );
PopupsContextTestWrapper::injectTestInstance( $contextMock );
$this->setService( 'Popups.Context', $contextMock );
$vars = [];

View file

@ -18,7 +18,6 @@
* @file
* @ingroup extensions
*/
require_once 'PopupsContextTestWrapper.php';
use Popups\PopupsContext;
use Popups\UserPreferencesChangeHandler;
@ -30,18 +29,13 @@ use Popups\UserPreferencesChangeHandler;
*/
class UserPreferencesChangeHandlerTest extends MediaWikiTestCase {
protected function tearDown() {
PopupsContextTestWrapper::resetTestInstance();
parent::tearDown();
}
/**
* @covers ::handle
* @covers ::__construct
* @dataProvider provideDataForEventHandling
*/
public function testEventHandling( $oldOption, $newOption, $expectedMethodCallsCount ) {
$contextMock = $this->getMockBuilder( PopupsContextTestWrapper::class )
$contextMock = $this->getMockBuilder( PopupsContexts::class )
->disableOriginalConstructor()
->setMethods( [ 'logUserDisabledPagePreviewsEvent' ] )
->getMock();