Skip to content

Commit 7d7f04b

Browse files
Checking for attribute validity (#7)
1 parent a7c8837 commit 7d7f04b

File tree

4 files changed

+97
-5
lines changed

4 files changed

+97
-5
lines changed

src/Optimizely/Optimizely.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
*/
1717
namespace Optimizely;
1818

19-
use Doctrine\Instantiator\Exception\InvalidArgumentException;
2019
use Exception;
2120
use Optimizely\Exceptions\InvalidAttributeException;
2221
use Throwable;

src/Optimizely/Utils/Validator.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public static function validateJsonSchema($datafile)
4545
*/
4646
public static function areAttributesValid($attributes)
4747
{
48-
//TODO(ali): Implement me
49-
return true;
48+
return is_array($attributes) && count(array_filter(array_keys($attributes), 'is_int')) == 0;
5049
}
5150

5251
/**

tests/OptimizelyTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Optimizely\Bucketer;
2222
use Optimizely\ErrorHandler\NoOpErrorHandler;
2323
use Optimizely\Event\LogEvent;
24+
use Optimizely\Exceptions\InvalidAttributeException;
2425
use Optimizely\Logger\NoOpLogger;
2526
use Optimizely\ProjectConfig;
2627
use TypeError;
@@ -250,6 +251,32 @@ public function testActivateInvalidOptimizelyObject()
250251
$this->expectOutputRegex('/Datafile has invalid format. Failing "activate"./');
251252
}
252253

254+
public function testActivateInvalidAttributes()
255+
{
256+
$this->loggerMock->expects($this->exactly(2))
257+
->method('log');
258+
$this->loggerMock->expects($this->at(0))
259+
->method('log')
260+
->with(Logger::ERROR, 'Provided attributes are in an invalid format.');
261+
$this->loggerMock->expects($this->at(1))
262+
->method('log')
263+
->with(Logger::INFO, 'Not activating user "test_user".');
264+
265+
$errorHandlerMock = $this->getMockBuilder(NoOpErrorHandler::class)
266+
->setMethods(array('handleError'))
267+
->getMock();
268+
$errorHandlerMock->expects($this->once())
269+
->method('handleError')
270+
->with(new InvalidAttributeException('Provided attributes are in an invalid format.'));
271+
272+
$optlyObject = new Optimizely(
273+
$this->datafile, new ValidEventDispatcher(), $this->loggerMock, $errorHandlerMock
274+
);
275+
276+
// Call activate
277+
$this->assertNull($optlyObject->activate('test_experiment', 'test_user', 42));
278+
}
279+
253280
public function testActivateNoAudienceNoAttributes()
254281
{
255282
$this->eventBuilderMock->expects($this->once())
@@ -400,6 +427,27 @@ public function testGetVariationInvalidOptimizelyObject()
400427
$this->expectOutputRegex('/Datafile has invalid format. Failing "getVariation"./');
401428
}
402429

430+
public function testGetVariationInvalidAttributes()
431+
{
432+
$this->loggerMock->expects($this->once())
433+
->method('log')
434+
->with(Logger::ERROR, 'Provided attributes are in an invalid format.');
435+
436+
$errorHandlerMock = $this->getMockBuilder(NoOpErrorHandler::class)
437+
->setMethods(array('handleError'))
438+
->getMock();
439+
$errorHandlerMock->expects($this->once())
440+
->method('handleError')
441+
->with(new InvalidAttributeException('Provided attributes are in an invalid format.'));
442+
443+
$optlyObject = new Optimizely(
444+
$this->datafile, new ValidEventDispatcher(), $this->loggerMock, $errorHandlerMock
445+
);
446+
447+
// Call activate
448+
$this->assertNull($optlyObject->getVariation('test_experiment', 'test_user', 42));
449+
}
450+
403451
public function testGetVariationAudienceMatch()
404452
{
405453
$this->loggerMock->expects($this->exactly(2))
@@ -447,6 +495,27 @@ public function testTrackInvalidOptimizelyObject()
447495
$this->expectOutputRegex('/Datafile has invalid format. Failing "track"./');
448496
}
449497

498+
public function testTrackInvalidAttributes()
499+
{
500+
$this->loggerMock->expects($this->once())
501+
->method('log')
502+
->with(Logger::ERROR, 'Provided attributes are in an invalid format.');
503+
504+
$errorHandlerMock = $this->getMockBuilder(NoOpErrorHandler::class)
505+
->setMethods(array('handleError'))
506+
->getMock();
507+
$errorHandlerMock->expects($this->once())
508+
->method('handleError')
509+
->with(new InvalidAttributeException('Provided attributes are in an invalid format.'));
510+
511+
$optlyObject = new Optimizely(
512+
$this->datafile, new ValidEventDispatcher(), $this->loggerMock, $errorHandlerMock
513+
);
514+
515+
// Call activate
516+
$this->assertNull($optlyObject->track('purchase', 'test_user', 42));
517+
}
518+
450519
public function testTrackNoAttributesNoEventValue()
451520
{
452521
$this->eventBuilderMock->expects($this->once())

tests/UtilsTests/ValidatorTest.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,34 @@ public function testValidateJsonSchemaNoJsonContent()
4242
$this->assertFalse(Validator::validateJsonSchema($invalidDatafile));
4343
}
4444

45-
public function testAreAttributesValidReturnsTrue()
45+
public function testAreAttributesValidValidAttributes()
4646
{
47-
$this->assertTrue(Validator::areAttributesValid('some attributes here'));
47+
// Empty attributes
48+
$this->assertTrue(Validator::areAttributesValid([]));
49+
50+
// Valid attributes
51+
$this->assertTrue(Validator::areAttributesValid([
52+
'location' => 'San Francisco',
53+
'browser' => 'Firefox'
54+
]));
55+
}
56+
57+
public function testAreAttributesValidInvalidAttributes()
58+
{
59+
// String as attributes
60+
$this->assertFalse(Validator::areAttributesValid('Invalid string attributes.'));
61+
62+
// Integer as attributes
63+
$this->assertFalse(Validator::areAttributesValid(42));
64+
65+
// Boolean as attributes
66+
$this->assertFalse(Validator::areAttributesValid(true));
67+
68+
// Sequential array as attributes
69+
$this->assertFalse(Validator::areAttributesValid([0, 1, 2, 42]));
70+
71+
// Mixed array as attributes
72+
$this->assertFalse(Validator::areAttributesValid([0, 1, 2, 42, 'abc' => 'def']));
4873
}
4974

5075
public function testIsUserInExperimentNoAudienceUsedInExperiment()

0 commit comments

Comments
 (0)