Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4151521
SlotRecordTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
SlotRecordTest.php
View Options
<?php
namespace
MediaWiki\Tests\Revision
;
use
DummyContentForTesting
;
use
InvalidArgumentException
;
use
LogicException
;
use
MediaWiki\Revision\IncompleteRevisionException
;
use
MediaWiki\Revision\SlotRecord
;
use
MediaWiki\Revision\SuppressedDataException
;
use
MediaWikiUnitTestCase
;
/**
* @covers \MediaWiki\Revision\SlotRecord
*/
class
SlotRecordTest
extends
MediaWikiUnitTestCase
{
private
function
makeRow
(
$data
=
[]
)
{
$data
=
$data
+
[
'slot_id'
=>
1234
,
'slot_content_id'
=>
33
,
'content_size'
=>
'5'
,
'content_sha1'
=>
'someHash'
,
'content_address'
=>
'tt:456'
,
'model_name'
=>
DummyContentForTesting
::
MODEL_ID
,
'format_name'
=>
CONTENT_FORMAT_WIKITEXT
,
'slot_revision_id'
=>
'2'
,
'slot_origin'
=>
'1'
,
'role_name'
=>
'myRole'
,
];
return
(
object
)
$data
;
}
public
function
testCompleteConstruction
()
{
$row
=
$this
->
makeRow
();
$record
=
new
SlotRecord
(
$row
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
assertTrue
(
$record
->
hasAddress
()
);
$this
->
assertTrue
(
$record
->
hasContentId
()
);
$this
->
assertTrue
(
$record
->
hasRevision
()
);
$this
->
assertTrue
(
$record
->
isInherited
()
);
$this
->
assertSame
(
'A'
,
$record
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
5
,
$record
->
getSize
()
);
$this
->
assertSame
(
'someHash'
,
$record
->
getSha1
()
);
$this
->
assertSame
(
DummyContentForTesting
::
MODEL_ID
,
$record
->
getModel
()
);
$this
->
assertSame
(
2
,
$record
->
getRevision
()
);
$this
->
assertSame
(
1
,
$record
->
getOrigin
()
);
$this
->
assertSame
(
'tt:456'
,
$record
->
getAddress
()
);
$this
->
assertSame
(
33
,
$record
->
getContentId
()
);
$this
->
assertSame
(
CONTENT_FORMAT_WIKITEXT
,
$record
->
getFormat
()
);
$this
->
assertSame
(
'myRole'
,
$record
->
getRole
()
);
$this
->
assertFalse
(
$record
->
isDerived
()
);
}
public
function
testConstructionDeferred
()
{
$row
=
$this
->
makeRow
(
[
'content_size'
=>
null
,
// to be computed
'content_sha1'
=>
null
,
// to be computed
'format_name'
=>
static
function
()
{
return
CONTENT_FORMAT_WIKITEXT
;
},
'slot_revision_id'
=>
'2'
,
'slot_origin'
=>
'2'
,
'slot_content_id'
=>
static
function
()
{
return
null
;
},
]
);
$content
=
static
function
()
{
return
new
DummyContentForTesting
(
'A'
);
};
$record
=
new
SlotRecord
(
$row
,
$content
);
$this
->
assertTrue
(
$record
->
hasAddress
()
);
$this
->
assertTrue
(
$record
->
hasRevision
()
);
$this
->
assertFalse
(
$record
->
hasContentId
()
);
$this
->
assertFalse
(
$record
->
isInherited
()
);
$this
->
assertSame
(
'A'
,
$record
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
1
,
$record
->
getSize
()
);
$this
->
assertNotEmpty
(
$record
->
getSha1
()
);
$this
->
assertSame
(
DummyContentForTesting
::
MODEL_ID
,
$record
->
getModel
()
);
$this
->
assertSame
(
2
,
$record
->
getRevision
()
);
$this
->
assertSame
(
2
,
$record
->
getRevision
()
);
$this
->
assertSame
(
'tt:456'
,
$record
->
getAddress
()
);
$this
->
assertSame
(
CONTENT_FORMAT_WIKITEXT
,
$record
->
getFormat
()
);
$this
->
assertSame
(
'myRole'
,
$record
->
getRole
()
);
$this
->
assertFalse
(
$record
->
isDerived
()
);
}
public
function
testNewUnsaved
()
{
$record
=
SlotRecord
::
newUnsaved
(
'myRole'
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
assertFalse
(
$record
->
hasAddress
()
);
$this
->
assertFalse
(
$record
->
hasContentId
()
);
$this
->
assertFalse
(
$record
->
hasRevision
()
);
$this
->
assertFalse
(
$record
->
isInherited
()
);
$this
->
assertFalse
(
$record
->
hasOrigin
()
);
$this
->
assertSame
(
'A'
,
$record
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
1
,
$record
->
getSize
()
);
$this
->
assertNotEmpty
(
$record
->
getSha1
()
);
$this
->
assertSame
(
DummyContentForTesting
::
MODEL_ID
,
$record
->
getModel
()
);
$this
->
assertSame
(
'myRole'
,
$record
->
getRole
()
);
$this
->
assertFalse
(
$record
->
isDerived
()
);
}
public
static
function
provideInvalidConstruction
()
{
yield
'empty row'
=>
[
(
object
)[],
new
DummyContentForTesting
(
'A'
)
];
yield
'null content'
=>
[
(
object
)[],
null
];
}
/**
* @dataProvider provideInvalidConstruction
*/
public
function
testInvalidConstruction
(
$row
,
$content
)
{
$this
->
expectException
(
InvalidArgumentException
::
class
);
new
SlotRecord
(
$row
,
$content
);
}
public
function
testGetContentId_fails
()
{
$record
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
expectException
(
IncompleteRevisionException
::
class
);
$record
->
getContentId
();
}
public
function
testGetAddress_fails
()
{
$record
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
expectException
(
IncompleteRevisionException
::
class
);
$record
->
getAddress
();
}
public
function
provideIncomplete
()
{
$unsaved
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
yield
'unsaved'
=>
[
$unsaved
];
$parent
=
new
SlotRecord
(
$this
->
makeRow
(),
new
DummyContentForTesting
(
'A'
)
);
$inherited
=
SlotRecord
::
newInherited
(
$parent
);
yield
'inherited'
=>
[
$inherited
];
}
/**
* @dataProvider provideIncomplete
*/
public
function
testGetRevision_fails
(
SlotRecord
$record
)
{
$record
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
expectException
(
IncompleteRevisionException
::
class
);
$record
->
getRevision
();
}
/**
* @dataProvider provideIncomplete
*/
public
function
testGetOrigin_fails
(
SlotRecord
$record
)
{
$record
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
expectException
(
IncompleteRevisionException
::
class
);
$record
->
getOrigin
();
}
public
static
function
provideHashStability
()
{
yield
[
''
,
'phoiac9h4m842xq45sp7s6u21eteeq1'
];
yield
[
'Lorem ipsum'
,
'hcr5u40uxr81d3nx89nvwzclfz6r9c5'
];
}
/**
* @dataProvider provideHashStability
*/
public
function
testHashStability
(
$text
,
$hash
)
{
// Changing the output of the hash function will break things horribly!
$this
->
assertSame
(
$hash
,
SlotRecord
::
base36Sha1
(
$text
)
);
$record
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
$text
)
);
$this
->
assertSame
(
$hash
,
$record
->
getSha1
()
);
}
public
function
testHashComputed
()
{
$row
=
$this
->
makeRow
();
$row
->
content_sha1
=
''
;
$rec
=
new
SlotRecord
(
$row
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
assertNotEmpty
(
$rec
->
getSha1
()
);
}
public
function
testNewWithSuppressedContent
()
{
$input
=
new
SlotRecord
(
$this
->
makeRow
(),
new
DummyContentForTesting
(
'A'
)
);
$output
=
SlotRecord
::
newWithSuppressedContent
(
$input
);
$this
->
expectException
(
SuppressedDataException
::
class
);
$output
->
getContent
();
}
public
function
testNewInherited
()
{
$row
=
$this
->
makeRow
(
[
'slot_revision_id'
=>
7
,
'slot_origin'
=>
7
]
);
$parent
=
new
SlotRecord
(
$row
,
new
DummyContentForTesting
(
'A'
)
);
// This would happen while doing an edit, before saving revision meta-data.
$inherited
=
SlotRecord
::
newInherited
(
$parent
);
$this
->
assertSame
(
$parent
->
getContentId
(),
$inherited
->
getContentId
()
);
$this
->
assertSame
(
$parent
->
getAddress
(),
$inherited
->
getAddress
()
);
$this
->
assertSame
(
$parent
->
getContent
(),
$inherited
->
getContent
()
);
$this
->
assertTrue
(
$inherited
->
isInherited
()
);
$this
->
assertTrue
(
$inherited
->
hasOrigin
()
);
$this
->
assertFalse
(
$inherited
->
hasRevision
()
);
$this
->
assertFalse
(
$inherited
->
isDerived
()
);
// make sure we didn't mess with the internal state of $parent
$this
->
assertFalse
(
$parent
->
isInherited
()
);
$this
->
assertSame
(
7
,
$parent
->
getRevision
()
);
// This would happen while doing an edit, after saving the revision meta-data
// and content meta-data.
$saved
=
SlotRecord
::
newSaved
(
10
,
$inherited
->
getContentId
(),
$inherited
->
getAddress
(),
$inherited
);
$this
->
assertSame
(
$parent
->
getContentId
(),
$saved
->
getContentId
()
);
$this
->
assertSame
(
$parent
->
getAddress
(),
$saved
->
getAddress
()
);
$this
->
assertSame
(
$parent
->
getContent
(),
$saved
->
getContent
()
);
$this
->
assertTrue
(
$saved
->
isInherited
()
);
$this
->
assertTrue
(
$saved
->
hasRevision
()
);
$this
->
assertSame
(
10
,
$saved
->
getRevision
()
);
$this
->
assertFalse
(
$saved
->
isDerived
()
);
// make sure we didn't mess with the internal state of $parent or $inherited
$this
->
assertSame
(
7
,
$parent
->
getRevision
()
);
$this
->
assertFalse
(
$inherited
->
hasRevision
()
);
}
public
function
testNewSaved
()
{
// This would happen while doing an edit, before saving revision meta-data.
$unsaved
=
SlotRecord
::
newUnsaved
(
SlotRecord
::
MAIN
,
new
DummyContentForTesting
(
'A'
)
);
// This would happen while doing an edit, after saving the revision meta-data
// and content meta-data.
$saved
=
SlotRecord
::
newSaved
(
10
,
20
,
'theNewAddress'
,
$unsaved
);
$this
->
assertFalse
(
$saved
->
isInherited
()
);
$this
->
assertTrue
(
$saved
->
hasOrigin
()
);
$this
->
assertTrue
(
$saved
->
hasRevision
()
);
$this
->
assertTrue
(
$saved
->
hasAddress
()
);
$this
->
assertTrue
(
$saved
->
hasContentId
()
);
$this
->
assertSame
(
'theNewAddress'
,
$saved
->
getAddress
()
);
$this
->
assertSame
(
20
,
$saved
->
getContentId
()
);
$this
->
assertSame
(
'A'
,
$saved
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
10
,
$saved
->
getRevision
()
);
$this
->
assertSame
(
10
,
$saved
->
getOrigin
()
);
$this
->
assertFalse
(
$saved
->
isDerived
()
);
// make sure we didn't mess with the internal state of $unsaved
$this
->
assertFalse
(
$unsaved
->
hasAddress
()
);
$this
->
assertFalse
(
$unsaved
->
hasContentId
()
);
$this
->
assertFalse
(
$unsaved
->
hasRevision
()
);
$this
->
assertFalse
(
$unsaved
->
isDerived
()
);
}
public
function
provideNewSaved_LogicException
()
{
$freshRow
=
$this
->
makeRow
(
[
'content_id'
=>
10
,
'content_address'
=>
'address:1'
,
'slot_origin'
=>
1
,
'slot_revision_id'
=>
1
,
]
);
$freshSlot
=
new
SlotRecord
(
$freshRow
,
new
DummyContentForTesting
(
'A'
)
);
yield
'mismatching address'
=>
[
1
,
10
,
'address:BAD'
,
$freshSlot
];
yield
'mismatching revision'
=>
[
5
,
10
,
'address:1'
,
$freshSlot
];
yield
'mismatching content ID'
=>
[
1
,
17
,
'address:1'
,
$freshSlot
];
$inheritedRow
=
$this
->
makeRow
(
[
'content_id'
=>
null
,
'content_address'
=>
null
,
'slot_origin'
=>
0
,
'slot_revision_id'
=>
1
,
]
);
$inheritedSlot
=
new
SlotRecord
(
$inheritedRow
,
new
DummyContentForTesting
(
'A'
)
);
yield
'inherited, but no address'
=>
[
1
,
10
,
'address:2'
,
$inheritedSlot
];
}
/**
* @dataProvider provideNewSaved_LogicException
*/
public
function
testNewSaved_LogicException
(
$revisionId
,
$contentId
,
$contentAddress
,
SlotRecord
$protoSlot
)
{
$this
->
expectException
(
LogicException
::
class
);
SlotRecord
::
newSaved
(
$revisionId
,
$contentId
,
$contentAddress
,
$protoSlot
);
}
public
function
provideHasSameContent
()
{
$fail
=
static
function
()
{
self
::
fail
(
'There should be no need to actually load the content.'
);
};
$a100a1
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
'xxx:a1'
,
]
),
$fail
);
$a100a1b
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
'xxx:a1'
,
]
),
$fail
);
$a100null
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
null
,
]
),
$fail
);
$a100a2
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
'xxx:a2'
,
]
),
$fail
);
$b100a1
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'B'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
'xxx:a1'
,
]
),
$fail
);
$a200a1
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
200
,
'content_sha1'
=>
'hash-a'
,
'content_address'
=>
'xxx:a2'
,
]
),
$fail
);
$a100x1
=
new
SlotRecord
(
$this
->
makeRow
(
[
'model_name'
=>
'A'
,
'content_size'
=>
100
,
'content_sha1'
=>
'hash-x'
,
'content_address'
=>
'xxx:x1'
,
]
),
$fail
);
yield
'same instance'
=>
[
$a100a1
,
$a100a1
,
true
];
yield
'no address'
=>
[
$a100a1
,
$a100null
,
true
];
yield
'same address'
=>
[
$a100a1
,
$a100a1b
,
true
];
yield
'different address'
=>
[
$a100a1
,
$a100a2
,
true
];
yield
'different model'
=>
[
$a100a1
,
$b100a1
,
false
];
yield
'different size'
=>
[
$a100a1
,
$a200a1
,
false
];
yield
'different hash'
=>
[
$a100a1
,
$a100x1
,
false
];
}
/**
* @dataProvider provideHasSameContent
*/
public
function
testHasSameContent
(
SlotRecord
$a
,
SlotRecord
$b
,
$sameContent
)
{
$this
->
assertSame
(
$sameContent
,
$a
->
hasSameContent
(
$b
)
);
$this
->
assertSame
(
$sameContent
,
$b
->
hasSameContent
(
$a
)
);
}
public
function
testNewDerived
()
{
$record
=
SlotRecord
::
newDerived
(
'derivedslot'
,
new
DummyContentForTesting
(
'A'
)
);
$this
->
assertFalse
(
$record
->
hasAddress
()
);
$this
->
assertFalse
(
$record
->
hasContentId
()
);
$this
->
assertFalse
(
$record
->
hasRevision
()
);
$this
->
assertFalse
(
$record
->
isInherited
()
);
$this
->
assertFalse
(
$record
->
hasOrigin
()
);
$this
->
assertSame
(
'A'
,
$record
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
1
,
$record
->
getSize
()
);
$this
->
assertNotEmpty
(
$record
->
getSha1
()
);
$this
->
assertSame
(
DummyContentForTesting
::
MODEL_ID
,
$record
->
getModel
()
);
$this
->
assertSame
(
'derivedslot'
,
$record
->
getRole
()
);
$this
->
assertTrue
(
$record
->
isDerived
()
);
}
public
function
testCopyDerived
()
{
$unsaved
=
SlotRecord
::
newDerived
(
'derivedslot'
,
new
DummyContentForTesting
(
'A'
)
);
$saved
=
SlotRecord
::
newSaved
(
10
,
20
,
'theNewAddress'
,
$unsaved
);
$this
->
assertFalse
(
$saved
->
isInherited
()
);
$this
->
assertTrue
(
$saved
->
hasOrigin
()
);
$this
->
assertTrue
(
$saved
->
hasRevision
()
);
$this
->
assertTrue
(
$saved
->
hasAddress
()
);
$this
->
assertTrue
(
$saved
->
hasContentId
()
);
$this
->
assertSame
(
'theNewAddress'
,
$saved
->
getAddress
()
);
$this
->
assertSame
(
20
,
$saved
->
getContentId
()
);
$this
->
assertSame
(
'A'
,
$saved
->
getContent
()->
getNativeData
()
);
$this
->
assertSame
(
10
,
$saved
->
getRevision
()
);
$this
->
assertSame
(
10
,
$saved
->
getOrigin
()
);
$this
->
assertTrue
(
$saved
->
isDerived
()
);
// make sure we didn't mess with the internal state of $unsaved
$this
->
assertFalse
(
$unsaved
->
hasAddress
()
);
$this
->
assertFalse
(
$unsaved
->
hasContentId
()
);
$this
->
assertFalse
(
$unsaved
->
hasRevision
()
);
$this
->
assertTrue
(
$unsaved
->
isDerived
()
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 19 2026, 20:00 (7 w, 16 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
cd/38/3e075c88f4daf2a41dea0d6cd6e3
Default Alt Text
SlotRecordTest.php (14 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment