def test_visit_incorporate(self):
        alternative = participant(self.request).enroll(self.experiment.name, ['alternative'])

        ExperimentsRetentionMiddleware().process_response(self.request, HttpResponse())

        self.assertEqual(
            dict(self.experiment_counter.participant_goal_frequencies(self.experiment,
                                                                      alternative,
                                                                      participant(self.request)._participant_identifier()))[conf.VISIT_NOT_PRESENT_COUNT_GOAL],
            1
        )

        self.assertFalse(Enrollment.objects.all().exists())
        self._login()

        self.assertTrue(Enrollment.objects.all().exists())
        self.assertIsNotNone(Enrollment.objects.all()[0].last_seen)
        self.assertEqual(
            dict(self.experiment_counter.participant_goal_frequencies(self.experiment,
                                                                      alternative,
                                                                      participant(self.request)._participant_identifier()))[conf.VISIT_NOT_PRESENT_COUNT_GOAL],
            1
        )
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, alternative, conf.VISIT_NOT_PRESENT_COUNT_GOAL), 1)
        self.assertEqual(self.experiment_counter.participant_count(self.experiment, alternative), 1)
    def test_visit_incorporate(self):
        alternative = participant(self.request).enroll(self.experiment.name,
                                                       ['alternative'])

        ExperimentsRetentionMiddleware().process_response(
            self.request, HttpResponse())

        self.assertEqual(
            dict(
                self.experiment_counter.participant_goal_frequencies(
                    self.experiment, alternative,
                    participant(self.request)._participant_identifier()))[
                        conf.VISIT_NOT_PRESENT_COUNT_GOAL], 1)

        self.assertFalse(Enrollment.objects.all().exists())
        self._login()

        self.assertTrue(Enrollment.objects.all().exists())
        self.assertIsNotNone(Enrollment.objects.all()[0].last_seen)
        self.assertEqual(
            dict(
                self.experiment_counter.participant_goal_frequencies(
                    self.experiment, alternative,
                    participant(self.request)._participant_identifier()))[
                        conf.VISIT_NOT_PRESENT_COUNT_GOAL], 1)
        self.assertEqual(
            self.experiment_counter.goal_count(
                self.experiment, alternative,
                conf.VISIT_NOT_PRESENT_COUNT_GOAL), 1)
        self.assertEqual(
            self.experiment_counter.participant_count(self.experiment,
                                                      alternative), 1)
Пример #3
0
    def render(self, context):
        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
            gargoyle_key = auth_user
        else:
            request = context.get('request', None)
            user = participant(request)
            gargoyle_key = request

        # Extract session alternative, if any pertain to this experiment.
        selected_alternative = None
        if 'experiment' in request.session:
            if request.session['experiment'] == self.experiment_name:
                selected_alternative = request.session['alternative']
                del request.session['experiment']

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative, gargoyle_key, selected_alternative):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
    def test_set_alternative(self):
        experiment = Experiment.objects.create(name='test_experiment',
                                               state=ENABLED_STATE)
        user = User.objects.create_superuser(username='******',
                                             email='*****@*****.**',
                                             password='******')
        self.client.login(username='******', password='******')

        participant(user=user).enroll('test_experiment',
                                      alternatives=['other1', 'other2'])

        for alternative in ('other2', 'control', 'other1'):
            response = self.client.post(
                reverse('admin:experiment_admin_set_alternative'), {
                    'experiment': experiment.name,
                    'alternative': alternative,
                })
            self.assertDictEqual(json.loads(response.content.decode('utf-8')),
                                 {
                                     'success': True,
                                     'alternative': alternative,
                                 })
            self.assertEqual(
                participant(user=user).get_alternative('test_experiment'),
                alternative)
Пример #5
0
def change_alternative(request, experiment_name, alternative_name):
    experiment = get_object_or_404(Experiment, name=experiment_name)
    if alternative_name not in experiment.alternatives.keys():
        return HttpResponseBadRequest()

    participant(request).set_alternative(experiment_name, alternative_name)
    return HttpResponse('OK')
