1<?php 2 3namespace Wikimedia\ParamValidator\TypeDef; 4 5use InvalidArgumentException; 6use Wikimedia\Message\DataMessageValue; 7use Wikimedia\ParamValidator\SimpleCallbacks; 8use Wikimedia\ParamValidator\ValidationException; 9use Wikimedia\Timestamp\ConvertibleTimestamp; 10 11/** 12 * @covers \Wikimedia\ParamValidator\TypeDef\ExpiryDef 13 */ 14class ExpiryDefTest extends TypeDefTestCase { 15 16 protected function getInstance( SimpleCallbacks $callbacks, array $options ) { 17 return new ExpiryDef( $callbacks, $options ); 18 } 19 20 /** 21 * Get an entry for the provideValidate() provider, where a given value 22 * is asserted to cause a ValidationException with the given message. 23 * @param string $value 24 * @param string $msg 25 * @param array $settings 26 * @return array 27 */ 28 private function getValidationAssertion( string $value, string $msg, array $settings = [] ) { 29 return [ 30 $value, 31 new ValidationException( 32 DataMessageValue::new( $msg ), 33 'expiry', 34 $value, 35 [] 36 ), 37 $settings 38 ]; 39 } 40 41 /** 42 * @dataProvider provideValidate 43 */ 44 public function testValidate( 45 $value, $expect, array $settings = [], array $options = [], array $expectConds = [] 46 ) { 47 ConvertibleTimestamp::setFakeTime( 1559764242 ); 48 parent::testValidate( $value, $expect, $settings, $options, $expectConds ); 49 } 50 51 public function provideValidate() { 52 $settings = [ 53 ExpiryDef::PARAM_MAX => '6 months', 54 ExpiryDef::PARAM_USE_MAX => true, 55 ]; 56 57 return [ 58 'Valid infinity' => [ 'indefinite', 'infinity' ], 59 'Invalid expiry' => $this->getValidationAssertion( 'foobar', 'badexpiry' ), 60 'Expiry in past' => $this->getValidationAssertion( '20150123T12:34:56Z', 'badexpiry-past' ), 61 'Expiry in past with unix 0' => $this->getValidationAssertion( 62 '1970-01-01T00:00:00Z', 63 'badexpiry-past' 64 ), 65 'Expiry in past with negative unix time' => $this->getValidationAssertion( 66 '1969-12-31T23:59:59Z', 67 'badexpiry-past', 68 $settings 69 ), 70 'Valid expiry' => [ 71 '99990123123456', 72 '9999-01-23T12:34:56Z' 73 ], 74 'Valid relative expiry' => [ 75 '1 month', 76 '2019-07-05T19:50:42Z' 77 ], 78 'Expiry less than max' => [ '20190701123456', '2019-07-01T12:34:56Z', $settings ], 79 'Relative expiry less than max' => [ '1 day', '2019-06-06T19:50:42Z', $settings ], 80 'Infinity less than max' => [ 'indefinite', 'infinity', $settings ], 81 'Expiry exceeds max' => [ 82 '9999-01-23T12:34:56Z', 83 '2019-12-05T19:50:42Z', 84 $settings, 85 [], 86 [ 87 [ 88 'code' => 'paramvalidator-badexpiry-duration-max', 89 'data' => null, 90 ] 91 ], 92 ], 93 'Relative expiry exceeds max' => [ 94 '10 years', 95 '2019-12-05T19:50:42Z', 96 $settings, 97 [], 98 [ 99 [ 100 'code' => 'paramvalidator-badexpiry-duration-max', 101 'data' => null, 102 ] 103 ], 104 ], 105 'Expiry exceeds max, fatal' => $this->getValidationAssertion( 106 '9999-01-23T12:34:56Z', 107 'paramvalidator-badexpiry-duration', 108 [ 109 ExpiryDef::PARAM_MAX => '6 months', 110 ] 111 ), 112 ]; 113 } 114 115 public function testNormalizeExpiry() { 116 $this->assertNull( ExpiryDef::normalizeExpiry( null ) ); 117 $this->assertSame( 118 'infinity', 119 ExpiryDef::normalizeExpiry( 'indefinite' ) 120 ); 121 $this->assertSame( 122 '2050-01-01T00:00:00Z', 123 ExpiryDef::normalizeExpiry( '205001010000', TS_ISO_8601 ) 124 ); 125 $this->assertSame( 126 '1970-01-01T00:00:00Z', 127 ExpiryDef::normalizeExpiry( '1970-01-01T00:00:00Z', TS_ISO_8601 ) 128 ); 129 $this->expectException( InvalidArgumentException::class ); 130 $this->expectExceptionMessage( 'Invalid expiry value: 0' ); 131 ExpiryDef::normalizeExpiry( 0, TS_ISO_8601 ); 132 } 133 134 public function provideGetInfo() { 135 return [ 136 'Basic' => [ 137 [], 138 [], 139 [ 140 // phpcs:ignore Generic.Files.LineLength.TooLong 141 'param-type' => '<message key="paramvalidator-help-type-expiry"><text>1</text><list listType="text"><text>"infinite"</text><text>"indefinite"</text><text>"infinity"</text><text>"never"</text></list></message>' 142 ] 143 ] 144 ]; 145 } 146 147 /** 148 * @covers \Wikimedia\ParamValidator\TypeDef\ExpiryDef::normalizeUsingMaxExpiry 149 */ 150 public function testNormalizeUsingMaxExpiry() { 151 // Fake current time to be 2020-05-27T00:00:00Z 152 $fakeTime = ConvertibleTimestamp::setFakeTime( '20200527000000' ); 153 $this->assertSame( 154 '2020-11-27T00:00:00Z', 155 ExpiryDef::normalizeUsingMaxExpiry( '10 months', '6 months', TS_ISO_8601 ) 156 ); 157 $this->assertSame( 158 '2020-10-27T00:00:00Z', 159 ExpiryDef::normalizeUsingMaxExpiry( '2020-10-27T00:00:00Z', '6 months', TS_ISO_8601 ) 160 ); 161 $this->assertSame( 162 'infinity', 163 ExpiryDef::normalizeUsingMaxExpiry( 'infinity', '6 months', TS_ISO_8601 ) 164 ); 165 $this->assertNull( ExpiryDef::normalizeUsingMaxExpiry( null, '6 months', TS_ISO_8601 ) ); 166 167 $this->expectException( InvalidArgumentException::class ); 168 $this->expectExceptionMessage( 'Invalid expiry value: invalid expiry' ); 169 ExpiryDef::normalizeUsingMaxExpiry( 'invalid expiry', '6 months', TS_ISO_8601 ); 170 } 171} 172