1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-22 15:07:44 +00:00
Files
matomo/plugins/MobileMessaging/tests/Integration/MobileMessagingTest.php
Stefan Giehl 840029ed3e Various improvements to number verification workflow in MobileMessaging (#22668)
* Adjust Development SMS provider to log messages instead of a notification

Notifications don't work here correctly anymore, as the messages are sent through the API, where access to the session may not be possible"

* Extend verification code to 6 alhpanumeric characters

* Limit number of unverified phone numbers to 3 per user

* Add confirmation when removing a phone number

* Store verification details and ensure that verification code expires after 3 failed tries or 10 minutes

* Sort numbers in UI so unverified are listed first

* improve usability of phone number management

* Add possibility to resend a verification code

* fix a couple of tests

* Adds some more tests

* move UI tests to plugin

* adds some more UI tests

* Only validate numbers when adding them

* apply some review feedback
2024-10-14 17:02:31 +02:00

337 خطوط
12 KiB
PHP

<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\MobileMessaging\tests\Integration;
use Piwik\Date;
use Piwik\Piwik;
use Piwik\Plugins\MobileMessaging\API as APIMobileMessaging;
use Piwik\Plugins\MobileMessaging\MobileMessaging;
use Piwik\Plugins\MobileMessaging\Model;
use Piwik\Plugins\MobileMessaging\SMSProvider;
use Piwik\Plugins\ScheduledReports\API as APIScheduledReports;
use Piwik\Plugins\SitesManager\API as APISitesManager;
use Piwik\Tests\Framework\Mock\FakeAccess;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
/**
* Class Plugins_MobileMessagingTest
*
* @group Plugins
*/
class MobileMessagingTest extends IntegrationTestCase
{
protected $idSiteAccess;
public function setUp(): void
{
parent::setUp();
// setup the access layer
FakeAccess::$superUser = true;
$this->idSiteAccess = APISitesManager::getInstance()->addSite("test", "http://test");
\Piwik\Plugin\Manager::getInstance()->loadPlugins(array('ScheduledReports', 'MobileMessaging', 'MultiSites'));
\Piwik\Plugin\Manager::getInstance()->installLoadedPlugins();
}
/**
* When the MultiSites plugin is not activated, the SMS content should invite the user to activate it back
*/
public function testWarnUserViaSMSMultiSitesDeactivated()
{
// safety net
\Piwik\Plugin\Manager::getInstance()->loadPlugins(array('ScheduledReports', 'MobileMessaging'));
$this->assertFalse(\Piwik\Plugin\Manager::getInstance()->isPluginActivated('MultiSites'));
$APIScheduledReports = APIScheduledReports::getInstance();
$reportId = $APIScheduledReports->addReport(
$this->idSiteAccess,
'description',
'month',
0,
'mobile',
'sms',
array(),
array("phoneNumbers" => array('33698896656'))
);
$contents = $APIScheduledReports->generateReport(
$reportId,
'01-01-2010',
'en',
APIScheduledReports::OUTPUT_RETURN
);
$this->assertEquals(
\Piwik\Piwik::translate('MobileMessaging_MultiSites_Must_Be_Activated'),
$contents
);
}
/**
* Dataprovider for testTruncate
*/
public function getTruncateTestCases()
{
$stdGSMx459 = str_repeat('a', 459);
$extGSMx229 = str_repeat('€', 229);
$alternatedGSMx153 = str_repeat('a€', 153);
$GSMWithRegExpSpecialChars = $stdGSMx459 . '[\^$.|?*/+()';
$UCS2x201 = str_repeat('控', 201);
// appended strings
$stdGSMAppendedString = 'too long';
$extGSMAppendedString = '[too long]';
$UCS2AppendedString = '[控控]';
return array(
// maximum number of standard GSM characters
array($stdGSMx459, $stdGSMx459, 3, 'N/A'),
// maximum number of extended GSM characters
array($extGSMx229, $extGSMx229, 3, 'N/A'),
// maximum number of alternated GSM characters
array($alternatedGSMx153, $alternatedGSMx153, 3, 'N/A'),
// standard GSM, one 'a' too many, appended with standard GSM characters
array(str_repeat('a', 451) . $stdGSMAppendedString, $stdGSMx459 . 'a', 3, $stdGSMAppendedString),
// standard GSM, one 'a' too many, appended with extended GSM characters
array(str_repeat('a', 447) . $extGSMAppendedString, $stdGSMx459 . 'a', 3, $extGSMAppendedString),
// standard GSM, one 'a' too many, appended with UCS2 characters
array(str_repeat('a', 197) . $UCS2AppendedString, $stdGSMx459 . 'a', 3, $UCS2AppendedString),
// extended GSM, one '€' too many, appended with standard GSM characters
array(str_repeat('€', 225) . $stdGSMAppendedString, $extGSMx229 . '€', 3, $stdGSMAppendedString),
// extended GSM, one '€' too many, appended with extended GSM characters
array(str_repeat('€', 223) . $extGSMAppendedString, $extGSMx229 . '€', 3, $extGSMAppendedString),
// extended GSM, one '€' too many, appended with UCS2 characters
array(str_repeat('€', 197) . $UCS2AppendedString, $extGSMx229 . '€', 3, $UCS2AppendedString),
// alternated GSM, one 'a' too many, appended with standard GSM characters
array(str_repeat('a€', 150) . 'a' . $stdGSMAppendedString, $alternatedGSMx153 . 'a', 3, $stdGSMAppendedString),
// alternated GSM, one 'a' too many, appended with extended GSM characters
array(str_repeat('a€', 149) . $extGSMAppendedString, $alternatedGSMx153 . 'a', 3, $extGSMAppendedString),
// alternated GSM, one 'a' too many, appended with UCS2 characters
array(str_repeat('a€', 98) . 'a' . $UCS2AppendedString, $alternatedGSMx153 . 'a', 3, $UCS2AppendedString),
// alternated GSM, one '€' too many, appended with standard GSM characters
array(str_repeat('a€', 150) . 'a' . $stdGSMAppendedString, $alternatedGSMx153 . '€', 3, $stdGSMAppendedString),
// alternated GSM, one '€' too many, appended with extended GSM characters
array(str_repeat('a€', 149) . $extGSMAppendedString, $alternatedGSMx153 . '€', 3, $extGSMAppendedString),
// alternated GSM, one '€' too many, appended with UCS2 characters
array(str_repeat('a€', 98) . 'a' . $UCS2AppendedString, $alternatedGSMx153 . '€', 3, $UCS2AppendedString),
// GSM with RegExp reserved special chars
array(str_repeat('a', 451) . $stdGSMAppendedString, $GSMWithRegExpSpecialChars, 3, $stdGSMAppendedString),
// maximum number of UCS-2 characters
array($UCS2x201, $UCS2x201, 3, 'N/A'),
// UCS-2, one '控' too many, appended with UCS2 characters
array(str_repeat('控', 197) . $UCS2AppendedString, $UCS2x201 . '控', 3, $UCS2AppendedString),
// UCS-2, one '控' too many, appended with standard GSM characters
array(str_repeat('控', 193) . $stdGSMAppendedString, $UCS2x201 . '控', 3, $stdGSMAppendedString)
);
}
/**
* @dataProvider getTruncateTestCases
*/
public function testTruncate($expected, $stringToTruncate, $maximumNumberOfConcatenatedSMS, $appendedString)
{
$this->assertEquals(
$expected,
SMSProvider::truncate($stringToTruncate, $maximumNumberOfConcatenatedSMS, $appendedString)
);
}
/**
* Dataprovider for testContainsUCS2Characters
*/
public function getContainsUCS2CharactersTestCases()
{
return array(
array(false, 'too long'),
array(false, '[too long]'),
array(false, '€'),
array(true, '[控控]'),
);
}
/**
* @dataProvider getContainsUCS2CharactersTestCases
*/
public function testContainsUCS2Characters($expected, $stringToTest)
{
$this->assertEquals(
$expected,
SMSProvider::containsUCS2Characters($stringToTest)
);
}
/**
* @dataProvider getInvalidPhoneNumbers
*/
public function testPhoneNumberIsValidated(string $phoneNumber)
{
self::expectException(\Exception::class);
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
$mobileMessagingAPI->addPhoneNumber($phoneNumber);
}
public function getInvalidPhoneNumbers(): iterable
{
yield "not starting with +" => [
"123456789"
];
yield "shorter than 5 numbers" => [
"+4526"
];
yield "longer than 30 numbers" => [
"+452651234564565456545641893248932148632578905"
];
yield "invalid characters" => [
"+452d89#05"
];
}
public function testPhoneNumberIsSanitized()
{
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
$mobileMessagingAPI->addPhoneNumber('+6 (76) 93 26 47');
$this->assertEquals('+676932647', key($model->getPhoneNumbers(Piwik::getCurrentUserLogin(), false)));
}
public function testResendVerificationCodeDoesNotWorkWithin60Seconds()
{
self::expectException(\Exception::class);
self::expectExceptionMessage('MobileMessaging_VerificationCodeRecentlySentError');
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
Date::$now = time() - 55;
$mobileMessagingAPI->addPhoneNumber('+1234567895');
Date::$now = time();
$mobileMessagingAPI->resendVerificationCode('+1234567895');
}
public function testResendVerificationCodeWorksAgainAfter60Seconds()
{
self::expectNotToPerformAssertions();
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
Date::$now = time() - 65;
$mobileMessagingAPI->addPhoneNumber('+1234567895');
Date::$now = time();
$mobileMessagingAPI->resendVerificationCode('+1234567895');
}
public function testAdding3UnverifiedNumbersWorks()
{
self::expectNotToPerformAssertions();
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
$mobileMessagingAPI->addPhoneNumber('+1234567895');
$mobileMessagingAPI->addPhoneNumber('+2345678890');
$mobileMessagingAPI->addPhoneNumber('+2345678901');
}
public function testAddingMoreThan3UnverifiedNumbersDoesNotWork()
{
self::expectException(\Exception::class);
$mobileMessagingAPI = APIMobileMessaging::getInstance();
$model = new Model();
$mobileMessagingAPI->setSMSAPICredential('StubbedProvider', []);
$mobileMessagingAPI->addPhoneNumber('+1234567895');
$mobileMessagingAPI->addPhoneNumber('+2345678890');
$mobileMessagingAPI->addPhoneNumber('+2345678901');
$mobileMessagingAPI->addPhoneNumber('+3456789012');
}
/**
* Dataprovider for testSendReport
*/
public function getSendReportTestCases()
{
return array(
array('reportContent', '0101010101', 'Piwik.org', 'reportContent', '0101010101', 'Piwik.org'),
array('reportContent', '0101010101', 'General_Reports', 'reportContent', '0101010101', 'General_MultiSitesSummary'),
);
}
/**
* @dataProvider getSendReportTestCases
*/
public function testSendReport($expectedReportContent, $expectedPhoneNumber, $expectedFrom, $reportContent, $phoneNumber, $reportSubject)
{
$report = array(
'parameters' => array(MobileMessaging::PHONE_NUMBERS_PARAMETER => array($phoneNumber)),
);
$stubbedModel = $this->getMockBuilder(Model::class)
->onlyMethods(array('sendSMS'))
->getMock();
$stubbedModel->expects($this->once())->method('sendSMS')->with(
$this->equalTo($expectedReportContent, 0),
$this->equalTo($expectedPhoneNumber, 1),
$this->equalTo($expectedFrom, 2)
);
$stubbedMobileMessaging = $this->getMockBuilder(MobileMessaging::class)
->onlyMethods(['getModel'])
->getMock();
$stubbedMobileMessaging->expects($this->once())->method('getModel')->will($this->returnValue($stubbedModel));
$stubbedMobileMessaging->sendReport(MobileMessaging::MOBILE_TYPE, $report, $reportContent, null, null, $reportSubject, null, null, null, false);
}
public function provideContainerConfig()
{
return array(
'Piwik\Access' => new FakeAccess()
);
}
}