Пример #6
0
def change_alternative(request, experiment_name, alternative_name):
    experiment = get_object_or_404(Experiment, name=experiment_name)
    if alternative_name not in experiment.alternatives.keys():
        return HttpResponseBadRequest()

    participant(request).set_alternative(experiment_name, alternative_name)
    return HttpResponse('OK')
 def set_alternative(self, request):
     experiment_name = request.POST.get("experiment")
     alternative_name = request.POST.get("alternative")
     participant(request).set_alternative(experiment_name, alternative_name)
     return {
         'success': True,
         'alternative': participant(request).get_alternative(experiment_name)
     }
Пример #8
0
 def set_alternative(self, request):
     experiment_name = request.POST.get("experiment")
     alternative_name = request.POST.get("alternative")
     participant(request).set_alternative(experiment_name, alternative_name)
     return {
         'success': True,
         'alternative': participant(request).get_alternative(experiment_name)
     }
    def setUp(self):
        self.experiment = Experiment.objects.create(name=EXPERIMENT_NAME, state=ENABLED_STATE)
        self.experiment_counter = ExperimentCounter()

        User = get_user_model()
        self.user = User.objects.create(username='******')
        self.user.is_confirmed_human = True

        request_factory = RequestFactory()
        self.request = request_factory.get('/')
        self.request.session = DatabaseSession()
        participant(self.request).confirm_human()
    def setUp(self):
        self.experiment = Experiment.objects.create(name=EXPERIMENT_NAME,
                                                    state=ENABLED_STATE)
        self.experiment_counter = ExperimentCounter()

        User = get_user_model()
        self.user = User.objects.create(username='******')
        self.user.is_confirmed_human = True

        request_factory = RequestFactory()
        self.request = request_factory.get('/')
        self.request.session = DatabaseSession()
        participant(self.request).confirm_human()
Пример #11
0
    def test_default_alternative(self):
        experiment = Experiment.objects.create(name='test_default')
        self.assertEqual(experiment.default_alternative, conf.CONTROL_GROUP)
        experiment.ensure_alternative_exists('alt1')
        experiment.ensure_alternative_exists('alt2')

        self.assertEqual(conf.CONTROL_GROUP, participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
        experiment.set_default_alternative('alt2')
        experiment.save()
        self.assertEqual('alt2', participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
        experiment.set_default_alternative('alt1')
        experiment.save()
        self.assertEqual('alt1', participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
Пример #12
0
    def test_default_alternative(self):
        experiment = Experiment.objects.create(name='test_default')
        self.assertEqual(experiment.default_alternative, conf.CONTROL_GROUP)
        experiment.ensure_alternative_exists('alt1')
        experiment.ensure_alternative_exists('alt2')

        self.assertEqual(conf.CONTROL_GROUP, participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
        experiment.set_default_alternative('alt2')
        experiment.save()
        self.assertEqual('alt2', participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
        experiment.set_default_alternative('alt1')
        experiment.save()
        self.assertEqual('alt1', participant(session=DatabaseSession()).enroll('test_default', ['alt1', 'alt2']))
Пример #13
0
 def test_transfer_enrollments(self):
     User = get_user_model()
     user = User.objects.create(username='******')
     request = request_factory.get('/')
     request.session = DatabaseSession()
     participant(request).enroll('test_experiment1', ['alternative'])
     request.user = user
     transfer_enrollments_to_user(None, request, user)
     # the call to the middleware will set last_seen on the experiment
     # if the participant cache hasn't been wiped appropriately then the
     # session experiment user will be impacted instead of the authenticated
     # experiment user
     ExperimentsRetentionMiddleware().process_response(request, HttpResponse())
     self.assertIsNotNone(Enrollment.objects.all()[0].last_seen)
Пример #14
0
 def test_transfer_enrollments(self):
     User = get_user_model()
     user = User.objects.create(username='******')
     request = request_factory.get('/')
     request.session = DatabaseSession()
     participant(request).enroll('test_experiment1', ['alternative'])
     request.user = user
     transfer_enrollments_to_user(None, request, user)
     # the call to the middleware will set last_seen on the experiment
     # if the participant cache hasn't been wiped appropriately then the
     # session experiment user will be impacted instead of the authenticated
     # experiment user
     ExperimentsRetentionMiddleware().process_response(request, HttpResponse())
     self.assertIsNotNone(Enrollment.objects.all()[0].last_seen)
Пример #15
0
 def test_user_does_not_enroll(self):
     experiment_user = participant(self.request)
     experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
     self.assertEqual(
         self.experiment_counter.participant_count(self.experiment,
                                                   TEST_ALTERNATIVE), 0,
         "Bot counted towards results")
Пример #16
0
 def setUp(self):
     self.experiment = Experiment.objects.create(name='test_experiment1', state=ENABLED_STATE)
     self.experiment_counter = ExperimentCounter()
     self.experiment_user = participant(session=DatabaseSession())
     self.alternative = self.experiment_user.enroll(self.experiment.name, ['alternative'])
     self.experiment_user.goal('my_goal')
     self.redis = get_redis_client()
Пример #17
0
    def test_counts_increment_immediately_once_confirmed_human(self):
        experiment_user = participant(self.request)
        self.confirm_human(experiment_user)

        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
        self.assertEqual(self.participants(TEST_ALTERNATIVE), 1,
                         "Did not count participant after confirm human")
Пример #18
0
    def test_visit_increases_goal(self):
        thetime = timezone.now()
        with mock.patch('experiments.utils.now', return_value=thetime):
            experiment_user = participant(self.request)
            experiment_user.confirm_human()
            experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

            experiment_user.visit()
            self.assertEqual(
                self.experiment_counter.goal_distribution(
                    self.experiment, TEST_ALTERNATIVE,
                    VISIT_NOT_PRESENT_COUNT_GOAL), {1: 1},
                "Not Present Visit was not correctly counted")
            self.assertEqual(
                self.experiment_counter.goal_distribution(
                    self.experiment, TEST_ALTERNATIVE,
                    VISIT_PRESENT_COUNT_GOAL), {},
                "Present Visit was not correctly counted")

        with mock.patch('experiments.utils.now',
                        return_value=thetime + timedelta(hours=7)):
            experiment_user.visit()
            self.assertEqual(
                self.experiment_counter.goal_distribution(
                    self.experiment, TEST_ALTERNATIVE,
                    VISIT_NOT_PRESENT_COUNT_GOAL), {2: 1},
                "No Present Visit was not correctly counted")
            self.assertEqual(
                self.experiment_counter.goal_distribution(
                    self.experiment, TEST_ALTERNATIVE,
                    VISIT_PRESENT_COUNT_GOAL), {1: 1},
                "Present Visit was not correctly counted")
Пример #19
0
 def test_user_force_enrolls(self):
     experiment_user = participant(self.request)
     experiment_user.enroll(EXPERIMENT_NAME,
                            ['control', 'alternative1', 'alternative2'],
                            force_alternative='alternative2')
     self.assertEqual(experiment_user.get_alternative(EXPERIMENT_NAME),
                      'alternative2')
Пример #20
0
def get_result_context(request, experiment):
    stats = get_experiment_stats(experiment)
    stats.update({
        'user_alternative':
        participant(request).get_alternative(experiment.name),
    })
    return stats
Пример #21
0
 def test_user_does_not_enroll(self):
     experiment_user = participant(self.request)
     experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
     self.assertEqual(
         self.experiment_counter.participant_count(self.experiment, TEST_ALTERNATIVE),
         0,
         "Bot counted towards results",
     )
Пример #22
0
    def set_alternative_view(self, request):
        """
        Allows the admin user to change their assigned alternative
        """
        if not request.user.has_perm('experiments.change_experiment'):
            return HttpResponseForbidden()

        experiment_name = request.POST.get("experiment")
        alternative_name = request.POST.get("alternative")
        if not (experiment_name and alternative_name):
            return HttpResponseBadRequest()

        participant(request).set_alternative(experiment_name, alternative_name)
        return JsonResponse({
            'success': True,
            'alternative': participant(request).get_alternative(experiment_name)
        })
Пример #23
0
    def setUp(self):
        super(LoggedInBotTestCase, self).setUp()
        User = get_user_model()
        self.user = User(username='******')
        self.user.is_confirmed_human = False
        self.user.save()

        self.experiment_user = participant(user=self.user)
Пример #24
0
    def test_confirm_human_increments_goal_count(self):
        experiment_user = participant(self.request)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
        experiment_user.goal(TEST_GOAL)

        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 0, "Counted goal before confirmed human")
        experiment_user.confirm_human()
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not count goal after confirm human")
Пример #25
0
    def test_record_goal_increments_counts(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 0)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not increment Goal count")
Пример #26
0
    def test_visit_increases_goal(self):
        experiment_user = participant(self.request)
        self.confirm_human(experiment_user)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.visit()

        self.assertEqual(self.experiment.goal_distribution(TEST_ALTERNATIVE, VISIT_COUNT_GOAL), {1: 1})
Пример #27
0
    def test_record_goal_increments_counts(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 0)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not increment Goal count")
Пример #28
0
    def test_set_alternative(self):
        experiment = Experiment.objects.create(name='test_experiment', state=ENABLED_STATE)
        user = User.objects.create_superuser(username='******', email='*****@*****.**', password='******')
        self.client.login(username='******', password='******')

        participant(user=user).enroll('test_experiment', alternatives=['other1', 'other2'])

        for alternative in ('other2', 'control', 'other1'):
            response = self.client.post(reverse('admin:experiment_admin_set_alternative'), {
                'experiment': experiment.name,
                'alternative': alternative,
            })
            self.assertDictEqual(json.loads(response.content.decode()), {
                'success': True,
                'alternative': alternative,
            })
            self.assertEqual(participant(user=user).get_alternative('test_experiment'), alternative)
Пример #29
0
    def setUp(self):
        super(LoggedInBotTestCase, self).setUp()
        User = get_user_model()
        self.user = User(username='******')
        self.user.is_confirmed_human = False
        self.user.save()

        self.experiment_user = participant(user=self.user)
Пример #30
0
    def test_confirm_human_increments_goal_count(self):
        experiment_user = participant(self.request)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
        experiment_user.goal(TEST_GOAL)

        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 0, "Counted goal before confirmed human")
        experiment_user.confirm_human()
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not count goal after confirm human")
    def render(self, context):
        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
            gargoyle_key = auth_user
        else:
            request = context.get('request', None)
            user = participant(request)
            gargoyle_key = request

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative, gargoyle_key):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
Пример #32
0
    def test_can_record_goal_multiple_times(self):
        experiment_user = participant(self.request)
        self.confirm_human(experiment_user)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1)
Пример #33
0
    def render(self, context):
        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
            gargoyle_key = auth_user
        else:
            request = context.get('request', None)
            user = participant(request)
            gargoyle_key = request

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative,
                            gargoyle_key):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
Пример #34
0
    def test_can_record_goal_multiple_times(self):
        experiment_user = participant(self.request)
        self.confirm_human(experiment_user)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(
            self.experiment.goal_count(TEST_ALTERNATIVE, TEST_GOAL), 1)
Пример #35
0
    def test_visit_increases_goal(self):
        experiment_user = participant(self.request)
        self.confirm_human(experiment_user)
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.visit()

        self.assertEqual(
            self.experiment.goal_distribution(TEST_ALTERNATIVE,
                                              VISIT_COUNT_GOAL), {1: 1})
Пример #36
0
    def process_response(self, request, response):
        # Don't track, failed pages, ajax requests, logged out users or widget impressions.
        # We detect widgets by relying on the fact that they are flagged as being embedable
        if response.status_code != 200 or request.is_ajax() or getattr(response, 'xframe_options_exempt', False):
            return response

        experiment_user = participant(request)
        experiment_user.visit()

        return response
Пример #37
0
    def test_can_record_goal_multiple_times(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not increment goal count correctly")
        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), {3: 1}, "Incorrect goal count distribution")
Пример #38
0
    def test_visit_twice_increases_once(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.visit()
        experiment_user.visit()

        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_NOT_PRESENT_COUNT_GOAL), {1: 1}, "Visit was not correctly counted")
        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_PRESENT_COUNT_GOAL), {}, "Present Visit was not correctly counted")
Пример #39
0
    def test_visit_twice_increases_once(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.visit()
        experiment_user.visit()

        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_NOT_PRESENT_COUNT_GOAL), {1: 1}, "Visit was not correctly counted")
        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_PRESENT_COUNT_GOAL), {}, "Present Visit was not correctly counted")
Пример #40
0
    def test_second_force_enroll_does_not_change_alternative(self):
        alternatives = ['control', 'alternative1', 'alternative2']
        experiment_user = participant(self.request)
        experiment_user.enroll(EXPERIMENT_NAME, alternatives, force_alternative='alternative1')
        alternative = experiment_user.get_alternative(EXPERIMENT_NAME)
        self.assertIsNotNone(alternative)

        other_alternative = random.choice(list(set(alternatives) - set(alternative)))
        experiment_user.enroll(EXPERIMENT_NAME, alternatives, force_alternative=other_alternative)
        self.assertEqual(alternative, experiment_user.get_alternative(EXPERIMENT_NAME))
Пример #41
0
    def test_can_record_goal_multiple_times(self):
        experiment_user = participant(self.request)
        experiment_user.confirm_human()
        experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        experiment_user.goal(TEST_GOAL)
        self.assertEqual(self.experiment_counter.goal_count(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), 1, "Did not increment goal count correctly")
        self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, TEST_GOAL), {3: 1}, "Incorrect goal count distribution")
Пример #42
0
    def test_second_force_enroll_does_not_change_alternative(self):
        alternatives = ['control', 'alternative1', 'alternative2']
        experiment_user = participant(self.request)
        experiment_user.enroll(EXPERIMENT_NAME, alternatives, force_alternative='alternative1')
        alternative = experiment_user.get_alternative(EXPERIMENT_NAME)
        self.assertIsNotNone(alternative)

        other_alternative = random.choice(list(set(alternatives) - set(alternative)))
        experiment_user.enroll(EXPERIMENT_NAME, alternatives, force_alternative=other_alternative)
        self.assertEqual(alternative, experiment_user.get_alternative(EXPERIMENT_NAME))
Пример #43
0
    def process_response(self, request, response):
        # Don't track, failed pages, ajax requests, logged out users or widget impressions.
        # We detect widgets by relying on the fact that they are flagged as being embedable
        if response.status_code != 200 or request.is_ajax() or getattr(
                response, 'xframe_options_exempt', False):
            return response

        experiment_user = participant(request)
        experiment_user.visit()

        return response
Пример #44
0
    def render(self, context):
        experiment = experiment_manager.get_experiment(self.experiment_name)
        if experiment:
            experiment.ensure_alternative_exists(self.alternative, self.weight)

        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
        else:
            request = context.get('request', None)
            user = participant(request)

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
    def render(self, context):
        experiment = experiment_manager.get_experiment(self.experiment_name)
        if experiment:
            experiment.ensure_alternative_exists(self.alternative, self.weight)

        # Get User object
        if self.user_variable:
            auth_user = self.user_variable.resolve(context)
            user = participant(user=auth_user)
        else:
            request = context.get("request", None)
            user = participant(request)

        # Should we render?
        if user.is_enrolled(self.experiment_name, self.alternative):
            response = self.node_list.render(context)
        else:
            response = ""

        return response
Пример #46
0
    def render_experiment(self, experiment_name, alternative, weight,
                          user_variable, context, caller):
        """Callback to render {% experiment ... %} tags"""

        experiment = experiment_manager.get_experiment(experiment_name)
        if experiment:
            # create alternative on the fly (write it to DB) if not existing:
            experiment.ensure_alternative_exists(alternative, weight)

        # Get User object
        if user_variable:
            auth_user = context[user_variable]
            user = participant(user=auth_user)
        else:
            request = context.get('request')
            user = participant(request)

        # Should we render?
        if user.is_enrolled(experiment_name, alternative):
            return caller()
        else:
            return nodes.Markup()  # empty node
Пример #47
0
 def change_view(self, request, object_id, form_url='', extra_context=None):
     participant_value = participant(request)
     participant_value.set_disabled_experiments([])
     experiment = self.get_object(request, unquote(object_id))
     context = self._admin_view_context(extra_context=extra_context)
     context.update(get_result_context(request, experiment))
     if request.method == 'GET':
         # for POST see `_save_related()`
         self._update_alternative_inlines(experiment)
     return super(ExperimentAdmin, self).change_view(request,
                                                     object_id,
                                                     form_url=form_url,
                                                     extra_context=context)
