Esempio n. 1
0
    def test_evidence_event_sent(self):
        test_url = get_certificate_url(user_id=self.user.id, course_id=self.course_id) + '?evidence_visit=1'
        self.recreate_tracker()
        assertion = BadgeAssertion(
            user=self.user, course_id=self.course_id, mode='honor',
            data={
                'image': 'http://www.example.com/image.png',
                'json': {'id': 'http://www.example.com/assertion.json'},
                'issuer': 'http://www.example.com/issuer.json',

            }
        )
        assertion.save()
        response = self.client.get(test_url)
        self.assertEqual(response.status_code, 200)
        assert_event_matches(
            {
                'name': 'edx.badge.assertion.evidence_visited',
                'data': {
                    'course_id': 'testorg/run1/refundable_course',
                    # pylint: disable=no-member
                    'assertion_id': assertion.id,
                    'assertion_json_url': 'http://www.example.com/assertion.json',
                    'assertion_image_url': 'http://www.example.com/image.png',
                    'user_id': self.user.id,
                    'issuer': 'http://www.example.com/issuer.json',
                    'enrollment_mode': 'honor',
                },
            },
            self.get_event()
        )
Esempio n. 2
0
 def test_social_event_sent(self):
     test_url = '/certificates/badge_share_tracker/{}/social_network/{}/'.format(
         unicode(self.course.id),
         self.user.username,
     )
     self.recreate_tracker()
     response = self.client.get(test_url)
     self.assertEqual(response.status_code, 302)
     self.assertEqual(response['Location'], 'http://www.example.com/image.png')
     assert_event_matches(
         {
             'name': 'edx.badge.assertion.shared',
             'data': {
                 'course_id': 'testorg/run1/trackable_course',
                 'social_network': 'social_network',
                 # pylint: disable=no-member
                 'assertion_id': self.assertion.id,
                 'assertion_json_url': 'http://www.example.com/assertion.json',
                 'assertion_image_url': 'http://www.example.com/image.png',
                 'user_id': self.user.id,
                 'issuer': 'http://www.example.com/issuer.json',
                 'enrollment_mode': 'honor'
             },
         },
         self.get_event()
     )
    def test_evidence_event_sent(self):
        self._add_course_certificates(count=1, signatory_count=2)

        cert_url = get_certificate_url(
            user_id=self.user.id,
            course_id=self.course_id
        )
        test_url = '{}?evidence_visit=1'.format(cert_url)
        self.recreate_tracker()
        assertion = BadgeAssertionFactory.create(
            user=self.user, course_id=self.course_id,
        )
        response = self.client.get(test_url)
        self.assertEqual(response.status_code, 200)
        assert_event_matches(
            {
                'name': 'edx.badge.assertion.evidence_visited',
                'data': {
                    'course_id': 'testorg/run1/refundable_course',
                    'assertion_id': assertion.id,
                    'assertion_json_url': 'http://www.example.com/assertion.json',
                    'assertion_image_url': 'http://www.example.com/image.png',
                    'user_id': self.user.id,
                    'issuer': 'http://www.example.com/issuer.json',
                    'enrollment_mode': 'honor',
                },
            },
            self.get_event()
        )
