コード例 #1
0
    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)
コード例 #2
0
    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
ファイル: views.py プロジェクト: TomasM/django-experiments
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')
コード例 #7
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)
     }
コード例 #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)
     }
コード例 #9
0
    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()
コード例 #10
0
    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
ファイル: webuser.py プロジェクト: ajvb/django-experiments
    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")
コード例 #31
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
コード例 #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
コード例 #45
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
コード例 #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))
コード例 #55
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))
コード例 #56
0
def visit(context):
    request = context.get('request', None)
    participant(request).visit()
    return ""
コード例 #57
0
 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)