Пример #48
0
 def test_bot_in_control_group(self):
     experiment_user = participant(self.request)
     experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
     self.assertEqual(experiment_user.get_alternative(EXPERIMENT_NAME),
                      'control', "Bot enrolled in a group")
     self.assertEqual(
         experiment_user.is_enrolled(self.experiment.name, TEST_ALTERNATIVE,
                                     self.request), False,
         "Bot in test alternative")
     self.assertEqual(
         experiment_user.is_enrolled(self.experiment.name, CONTROL_GROUP,
                                     self.request), True,
         "Bot not in control group")
Пример #49
0
 def test_bot_in_control_group(self):
     experiment_user = participant(self.request)
     experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)
     self.assertEqual(experiment_user.get_alternative(EXPERIMENT_NAME), "control", "Bot enrolled in a group")
     self.assertEqual(
         experiment_user.is_enrolled(self.experiment.name, TEST_ALTERNATIVE, self.request),
         False,
         "Bot in test alternative",
     )
     self.assertEqual(
         experiment_user.is_enrolled(self.experiment.name, CONTROL_GROUP, self.request),
         True,
         "Bot not in control group",
     )
Пример #50
0
    def test_visit_increases_goal(self):
        thetime = timezone.now()
        with patch('experiments.utils.now', return_value=thetime):
            experiment_user = participant(self.request)
            experiment_user.confirm_human()
            experiment_user.set_alternative(EXPERIMENT_NAME, TEST_ALTERNATIVE)

            experiment_user.visit()
            self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_NOT_PRESENT_COUNT_GOAL), {1: 1}, "Not Present Visit was not correctly counted")
            self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_PRESENT_COUNT_GOAL), {}, "Present Visit was not correctly counted")

        with patch('experiments.utils.now', return_value=thetime + timedelta(hours=7)):
            experiment_user.visit()
            self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_NOT_PRESENT_COUNT_GOAL), {2: 1}, "No Present Visit was not correctly counted")
            self.assertEqual(self.experiment_counter.goal_distribution(self.experiment, TEST_ALTERNATIVE, VISIT_PRESENT_COUNT_GOAL), {1: 1}, "Present Visit was not correctly counted")
Пример #51
0
def enrollments(context):
    """
    Adds an array named 'enrollments' to the experiments javascript
    variable.  This array of 

    [{'experiment': experiment_name, 'alternative': alternative_name}, ...]

    describes each running experiment and the alternative selected for the user.
    Other template tags may select experiments and alternatives so use this
    tag after all of the other experiments template tags in your template.

    Note: The enrollments array can only be accessed after
    $(document).ready.
    """
    request = context.get('request', None)
    user = participant(request)
    enrollments = [{'experiment': enrollment.experiment.name,
                    'alternative': enrollment.alternative}
                    for enrollment in user._get_all_enrollments()]
    return {'experiment_enrollments': mark_safe(to_json(enrollments))}
Пример #52
0
 def test_sends_enroll_signal(self):
     with WatchSignal(user_enrolled) as signal:
         participant(user=self.user).enroll(EXPERIMENT_NAME, ['red', 'blue'])
         self.assertTrue(signal.called)
Пример #53
0
def _experiment_enrolled_alternative(context, experiment_name):
    user = participant(request=context.get('request', None))
    return user.get_alternative(experiment_name)
Пример #54
0
def _experiment_enroll(context, experiment_name, *alternatives, **kwargs):
    if 'user' in kwargs:
        user = participant(user=kwargs['user'])
    else:
        user = participant(request=context.get('request', None))
    return user.enroll(experiment_name, list(alternatives))
def experiment_enroll(context, experiment_name, *alternatives, **kwargs):
    if "user" in kwargs:
        user = participant(user=kwargs["user"])
    else:
        user = participant(request=context.get("request", None))
    return user.enroll(experiment_name, list(alternatives))
Пример #56
0
def visit(context):
    request = context.get('request', None)
    participant(request).visit()
    return ""
 def test_view_auto_create_on(self):
     user = User.objects.create(username="******")
     participant(user=user).enroll("test_experiment_x", alternatives=["other"])
     self.assertTrue(Experiment.objects.filter(name="test_experiment_x").exists())
