Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4138897
EventDispatchEngineTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
EventDispatchEngineTest.php
View Options
<?php
namespace
MediaWiki\Tests\DomainEvent
;
use
MediaWiki\Deferred\DeferredUpdates
;
use
MediaWiki\DomainEvent\DomainEvent
;
use
MediaWiki\DomainEvent\DomainEventIngress
;
use
MediaWiki\DomainEvent\DomainEventSource
;
use
MediaWiki\DomainEvent\DomainEventSubscriber
;
use
MediaWiki\DomainEvent\EventDispatchEngine
;
use
MediaWiki\Tests\MockDatabase
;
use
MediaWikiUnitTestCase
;
use
Wikimedia\ObjectFactory\ObjectFactory
;
use
Wikimedia\Rdbms\IConnectionProvider
;
use
Wikimedia\Services\ServiceContainer
;
/**
* @covers \MediaWiki\DomainEvent\EventDispatchEngine
*/
class
EventDispatchEngineTest
extends
MediaWikiUnitTestCase
{
private
function
newEvent
(
string
$type
):
DomainEvent
{
return
new
class
(
$type
)
extends
DomainEvent
{
public
function
__construct
(
string
$type
)
{
parent
::
__construct
();
$this
->
declareEventType
(
$type
);
}
};
}
private
function
newConnectionProvider
():
IConnectionProvider
{
$conProv
=
$this
->
createNoOpMock
(
IConnectionProvider
::
class
,
[
'getPrimaryDatabase'
]
);
$db
=
new
MockDatabase
();
$conProv
->
method
(
'getPrimaryDatabase'
)->
willReturnCallback
(
static
function
()
use
(
$db
)
{
return
$db
;
}
);
return
$conProv
;
}
private
function
newDispatchEngine
():
EventDispatchEngine
{
$objectFactory
=
new
ObjectFactory
(
$this
->
createNoOpMock
(
ServiceContainer
::
class
)
);
$engine
=
new
EventDispatchEngine
(
$objectFactory
);
return
$engine
;
}
public
function
testDispatch
()
{
$engine
=
$this
->
newDispatchEngine
();
$conProv
=
$this
->
newConnectionProvider
();
$callCount
=
0
;
$engine
->
registerListener
(
'Tested'
,
static
function
(
DomainEvent
$event
)
use
(
&
$callCount
)
{
$callCount
++;
}
);
$dbw
=
$conProv
->
getPrimaryDatabase
();
$dbw
->
begin
();
$event
=
$this
->
newEvent
(
'Tested'
);
$engine
->
dispatch
(
$event
,
$conProv
);
$dbw
->
commit
();
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
1
,
$callCount
,
'Listener should have been called'
);
}
public
function
testWildcardListener
()
{
$engine
=
$this
->
newDispatchEngine
();
$conProv
=
$this
->
newConnectionProvider
();
$callCount
=
0
;
$engine
->
registerListener
(
DomainEvent
::
ANY
,
// register for any event
static
function
()
use
(
&
$callCount
)
{
$callCount
++;
}
);
$engine
->
dispatch
(
$this
->
newEvent
(
'Tested1'
),
$conProv
);
$engine
->
dispatch
(
$this
->
newEvent
(
'Tested2'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
2
,
$callCount
,
'Listener should have been called'
);
}
/**
* Assert that listeners registered in INVOKE_AFTER_COMMIT mode will
* not be invoked if the transaction is rolled back, but listeners
* registered as INVOKE_BEFORE_COMMIT are still invoked.
*/
public
function
testRollback
()
{
$engine
=
$this
->
newDispatchEngine
();
$conProv
=
$this
->
newConnectionProvider
();
$callCount
=
0
;
$engine
->
registerListener
(
'Tested'
,
static
function
(
DomainEvent
$event
,
IConnectionProvider
$conProv
)
use
(
&
$callCount
)
{
$callCount
++;
}
);
$dbw
=
$conProv
->
getPrimaryDatabase
();
$dbw
->
begin
();
$event
=
$this
->
newEvent
(
'Tested'
);
$engine
->
dispatch
(
$event
,
$conProv
);
$dbw
->
rollback
();
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
0
,
$callCount
,
'After-commit listener should not have been called'
);
}
public
function
testRegisterSubscriber
()
{
$engine
=
$this
->
newDispatchEngine
();
$trace
=
[];
$fooListener
=
static
function
()
use
(
&
$trace
)
{
$trace
[]
=
'fooListener'
;
};
$subscriber
=
$this
->
createMock
(
DomainEventSubscriber
::
class
);
$subscriber
->
method
(
'registerListeners'
)->
willReturnCallback
(
static
function
(
DomainEventSource
$source
)
use
(
$fooListener
,
&
$trace
)
{
$trace
[]
=
'registerListeners'
;
$source
->
registerListener
(
'FooComplete'
,
$fooListener
);
}
);
$engine
->
registerSubscriber
(
$subscriber
);
$conProv
=
$this
->
newConnectionProvider
();
$engine
->
dispatch
(
$this
->
newEvent
(
'Xyzzy'
),
$conProv
);
$engine
->
dispatch
(
$this
->
newEvent
(
'FooComplete'
),
$conProv
);
$engine
->
dispatch
(
$this
->
newEvent
(
'Foobar'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
[
'registerListeners'
,
'fooListener'
],
$trace
);
}
public
function
testRegisterSubscriber_lazy
()
{
$engine
=
$this
->
newDispatchEngine
();
$trace
=
[];
$fooListener
=
static
function
()
use
(
&
$trace
)
{
$trace
[]
=
'fooListener'
;
};
$barListener
=
static
function
()
use
(
&
$trace
)
{
$trace
[]
=
'barListener'
;
};
$subscriber
=
$this
->
createMock
(
DomainEventSubscriber
::
class
);
$subscriber
->
method
(
'registerListeners'
)->
willReturnCallback
(
static
function
(
DomainEventSource
$source
)
use
(
$fooListener
,
$barListener
,
&
$trace
)
{
$trace
[]
=
'registerListeners'
;
$source
->
registerListener
(
'FooComplete'
,
$fooListener
);
$source
->
registerListener
(
'BarComplete'
,
$barListener
);
}
);
$engine
->
registerSubscriber
(
[
'factory'
=>
static
function
()
use
(
$subscriber
)
{
return
$subscriber
;
},
'events'
=>
[
'FooComplete'
,
'BarComplete'
]
]
);
$conProv
=
$this
->
newConnectionProvider
();
$engine
->
dispatch
(
$this
->
newEvent
(
'Xyzzy'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
[],
$trace
);
$engine
->
dispatch
(
$this
->
newEvent
(
'FooComplete'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
// Subscriber and listener should have been called.
$this
->
assertSame
(
[
'registerListeners'
,
'fooListener'
],
$trace
);
$engine
->
dispatch
(
$this
->
newEvent
(
'BarComplete'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
// The subscriber must not get called again, even if the event is
// triggered for the first time.
$this
->
assertSame
(
[
'registerListeners'
,
'fooListener'
,
'barListener'
,
],
$trace
);
}
public
function
testRegisterSubscriber_recursive
()
{
$engine
=
$this
->
newDispatchEngine
();
$trace
=
[];
$fooListener
=
static
function
()
use
(
&
$trace
)
{
$trace
[]
=
'fooListener'
;
};
$subscriber1
=
$this
->
createMock
(
DomainEventSubscriber
::
class
);
$subscriber2
=
$this
->
createMock
(
DomainEventSubscriber
::
class
);
$subscriber1
->
method
(
'registerListeners'
)->
willReturnCallback
(
static
function
(
DomainEventSource
$source
)
use
(
$subscriber2
,
&
$trace
)
{
$trace
[]
=
'registerListeners1'
;
$source
->
registerSubscriber
(
[
'factory'
=>
static
function
()
use
(
$subscriber2
)
{
return
$subscriber2
;
},
'events'
=>
[
'FooComplete'
]
]
);
}
);
$subscriber2
->
method
(
'registerListeners'
)->
willReturnCallback
(
static
function
(
DomainEventSource
$source
)
use
(
$fooListener
,
&
$trace
)
{
$trace
[]
=
'registerListeners2'
;
$source
->
registerListener
(
'FooComplete'
,
$fooListener
);
}
);
$engine
->
registerSubscriber
(
[
'factory'
=>
static
function
()
use
(
$subscriber1
)
{
return
$subscriber1
;
},
'events'
=>
[
'FooComplete'
]
]
);
$conProv
=
$this
->
newConnectionProvider
();
$engine
->
dispatch
(
$this
->
newEvent
(
'FooComplete'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
// Both subscribers should have been resolved
$this
->
assertSame
(
[
'registerListeners1'
,
'registerListeners2'
,
'fooListener'
,
],
$trace
);
}
public
function
testRegisterSubscriber_automatic
()
{
$engine
=
$this
->
newDispatchEngine
();
$trace
=
[];
$subscriber
=
new
class
(
$trace
)
extends
DomainEventIngress
{
private
$trace
;
public
function
__construct
(
&
$trace
)
{
$this
->
trace
=&
$trace
;
}
public
function
handleFooCompleteEvent
()
{
$this
->
trace
[]
=
'afterFooComplete'
;
}
};
// The dispatcher should inject the list of events into $subscriber by
// calling the initSubscriber() method.
$engine
->
registerSubscriber
(
[
'events'
=>
[
'FooComplete'
],
'factory'
=>
static
function
()
use
(
$subscriber
)
{
return
$subscriber
;
}
]
);
$conProv
=
$this
->
newConnectionProvider
();
$engine
->
dispatch
(
$this
->
newEvent
(
'FooComplete'
),
$conProv
);
DeferredUpdates
::
doUpdates
();
$this
->
assertSame
(
[
'afterFooComplete'
],
$trace
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Wed, Aug 19, 14:51 (3 w, 4 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a9/91/b5bc0eb129ae17198c0dd4f2f820
Default Alt Text
EventDispatchEngineTest.php (7 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment