Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4142672
CommentStoreTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
CommentStoreTest.php
View Options
<?php
use
MediaWiki\CommentStore\CommentStore
;
use
MediaWiki\CommentStore\CommentStoreComment
;
use
MediaWiki\Language\Language
;
use
MediaWiki\Language\RawMessage
;
use
MediaWiki\Message\Message
;
use
Wikimedia\Rdbms\IMaintainableDatabase
;
/**
* @group Database
* @covers \MediaWiki\CommentStore\CommentStore
* @covers \MediaWiki\CommentStore\CommentStoreComment
*/
class
CommentStoreTest
extends
MediaWikiLangTestCase
{
protected
function
getSchemaOverrides
(
IMaintainableDatabase
$db
)
{
return
[
'scripts'
=>
[
__DIR__
.
'/CommentStoreTest.sql'
,
],
'drop'
=>
[],
'create'
=>
[
'commentstore1'
,
'commentstore2'
,
'commentstore2_temp'
],
'alter'
=>
[],
];
}
/**
* Create a store for a particular stage
* @return CommentStore
*/
private
function
makeStore
()
{
$lang
=
$this
->
createMock
(
Language
::
class
);
$lang
->
method
(
'truncateForDatabase'
)->
willReturnCallback
(
static
function
(
$str
,
$len
)
{
return
strlen
(
$str
)
>
$len
?
substr
(
$str
,
0
,
$len
-
3
)
.
'...'
:
$str
;
}
);
$lang
->
method
(
'truncateForVisual'
)->
willReturnCallback
(
static
function
(
$str
,
$len
)
{
return
mb_strlen
(
$str
)
>
$len
?
mb_substr
(
$str
,
0
,
$len
-
3
)
.
'...'
:
$str
;
}
);
return
new
CommentStore
(
$lang
);
}
/**
* @dataProvider provideGetJoin
* @param string $key
* @param array $expect
*/
public
function
testGetJoin
(
$key
,
$expect
)
{
$store
=
$this
->
makeStore
();
$result
=
$store
->
getJoin
(
$key
);
$this
->
assertEquals
(
$expect
,
$result
);
}
public
static
function
provideGetJoin
()
{
return
[
'Simple table'
=>
[
'ipb_reason'
,
[
'tables'
=>
[
'comment_ipb_reason'
=>
'comment'
],
'fields'
=>
[
'ipb_reason_text'
=>
'comment_ipb_reason.comment_text'
,
'ipb_reason_data'
=>
'comment_ipb_reason.comment_data'
,
'ipb_reason_cid'
=>
'comment_ipb_reason.comment_id'
,
],
'joins'
=>
[
'comment_ipb_reason'
=>
[
'JOIN'
,
'comment_ipb_reason.comment_id = ipb_reason_id'
],
],
],
],
'Revision'
=>
[
'rev_comment'
,
[
'tables'
=>
[
'comment_rev_comment'
=>
'comment'
,
],
'fields'
=>
[
'rev_comment_text'
=>
'comment_rev_comment.comment_text'
,
'rev_comment_data'
=>
'comment_rev_comment.comment_data'
,
'rev_comment_cid'
=>
'comment_rev_comment.comment_id'
,
],
'joins'
=>
[
'comment_rev_comment'
=>
[
'JOIN'
,
'comment_rev_comment.comment_id = rev_comment_id'
],
],
],
],
'Image'
=>
[
'img_description'
,
[
'tables'
=>
[
'comment_img_description'
=>
'comment'
,
],
'fields'
=>
[
'img_description_text'
=>
'comment_img_description.comment_text'
,
'img_description_data'
=>
'comment_img_description.comment_data'
,
'img_description_cid'
=>
'comment_img_description.comment_id'
,
],
'joins'
=>
[
'comment_img_description'
=>
[
'JOIN'
,
'comment_img_description.comment_id = img_description_id'
,
],
],
],
],
];
}
private
function
assertComment
(
$expect
,
$actual
,
$from
)
{
$this
->
assertSame
(
$expect
[
'text'
],
$actual
->
text
,
"text $from"
);
$this
->
assertInstanceOf
(
get_class
(
$expect
[
'message'
]
),
$actual
->
message
,
"message class $from"
);
$this
->
assertSame
(
$expect
[
'message'
]->
getKeysToTry
(),
$actual
->
message
->
getKeysToTry
(),
"message keys $from"
);
$this
->
assertEquals
(
$expect
[
'message'
]->
text
(),
$actual
->
message
->
text
(),
"message rendering $from"
);
$this
->
assertEquals
(
$expect
[
'text'
],
$actual
->
message
->
text
(),
"message rendering and text $from"
);
$this
->
assertEquals
(
$expect
[
'data'
],
$actual
->
data
,
"data $from"
);
}
/**
* @dataProvider provideInsertRoundTrip
* @param string $table
* @param string $key
* @param string $pk
* @param string|Message $comment
* @param array|null $data
* @param array $expect
*/
public
function
testInsertRoundTrip
(
$table
,
$key
,
$pk
,
$comment
,
$data
,
$expect
)
{
static
$id
=
1
;
$wstore
=
$this
->
makeStore
();
$fields
=
$wstore
->
insert
(
$this
->
getDb
(),
$key
,
$comment
,
$data
);
$this
->
assertArrayNotHasKey
(
$key
,
$fields
,
"old field"
);
$this
->
assertArrayHasKey
(
"{$key}_id"
,
$fields
,
"new field"
);
$this
->
getDb
()->
newInsertQueryBuilder
()
->
insertInto
(
$table
)
->
row
(
[
$pk
=>
++
$id
]
+
$fields
)
->
caller
(
__METHOD__
)
->
execute
();
$rstore
=
$this
->
makeStore
();
$fieldRow
=
$this
->
getDb
()->
newSelectQueryBuilder
()
->
select
(
[
"{$key}_id"
=>
"{$key}_id"
]
)
->
from
(
$table
)
->
where
(
[
$pk
=>
$id
]
)
->
caller
(
__METHOD__
)->
fetchRow
();
$queryInfo
=
$rstore
->
getJoin
(
$key
);
$joinRow
=
$this
->
getDb
()->
newSelectQueryBuilder
()
->
queryInfo
(
$queryInfo
)
->
from
(
$table
)
->
where
(
[
$pk
=>
$id
]
)
->
caller
(
__METHOD__
)
->
fetchRow
();
$this
->
assertComment
(
$expect
,
$rstore
->
getCommentLegacy
(
$this
->
getDb
(),
$key
,
$fieldRow
),
"from getFields()"
);
$this
->
assertComment
(
$expect
,
$rstore
->
getComment
(
$key
,
$joinRow
),
"from getJoin()"
);
}
public
static
function
provideInsertRoundTrip
()
{
$msgComment
=
new
Message
(
'parentheses'
,
[
'message comment'
]
);
$textCommentMsg
=
new
RawMessage
(
'$1'
,
[
Message
::
plaintextParam
(
'{{text}} comment'
)
]
);
$nestedMsgComment
=
new
Message
(
[
'parentheses'
,
'rawmessage'
],
[
new
Message
(
'mainpage'
)
]
);
$comStoreComment
=
new
CommentStoreComment
(
null
,
'comment store comment'
,
null
,
[
'foo'
=>
'bar'
]
);
return
[
'Simple table, text comment'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
'{{text}} comment'
,
null
,
[
'text'
=>
'{{text}} comment'
,
'message'
=>
$textCommentMsg
,
'data'
=>
null
,
]
],
'Simple table, text comment with data'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
'{{text}} comment'
,
[
'message'
=>
42
],
[
'text'
=>
'{{text}} comment'
,
'message'
=>
$textCommentMsg
,
'data'
=>
[
'message'
=>
42
],
]
],
'Simple table, message comment'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
$msgComment
,
null
,
[
'text'
=>
'(message comment)'
,
'message'
=>
$msgComment
,
'data'
=>
null
,
]
],
'Simple table, message comment with data'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
$msgComment
,
[
'message'
=>
42
],
[
'text'
=>
'(message comment)'
,
'message'
=>
$msgComment
,
'data'
=>
[
'message'
=>
42
],
]
],
'Simple table, nested message comment'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
$nestedMsgComment
,
null
,
[
'text'
=>
'(Main Page)'
,
'message'
=>
$nestedMsgComment
,
'data'
=>
null
,
]
],
'Simple table, CommentStoreComment'
=>
[
'commentstore1'
,
'cs1_comment'
,
'cs1_id'
,
clone
$comStoreComment
,
[
'baz'
=>
'baz'
],
[
'text'
=>
'comment store comment'
,
'message'
=>
$comStoreComment
->
message
,
'data'
=>
[
'foo'
=>
'bar'
],
]
],
];
}
public
function
testGetCommentErrors
()
{
$store
=
$this
->
makeStore
();
try
{
$store
->
getComment
(
'dummy'
,
[
'dummy'
=>
'comment'
]
);
$this
->
fail
(
'Expected exception not thrown'
);
}
catch
(
InvalidArgumentException
$ex
)
{
$this
->
assertSame
(
'$row does not contain fields needed for comment dummy'
,
$ex
->
getMessage
()
);
}
// Ignore: Using deprecated fallback handling for comment dummy
$res
=
@
$store
->
getComment
(
'dummy'
,
[
'dummy'
=>
'comment'
],
true
);
$this
->
assertSame
(
'comment'
,
$res
->
text
);
try
{
$store
->
getComment
(
'dummy'
,
[
'dummy_id'
=>
1
]
);
$this
->
fail
(
'Expected exception not thrown'
);
}
catch
(
InvalidArgumentException
$ex
)
{
$this
->
assertSame
(
'$row does not contain fields needed for comment dummy and getComment(), '
.
'but does have fields for getCommentLegacy()'
,
$ex
->
getMessage
()
);
}
$store
=
$this
->
makeStore
();
try
{
$store
->
getComment
(
'rev_comment'
,
[
'rev_comment'
=>
'comment'
]
);
$this
->
fail
(
'Expected exception not thrown'
);
}
catch
(
InvalidArgumentException
$ex
)
{
$this
->
assertSame
(
'$row does not contain fields needed for comment rev_comment'
,
$ex
->
getMessage
()
);
}
$res
=
@
$store
->
getComment
(
'rev_comment'
,
[
'rev_comment'
=>
'comment'
],
true
);
$this
->
assertSame
(
'comment'
,
$res
->
text
);
try
{
$store
->
getComment
(
'rev_comment'
,
[
'rev_comment_id'
=>
1
]
);
$this
->
fail
(
'Expected exception not thrown'
);
}
catch
(
InvalidArgumentException
$ex
)
{
$this
->
assertSame
(
'$row does not contain fields needed for comment rev_comment and getComment(), '
.
'but does have fields for getCommentLegacy()'
,
$ex
->
getMessage
()
);
}
}
public
function
testInsertTruncation
()
{
$comment
=
str_repeat
(
'💣'
,
16400
);
$truncated
=
str_repeat
(
'💣'
,
CommentStore
::
COMMENT_CHARACTER_LIMIT
-
3
)
.
'...'
;
$store
=
$this
->
makeStore
();
$fields
=
$store
->
insert
(
$this
->
getDb
(),
'ipb_reason'
,
$comment
);
$stored
=
$this
->
getDb
()->
newSelectQueryBuilder
()
->
select
(
'comment_text'
)
->
from
(
'comment'
)
->
where
(
[
'comment_id'
=>
$fields
[
'ipb_reason_id'
]
]
)
->
caller
(
__METHOD__
)->
fetchField
();
$this
->
assertSame
(
$truncated
,
$stored
);
}
public
function
testInsertTooMuchData
()
{
$store
=
$this
->
makeStore
();
$this
->
expectException
(
OverflowException
::
class
);
$this
->
expectExceptionMessage
(
"Comment data is too long (65611 bytes, maximum is 65535)"
);
$store
->
insert
(
$this
->
getDb
(),
'ipb_reason'
,
'foo'
,
[
'long'
=>
str_repeat
(
'💣'
,
16400
)
]
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Aug 19 2026, 16:28 (4 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5a/02/5937c8d542b2bd7f4459096632ac
Default Alt Text
CommentStoreTest.php (9 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment