|
263 | 263 | end
|
264 | 264 |
|
265 | 265 | describe 'when a UserProfile service is provided' do
|
266 |
| - it 'should look up the UserProfile, bucket normally, and save the result if no saved profile is found' do |
267 |
| - expected_user_profile = { |
268 |
| - user_id: 'test_user', |
269 |
| - experiment_bucket_map: { |
270 |
| - '111127' => { |
271 |
| - variation_id: '111128' |
272 |
| - } |
273 |
| - } |
274 |
| - } |
275 |
| - expect(spy_user_profile_service).to receive(:lookup).once.and_return(nil) |
276 |
| - |
277 |
| - user_context = project_instance.create_user_context('test_user') |
278 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
279 |
| - expect(variation_received).to eq('111128') |
280 |
| - expect(reasons).to eq([ |
281 |
| - "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.", |
282 |
| - "User 'test_user' is in variation 'control' of experiment '111127'." |
283 |
| - ]) |
284 |
| - |
285 |
| - # bucketing should have occurred |
286 |
| - expect(decision_service.bucketer).to have_received(:bucket).once |
287 |
| - # bucketing decision should have been saved |
288 |
| - expect(spy_user_profile_service).to have_received(:save).once.with(expected_user_profile) |
289 |
| - expect(spy_logger).to have_received(:log).once |
290 |
| - .with(Logger::INFO, "Saved variation ID 111128 of experiment ID 111127 for user 'test_user'.") |
291 |
| - end |
292 |
| - |
293 |
| - it 'should look up the UserProfile, bucket normally (using Bucketing ID attribute), and save the result if no saved profile is found' do |
294 |
| - expected_user_profile = { |
295 |
| - user_id: 'test_user', |
296 |
| - experiment_bucket_map: { |
297 |
| - '111127' => { |
298 |
| - variation_id: '111129' |
299 |
| - } |
300 |
| - } |
301 |
| - } |
| 266 | + it 'bucket normally (using Bucketing ID attribute)' do |
302 | 267 | user_attributes = {
|
303 | 268 | 'browser_type' => 'firefox',
|
304 | 269 | Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID'] => 'pid'
|
305 | 270 | }
|
306 |
| - expect(spy_user_profile_service).to receive(:lookup).once.and_return(nil) |
307 |
| - |
308 | 271 | user_context = project_instance.create_user_context('test_user', user_attributes)
|
309 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 272 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 273 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker) |
310 | 274 | expect(variation_received).to eq('111129')
|
311 | 275 | expect(reasons).to eq([
|
312 | 276 | "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.",
|
|
315 | 279 |
|
316 | 280 | # bucketing should have occurred
|
317 | 281 | expect(decision_service.bucketer).to have_received(:bucket).once
|
318 |
| - # bucketing decision should have been saved |
319 |
| - expect(spy_user_profile_service).to have_received(:save).once.with(expected_user_profile) |
320 |
| - expect(spy_logger).to have_received(:log).once |
321 |
| - .with(Logger::INFO, "Saved variation ID 111129 of experiment ID 111127 for user 'test_user'.") |
322 | 282 | end
|
323 | 283 |
|
324 |
| - it 'should look up the user profile and skip normal bucketing if a profile with a saved decision is found' do |
| 284 | + it 'skip normal bucketing if a profile with a saved decision is found' do |
325 | 285 | saved_user_profile = {
|
326 | 286 | user_id: 'test_user',
|
327 | 287 | experiment_bucket_map: {
|
|
334 | 294 | .with('test_user').once.and_return(saved_user_profile)
|
335 | 295 |
|
336 | 296 | user_context = project_instance.create_user_context('test_user')
|
337 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 297 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 298 | + user_profile_tracker.load_user_profile |
| 299 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker) |
338 | 300 | expect(variation_received).to eq('111129')
|
339 | 301 | expect(reasons).to eq([
|
340 | 302 | "Returning previously activated variation ID 111129 of experiment 'test_experiment' for user 'test_user' from user profile."
|
|
350 | 312 | expect(spy_user_profile_service).not_to have_received(:save)
|
351 | 313 | end
|
352 | 314 |
|
353 |
| - it 'should look up the user profile and bucket normally if a profile without a saved decision is found' do |
| 315 | + it 'bucket normally if a profile without a saved decision is found' do |
354 | 316 | saved_user_profile = {
|
355 | 317 | user_id: 'test_user',
|
356 | 318 | experiment_bucket_map: {
|
|
364 | 326 | .once.with('test_user').and_return(saved_user_profile)
|
365 | 327 |
|
366 | 328 | user_context = project_instance.create_user_context('test_user')
|
367 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 329 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 330 | + user_profile_tracker.load_user_profile |
| 331 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker) |
368 | 332 | expect(variation_received).to eq('111128')
|
369 | 333 | expect(reasons).to eq([
|
370 | 334 | "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.",
|
|
373 | 337 |
|
374 | 338 | # bucketing should have occurred
|
375 | 339 | expect(decision_service.bucketer).to have_received(:bucket).once
|
376 |
| - |
377 |
| - # user profile should have been updated with bucketing decision |
378 |
| - expected_user_profile = { |
379 |
| - user_id: 'test_user', |
380 |
| - experiment_bucket_map: { |
381 |
| - '111127' => { |
382 |
| - variation_id: '111128' |
383 |
| - }, |
384 |
| - '122227' => { |
385 |
| - variation_id: '122228' |
386 |
| - } |
387 |
| - } |
388 |
| - } |
389 |
| - expect(spy_user_profile_service).to have_received(:save).once.with(expected_user_profile) |
390 | 340 | end
|
391 | 341 |
|
392 | 342 | it 'should bucket normally if the user profile contains a variation ID not in the datafile' do
|
|
403 | 353 | .once.with('test_user').and_return(saved_user_profile)
|
404 | 354 |
|
405 | 355 | user_context = project_instance.create_user_context('test_user')
|
406 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 356 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 357 | + user_profile_tracker.load_user_profile |
| 358 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker) |
407 | 359 | expect(variation_received).to eq('111128')
|
408 | 360 | expect(reasons).to eq([
|
409 | 361 | "User 'test_user' was previously bucketed into variation ID '111111' for experiment '111127', but no matching variation was found. Re-bucketing user.",
|
|
413 | 365 |
|
414 | 366 | # bucketing should have occurred
|
415 | 367 | expect(decision_service.bucketer).to have_received(:bucket).once
|
416 |
| - |
417 |
| - # user profile should have been updated with bucketing decision |
418 |
| - expected_user_profile = { |
419 |
| - user_id: 'test_user', |
420 |
| - experiment_bucket_map: { |
421 |
| - '111127' => { |
422 |
| - variation_id: '111128' |
423 |
| - } |
424 |
| - } |
425 |
| - } |
426 |
| - expect(spy_user_profile_service).to have_received(:save).with(expected_user_profile) |
427 | 368 | end
|
428 | 369 |
|
429 |
| - it 'should bucket normally if the user profile service throws an error during lookup' do |
| 370 | + it 'should bucket normally if the user profile tracker throws an error during lookup' do |
430 | 371 | expect(spy_user_profile_service).to receive(:lookup).once.with('test_user').and_throw(:LookupError)
|
431 | 372 |
|
432 | 373 | user_context = project_instance.create_user_context('test_user')
|
433 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 374 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 375 | + user_profile_tracker.load_user_profile |
| 376 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker) |
| 377 | + user_profile_tracker.save_user_profile |
434 | 378 | expect(variation_received).to eq('111128')
|
435 | 379 | expect(reasons).to eq([
|
436 |
| - "Error while looking up user profile for user ID 'test_user': uncaught throw :LookupError.", |
437 | 380 | "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.",
|
438 | 381 | "User 'test_user' is in variation 'control' of experiment '111127'."
|
439 | 382 | ])
|
|
444 | 387 | expect(decision_service.bucketer).to have_received(:bucket).once
|
445 | 388 | end
|
446 | 389 |
|
447 |
| - it 'should log an error if the user profile service throws an error during save' do |
448 |
| - expect(spy_user_profile_service).to receive(:save).once.and_throw(:SaveError) |
449 |
| - |
450 |
| - user_context = project_instance.create_user_context('test_user') |
451 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
452 |
| - expect(variation_received).to eq('111128') |
453 |
| - expect(reasons).to eq([ |
454 |
| - "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.", |
455 |
| - "User 'test_user' is in variation 'control' of experiment '111127'." |
456 |
| - ]) |
457 |
| - |
458 |
| - expect(spy_logger).to have_received(:log).once |
459 |
| - .with(Logger::ERROR, "Error while saving user profile for user ID 'test_user': uncaught throw :SaveError.") |
460 |
| - end |
461 |
| - |
462 | 390 | describe 'IGNORE_USER_PROFILE_SERVICE decide option' do
|
463 | 391 | it 'should ignore user profile service if this option is set' do
|
464 | 392 | allow(spy_user_profile_service).to receive(:lookup)
|
465 | 393 | .with('test_user').once.and_return(nil)
|
466 | 394 |
|
467 | 395 | user_context = project_instance.create_user_context('test_user', nil)
|
468 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context, [Optimizely::Decide::OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE]) |
469 |
| - expect(variation_received).to eq('111128') |
470 |
| - expect(reasons).to eq([ |
471 |
| - "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.", |
472 |
| - "User 'test_user' is in variation 'control' of experiment '111127'." |
473 |
| - ]) |
474 |
| - |
475 |
| - expect(decision_service.bucketer).to have_received(:bucket) |
476 |
| - expect(Optimizely::Audience).to have_received(:user_meets_audience_conditions?) |
477 |
| - expect(spy_user_profile_service).not_to have_received(:lookup) |
478 |
| - expect(spy_user_profile_service).not_to have_received(:save) |
479 |
| - end |
480 |
| - |
481 |
| - it 'should not ignore user profile service if this option is not set' do |
482 |
| - allow(spy_user_profile_service).to receive(:lookup) |
483 |
| - .with('test_user').once.and_return(nil) |
484 |
| - |
485 |
| - user_context = project_instance.create_user_context('test_user') |
486 |
| - variation_received, reasons = decision_service.get_variation(config, '111127', user_context) |
| 396 | + user_profile_tracker = Optimizely::UserProfileTracker.new(user_context.user_id, spy_user_profile_service, spy_logger) |
| 397 | + user_profile_tracker.load_user_profile |
| 398 | + variation_received, reasons = decision_service.get_variation(config, '111127', user_context, user_profile_tracker, [Optimizely::Decide::OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE]) |
487 | 399 | expect(variation_received).to eq('111128')
|
488 | 400 | expect(reasons).to eq([
|
489 | 401 | "Audiences for experiment 'test_experiment' collectively evaluated to TRUE.",
|
|
492 | 404 |
|
493 | 405 | expect(decision_service.bucketer).to have_received(:bucket)
|
494 | 406 | expect(Optimizely::Audience).to have_received(:user_meets_audience_conditions?)
|
495 |
| - expect(spy_user_profile_service).to have_received(:lookup) |
496 |
| - expect(spy_user_profile_service).to have_received(:save) |
497 | 407 | end
|
498 | 408 | end
|
499 | 409 | end
|
|
0 commit comments