def get_suggestions(self, feedback, request=None): # Note: This implementation assumes there aren't a fajillion # active rules. If that becomes a problem, we should # re-architect the db so that this is easier to implement. # # Further, each matching rule will kick off a GA event # request. We have to do those synchronously so that we're # guaranteed to have the "suggest" event before the "click" # event. Otherwise the data is not as meaningful. rules = TriggerRule.objects.all_enabled() links = [] # Go through the rules and accrue links until we're done. # FIXME: Can we do one ga_track_event call for all the rules? for rule in rules: if rule.get_matcher().match(feedback): links.append( Link(provider=PROVIDER, provider_version=PROVIDER_VERSION, cssclass=u'document', summary=rule.title, description=rule.description, url=build_redirect_url(format_redirect(rule.slug)))) # Track category: trigger-slug, action: suggest ga_track_event({ 'cid': str(feedback.id), 'ec': build_ga_category(rule), 'ea': 'suggest', 'el': rule.url }) return links
def handle_redirect(self, request, redirect): # If it's not a trigger redirect, return. if not redirect.startswith(TRIGGER): return # Get the response id for the last feedback left. response_id = request.session.get('response_id', None) if response_id is None: return # Extract the slug. try: trigger, slug = parse_redirect(redirect) except RedirectParseError: return # Get the rule that has that slug. try: rule = TriggerRule.objects.get(slug=slug) except TriggerRule.DoesNotExist: return # Track the event and then return the new url. ga_track_event({ 'cid': str(response_id), 'ec': build_ga_category(rule), 'ea': 'view', 'el': rule.url }, async=True) return rule.url
def test_ga_track_event_async_false(self): """async=False, then delay() never gets called""" with requests_mock.Mocker() as m: m.post(GOOGLE_API_URL, text="") d = "fjord.base.google_utils.post_event.delay" with patch(d) as delay_patch: params = {"cid": "xxx", "ec": "ou812"} ga_track_event(params, async=False) eq_(delay_patch.call_count, 0)
def test_ga_track_event_async_false(self): """async=False, then delay() never gets called""" with requests_mock.Mocker() as m: m.post(GOOGLE_API_URL, text='') d = 'fjord.base.google_utils.post_event.delay' with patch(d) as delay_patch: params = {'cid': 'xxx', 'ec': 'ou812'} ga_track_event(params, async=False) assert delay_patch.call_count == 0
def test_ga_track_event_async_true(self): """async=True, then delay() gets called once""" with requests_mock.Mocker() as m: m.post(GOOGLE_API_URL, text="") post_event = "fjord.base.google_utils.post_event" post_event_delay = "fjord.base.google_utils.post_event.delay" with patch(post_event) as post_event_patch: with patch(post_event_delay) as post_event_delay_patch: params = {"cid": "xxx", "ec": "ou812"} ga_track_event(params, async=True) assert post_event_patch.call_count == 0 assert post_event_delay_patch.call_count == 1
def get_suggestions(self, feedback, request=None): # Note: We only want to run suggestions for sad responses for # Firefox product with en-US locale and for feedback that has # more than 7 words. # # If any of that changes, we'll need to rethink this. if ((feedback.happy or feedback.locale != u'en-US' or feedback.product != u'Firefox' or len(feedback.description.split()) < 7)): return [] session_key = SUMO_SUGGEST_SESSION_KEY.format(feedback.id) # Check the session to see if we've provided links already and # if so, re-use those. if request is not None: docs = request.session.get(session_key, None) if docs is not None: return self.docs_to_links(docs) try: docs = get_kb_articles(u'en-US', u'Firefox', feedback.description) except Exception: # FIXME: As we discover what exceptions actually get # kicked up, we can handle them individually as # appropriate. logger.exception('SUMO Suggest API raised exception.') return [] # Note: This needs to be synchronous so that "suggest" events # come before their respective "view*" events. ga_track_event({ 'cid': str(feedback.id), 'ec': EVENT_CATEGORY, 'ea': 'suggest' }, async=False) links = self.docs_to_links(docs) if request is not None: request.session[session_key] = docs return links
def test_ga_track_event_non_test(self): with patch('fjord.base.google_utils.requests') as req_patch: # Create a mock that we can call .post() on and query what # it got params-wise. It doesn't matter what the return # is. req_patch.post = MagicMock() params = {'cid': 'xxx', 'ec': 'ou812'} ga_track_event(params) req_patch.post.assert_called_once_with( GOOGLE_API_URL, data={ 'tid': 'UA-35433268-26', 'v': '1', 't': 'event', 'ec': 'ou812', # "test_" is not prepended. 'cid': 'xxx' })
def test_ga_track_event_non_test(self): with patch("fjord.base.google_utils.requests") as req_patch: # Create a mock that we can call .post() on and query what # it got params-wise. It doesn't matter what the return # is. req_patch.post = MagicMock() params = {"cid": "xxx", "ec": "ou812"} ga_track_event(params) req_patch.post.assert_called_once_with( GOOGLE_API_URL, data={ "tid": "UA-35433268-26", "v": "1", "t": "event", "ec": "ou812", # "test_" is not prepended. "cid": "xxx", }, )
def test_ga_track_event_non_test(self): with patch('fjord.base.google_utils.requests') as req_patch: # Create a mock that we can call .post() on and query what # it got params-wise. It doesn't matter what the return # is. req_patch.post = MagicMock() params = {'cid': 'xxx', 'ec': 'ou812'} ga_track_event(params) req_patch.post.assert_called_once_with( GOOGLE_API_URL, data={ 'tid': 'UA-35433268-26', 'v': '1', 't': 'event', 'ec': 'ou812', # "test_" is not prepended. 'cid': 'xxx' } )
def handle_redirect(self, request, redirect): # If it's not a trigger redirect, return. if not redirect.startswith(TRIGGER): return # Get the response id for the last feedback left. response_id = request.session.get('response_id', None) if response_id is None: return # Extract the slug. try: trigger, slug = parse_redirect(redirect) except RedirectParseError: return # Get the rule that has that slug. try: rule = TriggerRule.objects.get(slug=slug) except TriggerRule.DoesNotExist: return # Interpolate the url. destination_url = rule.url if '{' in destination_url: # Fetch the response so we can interpolate the url. try: response = FeedbackResponse.objects.get(id=response_id) except FeedbackResponse.DoesNotExist: return destination_url = interpolate_url(destination_url, response) # Track the event and then return the new url. ga_track_event({ 'cid': str(response_id), 'ec': build_ga_category(rule), 'ea': 'view', 'el': destination_url, }, async=True) return destination_url
def handle_redirect(self, request, redirect): # If it's not a sumosuggest redirect, return. if not redirect.startswith('sumosuggest'): return # Get the response id for the last feedback left. response_id = request.session.get('response_id', None) if response_id is None: return # If the session has no links, then we have nothing to # redirect to, so return. session_key = SUMO_SUGGEST_SESSION_KEY.format(response_id) docs = request.session.get(session_key, None) if not docs: return # Extract the rank. try: trigger, rank = parse_redirect(redirect) except RedirectParseError: return if rank == 'aaq': url = SUMO_AAQ_URL else: try: url = docs[rank]['url'] except IndexError: # This doc doesn't exist. return ga_track_event({ 'cid': str(response_id), 'ec': EVENT_CATEGORY, 'ea': 'view' if rank != 'aaq' else 'viewaaq', 'el': url }, async=True) return url
def get_suggestions(self, feedback, request=None): # Note: This implementation assumes there aren't a fajillion # active rules. If that becomes a problem, we should # re-architect the db so that this is easier to implement. # # Further, each matching rule will kick off a GA event # request. We have to do those synchronously so that we're # guaranteed to have the "suggest" event before the "click" # event. Otherwise the data is not as meaningful. rules = TriggerRule.objects.all_enabled() links = [] # Go through the rules and accrue links until we're done. # FIXME: Can we do one ga_track_event call for all the rules? for rule in rules: if rule.match(feedback): links.append( Link( provider=PROVIDER, provider_version=PROVIDER_VERSION, cssclass=u'document', summary=rule.title, description=rule.description, url=build_redirect_url(format_redirect(rule.slug)) ) ) # Track category: trigger-slug, action: suggest ga_track_event({ 'cid': str(feedback.id), 'ec': build_ga_category(rule), 'ea': 'suggest', 'el': rule.url }) return links