Пример #58
0
def get_result_context(request, experiment):
    experiment_counter = ExperimentCounter()

    try:
        chi2_goals = experiment.relevant_chi2_goals.replace(" ", "").split(",")
    except AttributeError:
        chi2_goals = [u'']
    try:
        mwu_goals = experiment.relevant_mwu_goals.replace(" ", "").split(",")
    except AttributeError:
        mwu_goals = [u'']
    relevant_goals = set(chi2_goals + mwu_goals)

    alternatives = {}
    for alternative_name in experiment.alternatives.keys():
        alternatives[alternative_name] = experiment_counter.participant_count(experiment, alternative_name)
    alternatives = sorted(alternatives.items())

    control_participants = experiment_counter.participant_count(experiment, conf.CONTROL_GROUP)

    results = {}

    for goal in conf.ALL_GOALS:
        show_mwu = goal in mwu_goals

        alternatives_conversions = {}
        control_conversions = experiment_counter.goal_count(experiment, conf.CONTROL_GROUP, goal)
        control_conversion_rate = rate(control_conversions, control_participants)

        if show_mwu:
            mwu_histogram = {}
            control_conversion_distribution = fixup_distribution(experiment_counter.goal_distribution(experiment, conf.CONTROL_GROUP, goal), control_participants)
            control_average_goal_actions = average_actions(control_conversion_distribution)
            mwu_histogram['control'] = control_conversion_distribution
        else:
            control_average_goal_actions = None
        for alternative_name in experiment.alternatives.keys():
            if not alternative_name == conf.CONTROL_GROUP:
                alternative_conversions = experiment_counter.goal_count(experiment, alternative_name, goal)
                alternative_participants = experiment_counter.participant_count(experiment, alternative_name)
                alternative_conversion_rate = rate(alternative_conversions, alternative_participants)
                alternative_confidence = chi_squared_confidence(alternative_participants, alternative_conversions, control_participants, control_conversions)
                if show_mwu:
                    alternative_conversion_distribution = fixup_distribution(experiment_counter.goal_distribution(experiment, alternative_name, goal), alternative_participants)
                    alternative_average_goal_actions = average_actions(alternative_conversion_distribution)
                    alternative_distribution_confidence = mann_whitney_confidence(alternative_conversion_distribution, control_conversion_distribution)
                    mwu_histogram[alternative_name] = alternative_conversion_distribution
                else:
                    alternative_average_goal_actions = None
                    alternative_distribution_confidence = None
                alternative = {
                    'conversions': alternative_conversions,
                    'conversion_rate': alternative_conversion_rate,
                    'improvement': improvement(alternative_conversion_rate, control_conversion_rate),
                    'confidence': alternative_confidence,
                    'average_goal_actions': alternative_average_goal_actions,
                    'mann_whitney_confidence': alternative_distribution_confidence,
                }
                alternatives_conversions[alternative_name] = alternative

        control = {
            'conversions': control_conversions,
            'conversion_rate': control_conversion_rate,
            'average_goal_actions': control_average_goal_actions,
        }

        results[goal] = {
            "control": control,
            "alternatives": sorted(alternatives_conversions.items()),
            "relevant": goal in relevant_goals or relevant_goals == {u''},
            "mwu": goal in mwu_goals,
            "mwu_histogram": conversion_distributions_to_graph_table(mwu_histogram) if show_mwu else None
        }

    return {
        'experiment': experiment.to_dict(),
        'alternatives': alternatives,
        'control_participants': control_participants,
        'results': results,
        'column_count': len(alternatives_conversions) * 3 + 2,  # Horrible coupling with template design
        'user_alternative': participant(request).get_alternative(experiment.name),
    }
Пример #59
0
 def test_does_not_send_enroll_signal_again(self):
     participant(user=self.user).enroll(EXPERIMENT_NAME, ['red', 'blue'])
     with WatchSignal(user_enrolled) as signal:
         participant(user=self.user).enroll(EXPERIMENT_NAME, ['red', 'blue'])
         self.assertFalse(signal.called)