Skip to content

Commit 56507ab

Browse files
Remove version restrictions from datafile parsing (#41)
1 parent e3eef7c commit 56507ab

File tree

3 files changed

+281
-4
lines changed

3 files changed

+281
-4
lines changed

src/Optimizely/Utils/ConfigParser.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -36,7 +36,9 @@ public static function generateMap($entities, $entityId, $entityClass)
3636
forEach ($entity as $key => $value)
3737
{
3838
$propSetter = 'set'.ucfirst($key);
39-
$entityObject->$propSetter($value);
39+
if (method_exists($entityObject, $propSetter)) {
40+
$entityObject->$propSetter($value);
41+
}
4042
}
4143

4244
if (is_null($entityId)) {

tests/ProjectConfigTest.php

Lines changed: 239 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -171,6 +171,244 @@ public function testInit()
171171
], $variationIdMap->getValue($this->config));
172172
}
173173

174+
public function testInitWithDatafileV3()
175+
{
176+
// Init with v3 datafile
177+
$this->config = new ProjectConfig(DATAFILE_V3, $this->loggerMock, $this->errorHandlerMock);
178+
179+
// Check version
180+
$version = new \ReflectionProperty(ProjectConfig::class, '_version');
181+
$version->setAccessible(true);
182+
$this->assertEquals('2', $version->getValue($this->config));
183+
184+
// Check account ID
185+
$accountId = new \ReflectionProperty(ProjectConfig::class, '_accountId');
186+
$accountId->setAccessible(true);
187+
$this->assertEquals('1592310167', $accountId->getValue($this->config));
188+
189+
// Check project ID
190+
$projectId = new \ReflectionProperty(ProjectConfig::class, '_projectId');
191+
$projectId->setAccessible(true);
192+
$this->assertEquals('7720880029', $projectId->getValue($this->config));
193+
194+
// Check revision
195+
$revision = new \ReflectionProperty(ProjectConfig::class, '_revision');
196+
$revision->setAccessible(true);
197+
$this->assertEquals('15', $revision->getValue($this->config));
198+
199+
// Check group ID map
200+
$groupIdMap = new \ReflectionProperty(ProjectConfig::class, '_groupIdMap');
201+
$groupIdMap->setAccessible(true);
202+
$this->assertEquals([
203+
'7722400015' => $this->config->getGroup('7722400015')
204+
], $groupIdMap->getValue($this->config));
205+
206+
// Check experiment key map
207+
$experimentKeyMap = new \ReflectionProperty(ProjectConfig::class, '_experimentKeyMap');
208+
$experimentKeyMap->setAccessible(true);
209+
$this->assertEquals([
210+
'test_experiment' => $this->config->getExperimentFromKey('test_experiment'),
211+
'paused_experiment' => $this->config->getExperimentFromKey('paused_experiment'),
212+
'group_experiment_1' => $this->config->getExperimentFromKey('group_experiment_1'),
213+
'group_experiment_2' => $this->config->getExperimentFromKey('group_experiment_2')
214+
], $experimentKeyMap->getValue($this->config));
215+
216+
// Check experiment ID map
217+
$experimentIdMap = new \ReflectionProperty(ProjectConfig::class, '_experimentIdMap');
218+
$experimentIdMap->setAccessible(true);
219+
$this->assertEquals([
220+
'7716830082' => $this->config->getExperimentFromId('7716830082'),
221+
'7723330021' => $this->config->getExperimentFromId('7723330021'),
222+
'7718750065' => $this->config->getExperimentFromId('7718750065'),
223+
'7716830585' => $this->config->getExperimentFromId('7716830585')
224+
], $experimentIdMap->getValue($this->config));
225+
226+
// Check event key map
227+
$eventKeyMap = new \ReflectionProperty(ProjectConfig::class, '_eventKeyMap');
228+
$eventKeyMap->setAccessible(true);
229+
$this->assertEquals([
230+
'purchase' => $this->config->getEvent('purchase')
231+
], $eventKeyMap->getValue($this->config));
232+
233+
// Check attribute key map
234+
$attributeKeyMap = new \ReflectionProperty(ProjectConfig::class, '_attributeKeyMap');
235+
$attributeKeyMap->setAccessible(true);
236+
$this->assertEquals([
237+
'device_type' => $this->config->getAttribute('device_type'),
238+
'location' => $this->config->getAttribute('location')
239+
], $attributeKeyMap->getValue($this->config));
240+
241+
// Check audience ID map
242+
$audienceIdMap = new \ReflectionProperty(ProjectConfig::class, '_audienceIdMap');
243+
$audienceIdMap->setAccessible(true);
244+
$this->assertEquals([
245+
'7718080042' => $this->config->getAudience('7718080042')
246+
], $audienceIdMap->getValue($this->config));
247+
248+
// Check variation key map
249+
$variationKeyMap = new \ReflectionProperty(ProjectConfig::class, '_variationKeyMap');
250+
$variationKeyMap->setAccessible(true);
251+
$this->assertEquals([
252+
'test_experiment' => [
253+
'control' => $this->config->getVariationFromKey('test_experiment', 'control'),
254+
'variation' => $this->config->getVariationFromKey('test_experiment', 'variation')
255+
],
256+
'paused_experiment' => [
257+
'control' => $this->config->getVariationFromKey('paused_experiment', 'control'),
258+
'variation' => $this->config->getVariationFromKey('paused_experiment', 'variation')
259+
],
260+
'group_experiment_1' => [
261+
'group_exp_1_var_1' => $this->config->getVariationFromKey('group_experiment_1', 'group_exp_1_var_1'),
262+
'group_exp_1_var_2' => $this->config->getVariationFromKey('group_experiment_1', 'group_exp_1_var_2')
263+
],
264+
'group_experiment_2' => [
265+
'group_exp_2_var_1' => $this->config->getVariationFromKey('group_experiment_2', 'group_exp_2_var_1'),
266+
'group_exp_2_var_2' => $this->config->getVariationFromKey('group_experiment_2', 'group_exp_2_var_2')
267+
]
268+
], $variationKeyMap->getValue($this->config));
269+
270+
// Check variation ID map
271+
$variationIdMap = new \ReflectionProperty(ProjectConfig::class, '_variationIdMap');
272+
$variationIdMap->setAccessible(true);
273+
$this->assertEquals([
274+
'test_experiment' => [
275+
'7722370027' => $this->config->getVariationFromId('test_experiment', '7722370027'),
276+
'7721010009' => $this->config->getVariationFromId('test_experiment', '7721010009')
277+
],
278+
'paused_experiment' => [
279+
'7722370427' => $this->config->getVariationFromId('paused_experiment', '7722370427'),
280+
'7721010509' => $this->config->getVariationFromId('paused_experiment', '7721010509')
281+
],
282+
'group_experiment_1' => [
283+
'7722260071' => $this->config->getVariationFromId('group_experiment_1', '7722260071'),
284+
'7722360022' => $this->config->getVariationFromId('group_experiment_1', '7722360022')
285+
],
286+
'group_experiment_2' => [
287+
'7713030086' => $this->config->getVariationFromId('group_experiment_2', '7713030086'),
288+
'7725250007' => $this->config->getVariationFromId('group_experiment_2', '7725250007')
289+
]
290+
], $variationIdMap->getValue($this->config));
291+
}
292+
293+
public function testInitWithMoreData()
294+
{
295+
// Init with datafile consisting of more fields
296+
$this->config = new ProjectConfig(DATAFILE_MORE_DATA, $this->loggerMock, $this->errorHandlerMock);
297+
298+
// Check version
299+
$version = new \ReflectionProperty(ProjectConfig::class, '_version');
300+
$version->setAccessible(true);
301+
$this->assertEquals('2', $version->getValue($this->config));
302+
303+
// Check account ID
304+
$accountId = new \ReflectionProperty(ProjectConfig::class, '_accountId');
305+
$accountId->setAccessible(true);
306+
$this->assertEquals('1592310167', $accountId->getValue($this->config));
307+
308+
// Check project ID
309+
$projectId = new \ReflectionProperty(ProjectConfig::class, '_projectId');
310+
$projectId->setAccessible(true);
311+
$this->assertEquals('7720880029', $projectId->getValue($this->config));
312+
313+
// Check revision
314+
$revision = new \ReflectionProperty(ProjectConfig::class, '_revision');
315+
$revision->setAccessible(true);
316+
$this->assertEquals('15', $revision->getValue($this->config));
317+
318+
// Check group ID map
319+
$groupIdMap = new \ReflectionProperty(ProjectConfig::class, '_groupIdMap');
320+
$groupIdMap->setAccessible(true);
321+
$this->assertEquals([
322+
'7722400015' => $this->config->getGroup('7722400015')
323+
], $groupIdMap->getValue($this->config));
324+
325+
// Check experiment key map
326+
$experimentKeyMap = new \ReflectionProperty(ProjectConfig::class, '_experimentKeyMap');
327+
$experimentKeyMap->setAccessible(true);
328+
$this->assertEquals([
329+
'test_experiment' => $this->config->getExperimentFromKey('test_experiment'),
330+
'paused_experiment' => $this->config->getExperimentFromKey('paused_experiment'),
331+
'group_experiment_1' => $this->config->getExperimentFromKey('group_experiment_1'),
332+
'group_experiment_2' => $this->config->getExperimentFromKey('group_experiment_2')
333+
], $experimentKeyMap->getValue($this->config));
334+
335+
// Check experiment ID map
336+
$experimentIdMap = new \ReflectionProperty(ProjectConfig::class, '_experimentIdMap');
337+
$experimentIdMap->setAccessible(true);
338+
$this->assertEquals([
339+
'7716830082' => $this->config->getExperimentFromId('7716830082'),
340+
'7723330021' => $this->config->getExperimentFromId('7723330021'),
341+
'7718750065' => $this->config->getExperimentFromId('7718750065'),
342+
'7716830585' => $this->config->getExperimentFromId('7716830585')
343+
], $experimentIdMap->getValue($this->config));
344+
345+
// Check event key map
346+
$eventKeyMap = new \ReflectionProperty(ProjectConfig::class, '_eventKeyMap');
347+
$eventKeyMap->setAccessible(true);
348+
$this->assertEquals([
349+
'purchase' => $this->config->getEvent('purchase')
350+
], $eventKeyMap->getValue($this->config));
351+
352+
// Check attribute key map
353+
$attributeKeyMap = new \ReflectionProperty(ProjectConfig::class, '_attributeKeyMap');
354+
$attributeKeyMap->setAccessible(true);
355+
$this->assertEquals([
356+
'device_type' => $this->config->getAttribute('device_type'),
357+
'location' => $this->config->getAttribute('location')
358+
], $attributeKeyMap->getValue($this->config));
359+
360+
// Check audience ID map
361+
$audienceIdMap = new \ReflectionProperty(ProjectConfig::class, '_audienceIdMap');
362+
$audienceIdMap->setAccessible(true);
363+
$this->assertEquals([
364+
'7718080042' => $this->config->getAudience('7718080042')
365+
], $audienceIdMap->getValue($this->config));
366+
367+
// Check variation key map
368+
$variationKeyMap = new \ReflectionProperty(ProjectConfig::class, '_variationKeyMap');
369+
$variationKeyMap->setAccessible(true);
370+
$this->assertEquals([
371+
'test_experiment' => [
372+
'control' => $this->config->getVariationFromKey('test_experiment', 'control'),
373+
'variation' => $this->config->getVariationFromKey('test_experiment', 'variation')
374+
],
375+
'paused_experiment' => [
376+
'control' => $this->config->getVariationFromKey('paused_experiment', 'control'),
377+
'variation' => $this->config->getVariationFromKey('paused_experiment', 'variation')
378+
],
379+
'group_experiment_1' => [
380+
'group_exp_1_var_1' => $this->config->getVariationFromKey('group_experiment_1', 'group_exp_1_var_1'),
381+
'group_exp_1_var_2' => $this->config->getVariationFromKey('group_experiment_1', 'group_exp_1_var_2')
382+
],
383+
'group_experiment_2' => [
384+
'group_exp_2_var_1' => $this->config->getVariationFromKey('group_experiment_2', 'group_exp_2_var_1'),
385+
'group_exp_2_var_2' => $this->config->getVariationFromKey('group_experiment_2', 'group_exp_2_var_2')
386+
]
387+
], $variationKeyMap->getValue($this->config));
388+
389+
// Check variation ID map
390+
$variationIdMap = new \ReflectionProperty(ProjectConfig::class, '_variationIdMap');
391+
$variationIdMap->setAccessible(true);
392+
$this->assertEquals([
393+
'test_experiment' => [
394+
'7722370027' => $this->config->getVariationFromId('test_experiment', '7722370027'),
395+
'7721010009' => $this->config->getVariationFromId('test_experiment', '7721010009')
396+
],
397+
'paused_experiment' => [
398+
'7722370427' => $this->config->getVariationFromId('paused_experiment', '7722370427'),
399+
'7721010509' => $this->config->getVariationFromId('paused_experiment', '7721010509')
400+
],
401+
'group_experiment_1' => [
402+
'7722260071' => $this->config->getVariationFromId('group_experiment_1', '7722260071'),
403+
'7722360022' => $this->config->getVariationFromId('group_experiment_1', '7722360022')
404+
],
405+
'group_experiment_2' => [
406+
'7713030086' => $this->config->getVariationFromId('group_experiment_2', '7713030086'),
407+
'7725250007' => $this->config->getVariationFromId('group_experiment_2', '7725250007')
408+
]
409+
], $variationIdMap->getValue($this->config));
410+
}
411+
174412
public function testGetAccountId()
175413
{
176414
$this->assertEquals('1592310167', $this->config->getAccountId());

tests/TestData.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Copyright 2016, Optimizely
3+
* Copyright 2016-2017, Optimizely
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
@@ -39,6 +39,43 @@
3939
"events": [{"experimentIds": ["7716830082", "7723330021", "7718750065", "7716830585"], "id": "7718020063", "key": "purchase"}],
4040
"revision": "15"}');
4141

42+
define('DATAFILE_V3',
43+
'{"experiments": [{"status": "Running", "key": "test_experiment", "layerId": "7719770039",
44+
"trafficAllocation": [{"entityId": "", "endOfRange": 1500}, {"entityId": "7722370027", "endOfRange": 4000},
45+
{"entityId": "7721010009", "endOfRange": 8000}], "audienceIds": ["7718080042"],
46+
"variations": [{"id": "7722370027", "key": "control", "variables": [{"id": "8284765437", "value": "true"}]}, {"id": "7721010009", "key": "variation", "variables": [{"id": "8284765437", "value": "false"}]}],
47+
"forcedVariations": {"user1": "control"}, "id": "7716830082"}, {"status": "Paused", "key": "paused_experiment", "layerId": "7719779139",
48+
"trafficAllocation": [{"entityId": "7722370427", "endOfRange": 5000},
49+
{"entityId": "7721010509", "endOfRange": 8000}], "audienceIds": [],
50+
"variations": [{"id": "7722370427", "key": "control", "variables": []}, {"id": "7721010509", "key": "variation", "variables": []}],
51+
"forcedVariations": {}, "id": "7716830585"}], "version": "2",
52+
"audiences": [{"conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"device_type\", \"type\": \"custom_attribute\", \"value\": \"iPhone\"}]], [\"or\", [\"or\", {\"name\": \"location\", \"type\": \"custom_attribute\", \"value\": \"San Francisco\"}]]]", "id": "7718080042", "name": "iPhone users in San Francisco"}],
53+
"groups": [{"policy": "random", "trafficAllocation": [{"entityId": "", "endOfRange": 500}, {"entityId": "7723330021", "endOfRange": 2000}, {"entityId": "7718750065", "endOfRange": 6000}], "experiments": [{"status": "Running", "key": "group_experiment_1", "layerId": "7721010011", "trafficAllocation": [{"entityId": "7722260071", "endOfRange": 5000}, {"entityId": "7722360022", "endOfRange": 10000}], "audienceIds": [], "variations": [{"id": "7722260071", "key": "group_exp_1_var_1", "variables": []}, {"id": "7722360022", "key": "group_exp_1_var_2", "variables": []}], "forcedVariations": {"user1": "group_exp_1_var_1"}, "id": "7723330021"}, {"status": "Running", "key": "group_experiment_2", "layerId": "7721020020", "trafficAllocation": [{"entityId": "7713030086", "endOfRange": 5000}, {"entityId": "7725250007", "endOfRange": 10000}], "audienceIds": [],
54+
"variations": [{"id": "7713030086", "key": "group_exp_2_var_1", "variables": []}, {"id": "7725250007", "key": "group_exp_2_var_2", "variables": []}], "forcedVariations": {}, "id": "7718750065"}], "id": "7722400015"}],
55+
"attributes": [{"id": "7723280020", "key": "device_type"}, {"id": "7723340004", "key": "location"}],
56+
"projectId": "7720880029", "accountId": "1592310167",
57+
"events": [{"experimentIds": ["7716830082", "7723330021", "7718750065", "7716830585"], "id": "7718020063", "key": "purchase"}],
58+
"anonymizeIP": false, "variables": [{"defaultValue": "true", "type": "boolean", "id": "8284765437", "key": "is_working"}],
59+
"revision": "15"}');
60+
61+
define('DATAFILE_MORE_DATA',
62+
'{"experiments": [{"status": "Running", "key": "test_experiment", "layerId": "7719770039",
63+
"trafficAllocation": [{"entityId": "", "endOfRange": 1500}, {"entityId": "7722370027", "endOfRange": 4000},
64+
{"entityId": "7721010009", "endOfRange": 8000}], "audienceIds": ["7718080042"],
65+
"variations": [{"id": "7722370027", "key": "control"}, {"id": "7721010009", "key": "variation"}],
66+
"forcedVariations": {"user1": "control"}, "id": "7716830082"}, {"status": "Paused", "key": "paused_experiment", "layerId": "7719779139",
67+
"trafficAllocation": [{"entityId": "7722370427", "endOfRange": 5000},
68+
{"entityId": "7721010509", "endOfRange": 8000}], "audienceIds": [],
69+
"variations": [{"id": "7722370427", "key": "control"}, {"id": "7721010509", "key": "variation", "some_additiona_key": "some_additional_value"}],
70+
"forcedVariations": {}, "id": "7716830585"}], "version": "2",
71+
"audiences": [{"conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"device_type\", \"type\": \"custom_attribute\", \"value\": \"iPhone\"}]], [\"or\", [\"or\", {\"name\": \"location\", \"type\": \"custom_attribute\", \"value\": \"San Francisco\"}]]]", "id": "7718080042", "name": "iPhone users in San Francisco"}],
72+
"groups": [{"policy": "random", "trafficAllocation": [{"entityId": "", "endOfRange": 500}, {"entityId": "7723330021", "endOfRange": 2000}, {"entityId": "7718750065", "endOfRange": 6000}], "experiments": [{"status": "Running", "key": "group_experiment_1", "layerId": "7721010011", "trafficAllocation": [{"entityId": "7722260071", "endOfRange": 5000}, {"entityId": "7722360022", "endOfRange": 10000}], "audienceIds": [], "variations": [{"id": "7722260071", "key": "group_exp_1_var_1"}, {"id": "7722360022", "key": "group_exp_1_var_2"}], "forcedVariations": {"user1": "group_exp_1_var_1"}, "id": "7723330021"}, {"status": "Running", "key": "group_experiment_2", "layerId": "7721020020", "trafficAllocation": [{"entityId": "7713030086", "endOfRange": 5000}, {"entityId": "7725250007", "endOfRange": 10000}], "audienceIds": [],
73+
"variations": [{"id": "7713030086", "key": "group_exp_2_var_1"}, {"id": "7725250007", "key": "group_exp_2_var_2"}], "forcedVariations": {}, "id": "7718750065"}], "id": "7722400015"}],
74+
"attributes": [{"id": "7723280020", "key": "device_type"}, {"id": "7723340004", "key": "location"}],
75+
"projectId": "7720880029", "accountId": "1592310167",
76+
"events": [{"experimentIds": ["7716830082", "7723330021", "7718750065", "7716830585"], "id": "7718020063", "key": "purchase"}],
77+
"revision": "15", "random_data_key": [{"key_1": "value_1", "key_2": "value_2"}]}');
78+
4279
/**
4380
* Class TestBucketer
4481
* Extending Bucketer for the sake of tests.

0 commit comments

Comments
 (0)