Esempio n. 4
0
    def test_success(self, course_id):
        middleware = TrackMiddleware()

        request = self.create_request(
            data=self.create_segmentio_event_json(data={'foo': 'bar'}, course_id=course_id),
            content_type='application/json'
        )
        User.objects.create(pk=USER_ID, username=str(sentinel.username))

        middleware.process_request(request)
        # The middleware normally emits an event, make sure it doesn't in this case.
        self.assert_no_events_emitted()
        try:
            response = segmentio.segmentio_event(request)
            self.assertEquals(response.status_code, 200)

            expected_event = {
                'accept_language': '',
                'referer': '',
                'username': str(sentinel.username),
                'ip': '',
                'session': '',
                'event_source': 'mobile',
                'event_type': str(sentinel.name),
                'name': str(sentinel.name),
                'event': {'foo': 'bar'},
                'agent': str(sentinel.user_agent),
                'page': None,
                'time': datetime.strptime("2014-08-27T16:33:39.215Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                'host': 'testserver',
                'context': {
                    'application': {
                        'name': 'edx.mobile.android',
                        'version': '1.0.1',
                    },
                    'user_id': USER_ID,
                    'course_id': course_id,
                    'org_id': u'foo',
                    'path': ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'received_at': datetime.strptime("2014-08-27T16:33:39.100Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                },
            }
        finally:
            middleware.process_response(request, None)

        assert_event_matches(expected_event, self.get_event())
Esempio n. 5
0
 def assert_events_match(self, expected_events, actual_events):
     """
     Assert that each item in the expected events sequence matches its counterpart at the same index in the actual
     events sequence.
     """
     for expected_event, actual_event in zip(expected_events, actual_events):
         assert_event_matches(
             expected_event,
             actual_event,
             tolerate=EventMatchTolerates.lenient()
         )
Esempio n. 6
0
    def assert_events_match(self, expected_events, actual_events, in_order=True):
        """Assert that each actual event matches one of the expected events.

        Args:
            expected_events (List): a list of dicts representing the expected events.
            actual_events (List): a list of dicts that were actually recorded.
            in_order (bool): if True then the events must be in the same order (defaults to True).
        """
        if in_order:
            for expected_event, actual_event in zip(expected_events, actual_events):
                assert_event_matches(expected_event, actual_event, tolerate=EventMatchTolerates.lenient())
        else:
            for expected_event in expected_events:
                actual_event = next(event for event in actual_events if is_matching_event(expected_event, event))
                assert_event_matches(expected_event, actual_event or {}, tolerate=EventMatchTolerates.lenient())
Esempio n. 7
0
    def test_user_track_with_middleware_and_processors(self):
        self.recreate_tracker()

        middleware = TrackMiddleware()
        payload = '{"foo": "bar"}'
        user_id = 1
        request = self.request_factory.get('/event', {
            'page': self.url_with_course,
            'event_type': sentinel.event_type,
            'event': payload
        })
        request.user = User.objects.create(pk=user_id, username=str(sentinel.username))
        request.META['REMOTE_ADDR'] = '10.0.0.1'
        request.META['HTTP_REFERER'] = str(sentinel.referer)
        request.META['HTTP_ACCEPT_LANGUAGE'] = str(sentinel.accept_language)
        request.META['HTTP_USER_AGENT'] = str(sentinel.user_agent)
        request.META['SERVER_NAME'] = 'testserver2'
        middleware.process_request(request)
        try:
            views.user_track(request)

            expected_event = {
                'accept_language': str(sentinel.accept_language),
                'referer': str(sentinel.referer),
                'username': str(sentinel.username),
                'session': '',
                'ip': '10.0.0.1',
                'event_source': 'browser',
                'event_type': str(sentinel.event_type),
                'name': str(sentinel.event_type),
                'event': payload,
                'agent': str(sentinel.user_agent),
                'page': self.url_with_course,
                'time': FROZEN_TIME,
                'host': 'testserver2',
                'context': {
                    'course_id': 'foo/bar/baz',
                    'org_id': 'foo',
                    'user_id': user_id,
                    'path': u'/event'
                },
            }
        finally:
            middleware.process_response(request, None)

        actual_event = self.get_event()
        assert_event_matches(expected_event, actual_event)
Esempio n. 8
0
    def test_user_track_with_missing_values(self):
        request = self.request_factory.get('/event')

        views.user_track(request)

        actual_event = self.get_event()
        expected_event = {
            'context': {
                'course_id': '',
                'org_id': '',
                'event_source': 'browser',
                'page': '',
                'username': '******'
            },
            'data': {},
            'timestamp': FROZEN_TIME,
            'name': 'unknown'
        }
        assert_event_matches(expected_event, actual_event)
Esempio n. 9
0
 def test_badge_creation_event(self, post):
     result = {
         'json': {'id': 'http://www.example.com/example'},
         'image': 'http://www.example.com/example.png',
         'badge': 'test_assertion_slug',
         'issuer': 'https://example.com/v1/issuer/issuers/test-issuer',
     }
     response = Mock()
     response.json.return_value = result
     post.return_value = response
     self.recreate_tracker()
     self.handler._create_assertion(self.badge_class, self.user, 'https://example.com/irrefutable_proof')
     args, kwargs = post.call_args
     self.assertEqual(
         args[0],
         'https://example.com/v1/issuer/issuers/test-issuer/badges/' +
         EXAMPLE_SLUG +
         '/assertions'
     )
     self.check_headers(kwargs['headers'])
     assertion = BadgeAssertion.objects.get(user=self.user, badge_class__course_id=self.course.location.course_key)
     self.assertEqual(assertion.data, result)
     self.assertEqual(assertion.image_url, 'http://www.example.com/example.png')
     self.assertEqual(assertion.assertion_url, 'http://www.example.com/example')
     self.assertEqual(kwargs['data'], {
         'email': '*****@*****.**',
         'evidence': 'https://example.com/irrefutable_proof'
     })
     assert_event_matches({
         'name': 'edx.badge.assertion.created',
         'data': {
             'user_id': self.user.id,
             'course_id': six.text_type(self.course.location.course_key),
             'enrollment_mode': 'honor',
             'assertion_id': assertion.id,
             'badge_name': 'Test Badge',
             'badge_slug': 'test_slug',
             'issuing_component': 'test_component',
             'assertion_image_url': 'http://www.example.com/example.png',
             'assertion_json_url': 'http://www.example.com/example',
             'issuer': 'https://example.com/v1/issuer/issuers/test-issuer',
         }
     }, self.get_event())
Esempio n. 10
0
    def test_video_control_events(self):
        """
        Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources
        Given the course has a Video component in "Youtube" mode
        And I play the video
        And I watch 5 seconds of it
        And I pause the video
        Then a "load_video" event is emitted
        And a "play_video" event is emitted
        And a "pause_video" event is emitted
        """

        def is_video_event(event):
            """Filter out anything other than the video events of interest"""
            return event['event_type'] in ('load_video', 'play_video', 'pause_video')

        captured_events = []
        with self.capture_events(is_video_event, number_of_matches=3, captured_events=captured_events):
            self.navigate_to_video()
            self.video.click_player_button('play')
            self.video.wait_for_position('0:05')
            self.video.click_player_button('pause')

        for idx, video_event in enumerate(captured_events):
            self.assert_payload_contains_ids(video_event)
            if idx == 0:
                assert_event_matches({'event_type': 'load_video'}, video_event)
            elif idx == 1:
                assert_event_matches({'event_type': 'play_video'}, video_event)
                self.assert_valid_control_event_at_time(video_event, 0)
            elif idx == 2:
                assert_event_matches({'event_type': 'pause_video'}, video_event)
                self.assert_valid_control_event_at_time(video_event, self.video.seconds)
Esempio n. 11
0
 def test_badge_creation_event(self, post):
     result = {
         'json': {'id': 'http://www.example.com/example'},
         'image': 'http://www.example.com/example.png',
         'slug': 'test_assertion_slug',
         'issuer': 'https://example.com/v1/issuer/issuers/test-issuer',
     }
     response = Mock()
     response.json.return_value = result
     post.return_value = response
     self.recreate_tracker()
     self.handler.create_assertion(self.user, 'honor')
     args, kwargs = post.call_args
     self.assertEqual(
         args[0],
         'https://example.com/v1/issuer/issuers/test-issuer/badges/'
         'edxcourse_testtest_run_honor_fc5519b/assertions'
     )
     self.check_headers(kwargs['headers'])
     assertion = BadgeAssertion.objects.get(user=self.user, course_id=self.course.location.course_key)
     self.assertEqual(assertion.data, result)
     self.assertEqual(assertion.image_url, 'http://www.example.com/example.png')
     self.assertEqual(kwargs['data'], {
         'email': '*****@*****.**',
         'evidence': 'https://edx.org/certificates/user/2/course/edX/course_test/test_run?evidence_visit=1'
     })
     assert_event_matches({
         'name': 'edx.badge.assertion.created',
         'data': {
             'user_id': self.user.id,
             'course_id': unicode(self.course.location.course_key),
             'enrollment_mode': 'honor',
             'assertion_id': assertion.id,
             'assertion_image_url': 'http://www.example.com/example.png',
             'assertion_json_url': 'http://www.example.com/example',
             'issuer': 'https://example.com/v1/issuer/issuers/test-issuer',
         }
     }, self.get_event())
 def test_certificate_evidence_event_emitted(self):
     self.client.logout()
     self._add_course_certificates(count=1, signatory_count=2)
     self.recreate_tracker()
     test_url = get_certificate_url(
         user_id=self.user.id,
         course_id=unicode(self.course.id)
     )
     response = self.client.get(test_url)
     self.assertEqual(response.status_code, 200)
     actual_event = self.get_event()
     self.assertEqual(actual_event['name'], 'edx.certificate.evidence_visited')
     assert_event_matches(
         {
             'user_id': self.user.id,
             'certificate_id': unicode(self.cert.verify_uuid),
             'enrollment_mode': self.cert.mode,
             'certificate_url': test_url,
             'course_id': unicode(self.course.id),
             'social_network': CertificateSocialNetworks.linkedin
         },
         actual_event['data']
     )
Esempio n. 13
0
    def test_user_track_with_empty_event(self):
        request = self.request_factory.get('/event', {
            'page': self.url_with_course,
            'event_type': sentinel.event_type,
            'event': ''
        })

        views.user_track(request)

        actual_event = self.get_event()
        expected_event = {
            'context': {
                'course_id': 'foo/bar/baz',
                'org_id': 'foo',
                'event_source': 'browser',
                'page': self.url_with_course,
                'username': '******'
            },
            'data': {},
            'timestamp': FROZEN_TIME,
            'name': str(sentinel.event_type)
        }
        assert_event_matches(expected_event, actual_event)
 def assert_mock_tracker_call_matches(self, expected_event):
     self.assertEqual(len(self.mock_tracker.send.mock_calls), 1)
     actual_event = self.mock_tracker.send.mock_calls[0][1][0]
     assert_event_matches(expected_event, actual_event)
Esempio n. 15
0
    def test_video_control_events(self, event_type, action):
        """
        Scenario: Video component with pre-roll emits events correctly
        Given the course has a Video component in "Youtube" mode with pre-roll enabled
        And I click on the video poster
        And the pre-roll video start playing
        And I watch (5 seconds/5 seconds/to the end of) it
        And I click (skip/do not show again) video button

        Then a "edx.video.bumper.loaded" event is emitted
        And a "edx.video.bumper.played" event is emitted
        And a "edx.video.bumper.skipped/dismissed/stopped" event is emitted
        And a "load_video" event is emitted
        And a "play_video" event is emitted
        """

        def is_video_event(event):
            """Filter out anything other than the video events of interest"""
            return event['event_type'] in (
                'edx.video.bumper.loaded',
                'edx.video.bumper.played',
                'edx.video.bumper.skipped',
                'edx.video.bumper.dismissed',
                'edx.video.bumper.stopped',
                'load_video',
                'play_video',
                'pause_video'
            ) and self.video.state != 'buffering'

        captured_events = []
        self.add_bumper()
        with self.capture_events(is_video_event, number_of_matches=5, captured_events=captured_events):
            self.navigate_to_video_no_render()
            self.video.click_on_poster()
            self.video.wait_for_video_bumper_render()
            sources, duration = self.video.sources[0], self.video.duration
            action(self)

        # Filter subsequent events that appear due to bufferisation: edx.video.bumper.played
        # As bumper does not emit pause event, we filter subsequent edx.video.bumper.played events from
        # the list, except first.
        filtered_events = []
        for video_event in captured_events:
            is_played_event = video_event['event_type'] == 'edx.video.bumper.played'
            appears_again = filtered_events and video_event['event_type'] == filtered_events[-1]['event_type']
            if is_played_event and appears_again:
                continue
            filtered_events.append(video_event)

        for idx, video_event in enumerate(filtered_events):
            if idx < 3:
                self.assert_bumper_payload_contains_ids(video_event, sources, duration)
            else:
                self.assert_payload_contains_ids(video_event)

            if idx == 0:
                assert_event_matches({'event_type': 'edx.video.bumper.loaded'}, video_event)
            elif idx == 1:
                assert_event_matches({'event_type': 'edx.video.bumper.played'}, video_event)
                self.assert_valid_control_event_at_time(video_event, 0)
            elif idx == 2:
                assert_event_matches({'event_type': event_type}, video_event)
            elif idx == 3:
                assert_event_matches({'event_type': 'load_video'}, video_event)
            elif idx == 4:
                assert_event_matches({'event_type': 'play_video'}, video_event)
                self.assert_valid_control_event_at_time(video_event, 0)
Esempio n. 16
0
    def test_success(self, course_id):
        middleware = TrackMiddleware()

        request = self.create_request(data=self.create_segmentio_event_json(
            data={'foo': 'bar'}, course_id=course_id),
                                      content_type='application/json')
        User.objects.create(pk=USER_ID, username=str(sentinel.username))

        middleware.process_request(request)
        # The middleware normally emits an event, make sure it doesn't in this case.
        self.assert_no_events_emitted()
        try:
            response = segmentio.segmentio_event(request)
            self.assertEquals(response.status_code, 200)

            expected_event = {
                'accept_language':
                '',
                'referer':
                '',
                'username':
                str(sentinel.username),
                'ip':
                '',
                'session':
                '',
                'event_source':
                'mobile',
                'event_type':
                str(sentinel.name),
                'name':
                str(sentinel.name),
                'event': {
                    'foo': 'bar'
                },
                'agent':
                str(sentinel.user_agent),
                'page':
                None,
                'time':
                datetime.strptime("2014-08-27T16:33:39.215Z",
                                  "%Y-%m-%dT%H:%M:%S.%fZ"),
                'host':
                'testserver',
                'context': {
                    'application': {
                        'name': 'edx.mobile.android',
                        'version': '1.0.1',
                    },
                    'user_id':
                    USER_ID,
                    'course_id':
                    course_id,
                    'org_id':
                    u'foo',
                    'path':
                    ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'received_at':
                    datetime.strptime("2014-08-27T16:33:39.100Z",
                                      "%Y-%m-%dT%H:%M:%S.%fZ"),
                },
            }
        finally:
            middleware.process_response(request, None)

        assert_event_matches(expected_event, self.get_event())
    def test_video_control_events(self, event_type, action):
        """
        Scenario: Video component with pre-roll emits events correctly
        Given the course has a Video component in "Youtube" mode with pre-roll enabled
        And I click on the video poster
        And the pre-roll video start playing
        And I watch (5 seconds/5 seconds/to the end of) it
        And I click (skip/do not show again) video button

        Then a "edx.video.bumper.loaded" event is emitted
        And a "edx.video.bumper.played" event is emitted
        And a "edx.video.bumper.skipped/dismissed/stopped" event is emitted
        And a "load_video" event is emitted
        And a "play_video" event is emitted
        """
        def is_video_event(event):
            """Filter out anything other than the video events of interest"""
            return event['event_type'] in (
                'edx.video.bumper.loaded', 'edx.video.bumper.played',
                'edx.video.bumper.skipped', 'edx.video.bumper.dismissed',
                'edx.video.bumper.stopped', 'load_video', 'play_video',
                'pause_video') and self.video.state != 'buffering'

        captured_events = []
        self.add_bumper()
        with self.capture_events(is_video_event,
                                 number_of_matches=5,
                                 captured_events=captured_events):
            self.navigate_to_video_no_render()
            self.video.click_on_poster()
            self.video.wait_for_video_bumper_render()
            sources, duration = self.video.sources[0], self.video.duration
            action(self)

        # Filter subsequent events that appear due to bufferisation: edx.video.bumper.played
        # As bumper does not emit pause event, we filter subsequent edx.video.bumper.played events from
        # the list, except first.
        filtered_events = []
        for video_event in captured_events:
            is_played_event = video_event[
                'event_type'] == 'edx.video.bumper.played'
            appears_again = filtered_events and video_event[
                'event_type'] == filtered_events[-1]['event_type']
            if is_played_event and appears_again:
                continue
            filtered_events.append(video_event)

        for idx, video_event in enumerate(filtered_events):
            if idx < 3:
                self.assert_bumper_payload_contains_ids(
                    video_event, sources, duration)
            else:
                self.assert_payload_contains_ids(video_event)

            if idx == 0:
                assert_event_matches({'event_type': 'edx.video.bumper.loaded'},
                                     video_event)
            elif idx == 1:
                assert_event_matches({'event_type': 'edx.video.bumper.played'},
                                     video_event)
                self.assert_valid_control_event_at_time(video_event, 0)
            elif idx == 2:
                assert_event_matches({'event_type': event_type}, video_event)
            elif idx == 3:
                assert_event_matches({'event_type': 'load_video'}, video_event)
            elif idx == 4:
                assert_event_matches({'event_type': 'play_video'}, video_event)
                self.assert_valid_control_event_at_time(video_event, 0)
Esempio n. 18
0
    def test_previous_builds(self,
                             requested_skip_interval,
                             expected_skip_interval,
                             seek_type_key,
                             seek_type,
                             expected_seek_type,
                             name,
                             expected_name,
                             platform,
                             version,
                             ):
        """
        Test backwards compatibility of previous app builds

        iOS version 1.0.02: Incorrectly emits the skip back 30 seconds as +30
        instead of -30.
        Android version 1.0.02: Skip and slide were both being returned as a
        skip. Skip or slide is determined by checking if the skip time is == -30
        Additionally, for both of the above mentioned versions, edx.video.seeked
        was sent instead of edx.video.position.changed
        """
        course_id = 'foo/bar/baz'
        middleware = TrackMiddleware()
        input_payload = {
            "code": "mobile",
            "new_time": 89.699177437,
            "old_time": 119.699177437,
            seek_type_key: seek_type,
            "requested_skip_interval": requested_skip_interval,
            'module_id': 'i4x://foo/bar/baz/some_module',
        }
        request = self.create_request(
            data=self.create_segmentio_event_json(
                name=name,
                data=input_payload,
                context={
                    'open_in_browser_url': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity/2',
                    'course_id': course_id,
                    'application': {
                        'name': platform,
                        'version': version,
                        'component': 'videoplayer'
                    }
                },
            ),
            content_type='application/json'
        )
        User.objects.create(pk=USER_ID, username=str(sentinel.username))

        middleware.process_request(request)
        try:
            response = segmentio.segmentio_event(request)
            self.assertEquals(response.status_code, 200)

            expected_event = {
                'accept_language': '',
                'referer': '',
                'username': str(sentinel.username),
                'ip': '',
                'session': '',
                'event_source': 'mobile',
                'event_type': "seek_video",
                'name': expected_name,
                'agent': str(sentinel.user_agent),
                'page': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity',
                'time': datetime.strptime("2014-08-27T16:33:39.215Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                'host': 'testserver',
                'context': {
                    'user_id': USER_ID,
                    'course_id': course_id,
                    'org_id': 'foo',
                    'path': ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'application': {
                        'name': platform,
                        'version': version,
                        'component': 'videoplayer'
                    },
                    'received_at': datetime.strptime("2014-08-27T16:33:39.100Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                },
                'event': {
                    "code": "mobile",
                    "new_time": 89.699177437,
                    "old_time": 119.699177437,
                    "type": expected_seek_type,
                    "requested_skip_interval": expected_skip_interval,
                    'id': 'i4x-foo-bar-baz-some_module',
                }
            }
        finally:
            middleware.process_response(request, None)

        actual_event = self.get_event()
        assert_event_matches(expected_event, actual_event)
Esempio n. 19
0
    def test_video_event(self, name, event_type):
        course_id = 'foo/bar/baz'
        middleware = TrackMiddleware()

        input_payload = {
            'current_time': 132.134456,
            'module_id': 'i4x://foo/bar/baz/some_module',
            'code': 'mobile'
        }
        if name == 'edx.video.loaded':
            # We use the same expected payload for all of these types of events, but the load video event is the only
            # one that is not actually expected to contain a "current time" field. So we remove it from the expected
            # event here.
            del input_payload['current_time']

        request = self.create_request(
            data=self.create_segmentio_event_json(
                name=name,
                data=input_payload,
                context={
                    'open_in_browser_url': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity/2',
                    'course_id': course_id,
                    'application': {
                        'name': 'edx.mobileapp.android',
                        'version': '29',
                        'component': 'videoplayer'
                    }
                }),
            content_type='application/json'
        )
        User.objects.create(pk=USER_ID, username=str(sentinel.username))

        middleware.process_request(request)
        try:
            response = segmentio.segmentio_event(request)
            self.assertEquals(response.status_code, 200)

            expected_event = {
                'accept_language': '',
                'referer': '',
                'username': str(sentinel.username),
                'ip': '',
                'session': '',
                'event_source': 'mobile',
                'event_type': event_type,
                'name': name,
                'agent': str(sentinel.user_agent),
                'page': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity',
                'time': datetime.strptime("2014-08-27T16:33:39.215Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                'host': 'testserver',
                'context': {
                    'user_id': USER_ID,
                    'course_id': course_id,
                    'org_id': 'foo',
                    'path': ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'application': {
                        'name': 'edx.mobileapp.android',
                        'version': '29',
                        'component': 'videoplayer'
                    },
                    'received_at': datetime.strptime("2014-08-27T16:33:39.100Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                },
                'event': {
                    'currentTime': 132.134456,
                    'id': 'i4x-foo-bar-baz-some_module',
                    'code': 'mobile'
                }
            }
            if name == 'edx.video.loaded':
                # We use the same expected payload for all of these types of events, but the load video event is the
                # only one that is not actually expected to contain a "current time" field. So we remove it from the
                # expected event here.
                del expected_event['event']['currentTime']
        finally:
            middleware.process_response(request, None)

        actual_event = self.get_event()
        assert_event_matches(expected_event, actual_event)
    def test_previous_builds(
        self,
        requested_skip_interval,
        expected_skip_interval,
        seek_type_key,
        seek_type,
        expected_seek_type,
        name,
        expected_name,
        platform,
        version,
    ):
        """
        Test backwards compatibility of previous app builds

        iOS version 1.0.02: Incorrectly emits the skip back 30 seconds as +30
        instead of -30.
        Android version 1.0.02: Skip and slide were both being returned as a
        skip. Skip or slide is determined by checking if the skip time is == -30
        Additionally, for both of the above mentioned versions, edx.video.seeked
        was sent instead of edx.video.position.changed
        """
        course_id = 'foo/bar/baz'
        middleware = TrackMiddleware()
        input_payload = {
            "code": "mobile",
            "new_time": 89.699177437,
            "old_time": 119.699177437,
            seek_type_key: seek_type,
            "requested_skip_interval": requested_skip_interval,
            'module_id': 'i4x://foo/bar/baz/some_module',
        }
        request = self.create_request(data=self.create_segmentio_event_json(
            name=name,
            data=input_payload,
            context={
                'open_in_browser_url':
                'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity/2',
                'course_id': course_id,
                'application': {
                    'name': platform,
                    'version': version,
                    'component': 'videoplayer'
                }
            },
        ),
                                      content_type='application/json')

        middleware.process_request(request)
        try:
            response = segmentio.segmentio_event(request)
            self.assertEqual(response.status_code, 200)

            expected_event = {
                'accept_language': '',
                'referer': '',
                'username': str(sentinel.username),
                'ip': '',
                'session': '',
                'event_source': 'mobile',
                'event_type': "seek_video",
                'name': expected_name,
                'agent': str(sentinel.user_agent),
                'page':
                'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity',
                'time': parser.parse("2014-08-27T16:33:39.215Z"),
                'host': 'testserver',
                'context': {
                    'user_id': SEGMENTIO_TEST_USER_ID,
                    'course_id': course_id,
                    'org_id': 'foo',
                    'path': SEGMENTIO_TEST_ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'application': {
                        'name': platform,
                        'version': version,
                        'component': 'videoplayer'
                    },
                    'received_at': parser.parse("2014-08-27T16:33:39.100Z"),
                },
                'event': {
                    "code": "mobile",
                    "new_time": 89.699177437,
                    "old_time": 119.699177437,
                    "type": expected_seek_type,
                    "requested_skip_interval": expected_skip_interval,
                    'id': 'i4x-foo-bar-baz-some_module',
                }
            }
        finally:
            middleware.process_response(request, None)

        actual_event = self.get_event()
        assert_event_matches(expected_event, actual_event)
Esempio n. 21
0
    def test_video_event(self, name, event_type):
        course_id = 'foo/bar/baz'
        middleware = TrackMiddleware()

        input_payload = {
            'current_time': 132.134456,
            'module_id': 'i4x://foo/bar/baz/some_module',
            'code': 'mobile'
        }
        if name == 'edx.video.loaded':
            # We use the same expected payload for all of these types of events, but the load video event is the only
            # one that is not actually expected to contain a "current time" field. So we remove it from the expected
            # event here.
            del input_payload['current_time']

        request = self.create_request(
            data=self.create_segmentio_event_json(
                name=name,
                data=input_payload,
                context={
                    'open_in_browser_url': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity/2',
                    'course_id': course_id,
                    'application': {
                        'name': 'edx.mobileapp.android',
                        'version': '29',
                        'component': 'videoplayer'
                    }
                }),
            content_type='application/json'
        )
        User.objects.create(pk=USER_ID, username=str(sentinel.username))

        middleware.process_request(request)
        try:
            response = segmentio.segmentio_event(request)
            self.assertEquals(response.status_code, 200)

            expected_event = {
                'accept_language': '',
                'referer': '',
                'username': str(sentinel.username),
                'ip': '',
                'session': '',
                'event_source': 'mobile',
                'event_type': event_type,
                'name': name,
                'agent': str(sentinel.user_agent),
                'page': 'https://testserver/courses/foo/bar/baz/courseware/Week_1/Activity',
                'time': datetime.strptime("2014-08-27T16:33:39.215Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                'host': 'testserver',
                'context': {
                    'user_id': USER_ID,
                    'course_id': course_id,
                    'org_id': 'foo',
                    'path': ENDPOINT,
                    'client': {
                        'library': {
                            'name': 'test-app',
                            'version': 'unknown'
                        },
                        'app': {
                            'version': '1.0.1',
                        },
                    },
                    'application': {
                        'name': 'edx.mobileapp.android',
                        'version': '29',
                        'component': 'videoplayer'
                    },
                    'received_at': datetime.strptime("2014-08-27T16:33:39.100Z", "%Y-%m-%dT%H:%M:%S.%fZ"),
                },
                'event': {
                    'currentTime': 132.134456,
                    'id': 'i4x-foo-bar-baz-some_module',
                    'code': 'mobile'
                }
            }
            if name == 'edx.video.loaded':
                # We use the same expected payload for all of these types of events, but the load video event is the
                # only one that is not actually expected to contain a "current time" field. So we remove it from the
                # expected event here.
                del expected_event['event']['currentTime']
        finally:
            middleware.process_response(request, None)

        actual_event = self.get_event()
        assert_event_matches(expected_event, actual_event)
Esempio n. 22
0
 def assert_mock_tracker_call_matches(self, expected_event):
     self.assertEqual(len(self.mock_tracker.send.mock_calls), 1)
     actual_event = self.mock_tracker.send.mock_calls[0][1][0]
     assert_event_matches(expected_event, actual_event)