Skip to content

Commit 03c03dd

Browse files
committed
Merge pull request #4 from launchdarkly/jko/user-rules
Add tests, targeting rules for new attributes, support for user target.
2 parents 1cb6b99 + 1b0815e commit 03c03dd

File tree

8 files changed

+255
-15
lines changed

8 files changed

+255
-15
lines changed

src/LaunchDarkly/FeatureRep.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public function evaluate($user) {
3030
if (is_null($param)) {
3131
return null;
3232
} else {
33+
foreach ($this->_variations as $variation) {
34+
if ($variation->matchUser($user)) {
35+
return $variation->getValue();
36+
}
37+
}
38+
3339
foreach ($this->_variations as $variation) {
3440
if ($variation->matchTarget($user)) {
3541
return $variation->getValue();

src/LaunchDarkly/LDClient.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,12 @@ protected static function _decode($json, $user) {
207207

208208
$ts = empty($v['targets']) ? [] : $v['targets'];
209209
$targets = array_map($makeTarget, $ts);
210-
return new Variation($v['value'], $v['weight'], $targets);
210+
if (isset($v['userTarget'])) {
211+
return new Variation($v['value'], $v['weight'], $targets, $v['userTarget']);
212+
}
213+
else {
214+
return new Variation($v['value'], $v['weight'], $targets, null);
215+
}
211216
};
212217

213218
$vs = empty($json['variations']) ? [] : $json['variations'];

src/LaunchDarkly/LDUser.php

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,39 @@ class LDUser {
1111
protected $_secondary = null;
1212
protected $_ip = null;
1313
protected $_country = null;
14+
protected $_email = null;
15+
protected $_name = null;
16+
protected $_avatar = null;
17+
protected $_firstName = null;
18+
protected $_lastName = null;
1419
protected $_custom = [];
1520

1621
/**
1722
* @param string $key Unique key for the user. For authenticated users, this may be a username or e-mail address. For anonymous users, this could be an IP address or session ID.
1823
* @param string|null $secondary An optional secondary identifier
1924
* @param string|null $ip The user's IP address (optional)
2025
* @param string|null $country The user's country, as an ISO 3166-1 alpha-2 code (e.g. 'US') (optional)
21-
* @param array $custom Other custom attributes that can be used to create custom rules
26+
* @param string|null $email The user's e-mail address (optional)
27+
* @param string|null $name The user's full name (optional)
28+
* @param string|null $avatar A URL pointing to the user's avatar image (optional)
29+
* @param string|null $firstName The user's first name (optional)
30+
* @param string|null $lastName The user's last name (optional)
31+
* @param array|null $custom Other custom attributes that can be used to create custom rules
2232
*/
23-
public function __construct($key, $secondary = null, $ip = null, $country = null, $custom = []) {
33+
public function __construct($key, $secondary = null, $ip = null, $country = null, $email = null, $name = null, $avatar = null, $firstName = null, $lastName= null, $custom = []) {
2434
$this->_key = $key;
2535
$this->_secondary = $secondary;
2636
$this->_ip = $ip;
2737
$this->_country = $country;
38+
$this->_email = $email;
39+
$this->_name = $name;
40+
$this->_avatar = $avatar;
41+
$this->_firstName = $firstName;
42+
$this->_lastName = $lastName;
2843
$this->_custom = $custom;
2944
}
3045

31-
public function getCountryCode() {
46+
public function getCountry() {
3247
return $this->_country;
3348
}
3449

@@ -48,20 +63,55 @@ public function getSecondary() {
4863
return $this->_secondary;
4964
}
5065

66+
public function getEmail() {
67+
return $this->_email;
68+
}
69+
70+
public function getName() {
71+
return $this->_name;
72+
}
73+
74+
public function getAvatar() {
75+
return $this->_avatar;
76+
}
77+
78+
public function getFirstName() {
79+
return $this->_firstName;
80+
}
81+
82+
public function getLastName() {
83+
return $this->_lastName;
84+
}
85+
5186
public function toJSON() {
5287
$json = ["key" => $this->_key];
5388

5489
if (isset($this->_secondary)) {
5590
$json['secondary'] = $this->_secondary;
5691
}
57-
if (isset($this->ip)) {
58-
$json['ip'] = $this->ip;
92+
if (isset($this->_ip)) {
93+
$json['ip'] = $this->_ip;
94+
}
95+
if (isset($this->_country)) {
96+
$json['country'] = $this->_country;
97+
}
98+
if (isset($this->_email)) {
99+
$json['email'] = $this->_email;
100+
}
101+
if (isset($this->_name)) {
102+
$json['name'] = $this->_name;
103+
}
104+
if (isset($this->_avatar)) {
105+
$json['avatar'] = $this->_avatar;
106+
}
107+
if (isset($this->_firstName)) {
108+
$json['firstName'] = $this->_firstName;
59109
}
60-
if (isset($this->country)) {
61-
$json['country'] = $this->country;
110+
if (isset($this->_lastName)) {
111+
$json['lastName'] = $this->_lastName;
62112
}
63-
if (isset($this->custom)) {
64-
$json['custom'] = $this->custom;
113+
if (isset($this->_custom)) {
114+
$json['custom'] = $this->_custom;
65115
}
66116
return $json;
67117
}

src/LaunchDarkly/LDUserBuilder.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
namespace LaunchDarkly;
3+
4+
class LDUserBuilder {
5+
protected $_key = null;
6+
protected $_secondary = null;
7+
protected $_ip = null;
8+
protected $_country = null;
9+
protected $_email = null;
10+
protected $_name = null;
11+
protected $_avatar = null;
12+
protected $_firstName = null;
13+
protected $_lastName = null;
14+
protected $_custom = [];
15+
16+
public function __construct($key) {
17+
$this->_key = $key;
18+
}
19+
20+
public function secondary($secondary) {
21+
$this->_secondary = $secondary;
22+
return $this;
23+
}
24+
25+
public function ip($ip) {
26+
$this->_ip = $ip;
27+
return $this;
28+
}
29+
30+
public function country($country) {
31+
$this->_country = $country;
32+
return $this;
33+
}
34+
35+
public function email($email) {
36+
$this->_email = $email;
37+
return $this;
38+
}
39+
40+
public function name($name) {
41+
$this->_name = $name;
42+
return $this;
43+
}
44+
45+
public function avatar($avatar) {
46+
$this->_avatar = $avatar;
47+
return $this;
48+
}
49+
50+
public function firstName($firstName) {
51+
$this->_firstName = $firstName;
52+
return $this;
53+
}
54+
55+
public function lastName($lastName) {
56+
$this->_lastName = $lastName;
57+
return $this;
58+
}
59+
60+
public function custom($custom) {
61+
$this->_custom = $custom;
62+
return $this;
63+
}
64+
65+
public function build() {
66+
return new LDUser($this->_key, $this->_secondary, $this->_ip, $this->_country, $this->_email, $this->_name, $this->_avatar, $this->_firstName, $this->_lastName, $this->_custom);
67+
}
68+
69+
}

src/LaunchDarkly/TargetRule.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ public function matchTarget($user) {
2929
case "country":
3030
$u_value = $user->getCountryCode();
3131
break;
32+
case "email":
33+
$u_value = $user->getEmail();
34+
break;
35+
case "name":
36+
$u_value = $user->getName();
37+
break;
38+
case "avatar":
39+
$u_value = $user->getAvatar();
40+
break;
41+
case "firstName":
42+
$u_value = $user->getFirstName();
43+
break;
44+
case "lastName":
45+
$u_value = $user->getLastName();
46+
break;
3247
default:
3348
$custom = $user->getCustom();
3449
if (is_array($custom)) {

src/LaunchDarkly/Variation.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,29 @@
77
class Variation {
88
protected $_value = null;
99
protected $_weight = 0;
10+
protected $_targetRule = null;
11+
protected $_userTarget = null;
1012
protected $_targets = [];
1113

12-
public function __construct($value, $weight, $targets) {
14+
public function __construct($value, $weight, $targets, $userTarget) {
1315
$this->_value = $value;
1416
$this->_weight = $weight;
1517
$this->_targets = $targets;
18+
$this->_userTarget = $userTarget;
19+
}
20+
21+
public function matchUser($user) {
22+
if ($this->_userTarget != null) {
23+
return $this->_userTarget->matchTarget($user);
24+
}
25+
return false;
1626
}
1727

1828
public function matchTarget($user) {
1929
foreach($this->_targets as $target) {
30+
if ($this->_userTarget != null && $target->_attribute == "key") {
31+
continue;
32+
}
2033
if ($target->matchTarget($user)) {
2134
return true;
2235
}

tests/FeatureRepTest.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace LaunchDarkly\Tests;
33

44
use LaunchDarkly\FeatureRep;
5+
use LaunchDarkly\LDUserBuilder;
56
use LaunchDarkly\LDUser;
67
use LaunchDarkly\TargetRule;
78
use LaunchDarkly\Variation;
@@ -10,19 +11,25 @@ class FeatureRepTest extends \PHPUnit_Framework_TestCase {
1011

1112
protected $_simpleFlag = null;
1213
protected $_disabledFlag = null;
14+
protected $_userTargetFlag = null;
1315

1416
protected function setUp() {
1517
parent::setUp();
1618
$targetUserOn = new TargetRule("key", "in", ["[email protected]"]);
1719
$targetGroupOn = new TargetRule("groups", "in", ["google", "microsoft"]);
1820
$targetUserOff = new TargetRule("key", "in", ["[email protected]"]);
1921
$targetGroupOff = new TargetRule("groups", "in", ["oracle"]);
22+
$targetEmailOn = new TargetRule("email", "in", ["[email protected]"]);
2023

21-
$trueVariation = new Variation(true, 80, [$targetUserOn, $targetGroupOn]);
22-
$falseVariation = new Variation(false, 20, [$targetUserOff, $targetGroupOff]);
24+
$trueVariation = new Variation(true, 80, [$targetUserOn, $targetGroupOn, $targetEmailOn], null);
25+
$falseVariation = new Variation(false, 20, [$targetUserOff, $targetGroupOff], null);
2326

2427
$this->_simpleFlag = new FeatureRep("Sample flag", "sample.flag", "feefifofum", true, [$trueVariation, $falseVariation]);
2528
$this->_disabledFlag = new FeatureRep("Sample flag", "sample.flag", "feefifofum", false, [$trueVariation, $falseVariation]);
29+
30+
$userTargetVariation = new Variation(false, 20, [], $targetUserOn);
31+
32+
$this->_userTargetFlag = new FeatureRep("Sample flag", "sample.flag", "feefifofum", true, [$trueVariation, $userTargetVariation]);
2633
}
2734

2835
protected function tearDown() {
@@ -43,13 +50,13 @@ public function testFlagForTargetedUserOn() {
4350
}
4451

4552
public function testFlagForTargetGroupOn() {
46-
$user = new LDUser("[email protected]", null, null, null, ["groups" => ["google", "microsoft"]]);
53+
$user = (new LDUserBuilder("[email protected]"))->custom(["groups" => ["google", "microsoft"]])->build();
4754
$b = $this->_simpleFlag->evaluate($user);
4855
$this->assertEquals(true, $b);
4956
}
5057

5158
public function testFlagForTargetGroupOff() {
52-
$user = new LDUser("[email protected]", null, null, null, ["groups" => "oracle"]);
59+
$user = new LDUser("[email protected]", null, null, null, null, null, null, null, null, ["groups" => "oracle"]);
5360
$b = $this->_simpleFlag->evaluate($user);
5461
$this->assertEquals(false, $b);
5562
}
@@ -59,5 +66,17 @@ public function testDisabledFlagAlwaysOff() {
5966
$b = $this->_disabledFlag->evaluate($user);
6067
$this->assertEquals(null, $b);
6168
}
69+
70+
public function testUserRuleFlagForTargetUserOff() {
71+
$user = (new LDUserBuilder("[email protected]"))->build();
72+
$b = $this->_userTargetFlag->evaluate($user);
73+
$this->assertEquals(false, $b);
74+
}
75+
76+
public function testFlagForTargetEmailOff() {
77+
$user = (new LDUserBuilder("[email protected]"))->email("[email protected]")->build();
78+
$b = $this->_simpleFlag->evaluate($user);
79+
$this->assertEquals(true,$b);
80+
}
6281
}
6382

tests/LDUserTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
namespace LaunchDarkly\Tests;
3+
4+
use LaunchDarkly\LDUserBuilder;
5+
use LaunchDarkly\LDUser;
6+
7+
class LDUserTest extends \PHPUnit_Framework_TestCase {
8+
9+
public function testLDUserKey() {
10+
$user = (new LDUserBuilder("[email protected]"))->build();
11+
$this->assertEquals("[email protected]", $user->getKey());
12+
$this->assertEquals("[email protected]", $user->toJSON()['key']);
13+
}
14+
15+
public function testLDUserSecondary() {
16+
$user = (new LDUserBuilder("[email protected]"))->secondary("secondary")->build();
17+
$this->assertEquals("secondary", $user->getSecondary());
18+
$this->assertEquals("secondary", $user->toJSON()['secondary']);
19+
}
20+
21+
public function testLDUserIP() {
22+
$user = (new LDUserBuilder("[email protected]"))->ip("127.0.0.1")->build();
23+
$this->assertEquals("127.0.0.1", $user->getIP());
24+
$this->assertEquals("127.0.0.1", $user->toJSON()['ip']);
25+
}
26+
27+
public function testLDUserCountry() {
28+
$user = (new LDUserBuilder("[email protected]"))->country("US")->build();
29+
$this->assertEquals("US", $user->getCountry());
30+
$this->assertEquals("US", $user->toJSON()['country']);
31+
}
32+
33+
public function testLDUserEmail() {
34+
$user = (new LDUserBuilder("[email protected]"))->email("[email protected]")->build();
35+
$this->assertEquals("[email protected]", $user->getEmail());
36+
$this->assertEquals("[email protected]", $user->toJSON()['email']);
37+
}
38+
39+
public function testLDUserName() {
40+
$user = (new LDUserBuilder("[email protected]"))->name("Foo Bar")->build();
41+
$this->assertEquals("Foo Bar", $user->getName());
42+
$this->assertEquals("Foo Bar", $user->toJSON()['name']);
43+
}
44+
45+
public function testLDUserAvatar() {
46+
$user = (new LDUserBuilder("[email protected]"))->avatar("http://www.gravatar.com/avatar/1")->build();
47+
$this->assertEquals("http://www.gravatar.com/avatar/1", $user->getAvatar());
48+
$this->assertEquals("http://www.gravatar.com/avatar/1", $user->toJSON()['avatar']);
49+
}
50+
51+
public function testLDUserFirstName() {
52+
$user = (new LDUserBuilder("[email protected]"))->firstName("Foo")->build();
53+
$this->assertEquals("Foo", $user->getFirstName());
54+
$this->assertEquals("Foo", $user->toJSON()['firstName']);
55+
}
56+
57+
public function testLDUserLastName() {
58+
$user = (new LDUserBuilder("[email protected]"))->lastName("Bar")->build();
59+
$this->assertEquals("Bar", $user->getLastName());
60+
$this->assertEquals("Bar", $user->toJSON()['lastName']);
61+
}
62+
}
63+

0 commit comments

Comments
 (0)