def test_search_results_pagination(self): """Test that the pagination of results works as expected. """ def mocked_supersearch_get(**params): assert '_columns' in params # Make sure a negative page does not lead to negative offset value. # But instead it is considered as the page 1 and thus is not added. assert params.get('_results_offset') == 0 hits = [] for i in range(140): hits.append({ "signature": "hang | nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": i, "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }) return { "hits": self.only_certain_columns(hits, params['_columns']), "facets": "", "total": len(hits) } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_results') response = self.client.get( url, { 'signature': 'hang | nsASDOMWindowEnumerator::GetNext()', '_columns': ['version'], '_facets': ['platform'], } ) assert response.status_code == 200 assert '140' in smart_text(response.content) # Check that the pagination URL contains all three expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) assert '_facets=platform' in next_page_url assert '_columns=version' in next_page_url assert 'page=2' in next_page_url assert '#crash-reports' in next_page_url # Verify white spaces are correctly encoded. # Note we use `quote` and not `quote_plus`, so white spaces are # turned into '%20' instead of '+'. assert quote('hang | nsASDOMWindowEnumerator::GetNext()') in next_page_url # Test that a negative page value does not break it. response = self.client.get(url, {'page': '-1'}) assert response.status_code == 200
def test_topcrasher_by_build(self): def mocked_supersearch_get(**params): ok_('build_id' in params) return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_range_type': 'build', }) eq_(response.status_code, 200) # Test with a version that does not support builds. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '18.0', '_range_type': 'build', }) eq_(response.status_code, 200) ok_('versions do not support the by build date' in response.content) ok_('Range Type:' not in response.content)
def test_topcrasher_without_any_signatures(self, rpost): url = self.base_url + '?product=WaterWolf&version=19.0' response = self.client.get(self.base_url, { 'product': 'WaterWolf', }) ok_(url in response['Location']) rpost.side_effect = mocked_post_123 def mocked_supersearch_get(**params): return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', }) eq_(response.status_code, 200)
def test_search_custom_parameters(self): self.create_custom_query_perm() def mocked_supersearch_get(**params): ok_('_return_query' in params) ok_('signature' in params) eq_(params['signature'], ['nsA']) return { "query": { "query": None }, "indices": ["socorro200000", "socorro200001"] } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) url = reverse('supersearch.search_custom') response = self.client.get(url, {'signature': 'nsA'}) eq_(response.status_code, 200) ok_('Run a search to get some results' in response.content) ok_('{"query": null}' in response.content) ok_('socorro200000' in response.content) ok_('socorro200001' in response.content)
def test_topcrasher_modes(self): def mocked_supersearch_get(**params): return {'hits': [], 'facets': {'signature': []}, 'total': 0} SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) now = datetime.datetime.utcnow().replace(microsecond=0) today = now.replace(hour=0, minute=0, second=0) with freezegun.freeze_time(now, tz_offset=0): now = now.isoformat() today = today.isoformat() # By default, it returns "real-time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', }) assert response.status_code == 200 assert now in response.content assert today not in response.content # Now test the "day time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_tcbs_mode': 'byday', }) assert response.status_code == 200 assert today in response.content assert now not in response.content
def test_signature_summary_with_many_hexes(self): def mocked_supersearch_get(**params): assert "signature" in params assert params["signature"] == ["=" + DUMB_SIGNATURE] adapters = [{"term": "0x{0:0>4}".format(i), "count": 1} for i in range(50)] vendors = [ { "term": "0x{0:0>4}".format(i), "count": 50, "facets": {"adapter_device_id": adapters}, } for i in range(3) ] res = {"hits": [], "total": 4, "facets": {"adapter_vendor_id": vendors}} return res SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get # Test with no results url = reverse("signature:signature_summary") response = self.client.get( url, {"signature": DUMB_SIGNATURE, "product": "WaterWolf", "version": "1.0"} ) assert response.status_code == 200
def test_search_custom_parameters(self): self.create_custom_query_perm() def mocked_supersearch_get(**params): assert '_return_query' in params assert 'signature' in params assert params['signature'] == ['nsA'] return { "query": { "query": None }, "indices": ["socorro200000", "socorro200001"] } SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_custom') response = self.client.get(url, {'signature': 'nsA'}) assert response.status_code == 200 assert 'Run a search to get some results' in smart_text( response.content) assert '{"query": null}' in smart_text(response.content) assert 'socorro200000' in smart_text(response.content) assert 'socorro200001' in smart_text(response.content)
def test_modes(self): def mocked_supersearch_get(**params): return {"hits": [], "facets": {"signature": []}, "total": 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get now = datetime.datetime.utcnow().replace(microsecond=0) today = now.replace(hour=0, minute=0, second=0) with freezegun.freeze_time(now, tz_offset=0): now = now.isoformat() today = today.isoformat() # By default, it returns "real-time" data. response = self.client.get(self.base_url, { "product": "WaterWolf", "version": "19.0" }) assert response.status_code == 200 assert now in smart_text(response.content) assert today not in smart_text(response.content) # Now test the "day time" data. response = self.client.get( self.base_url, { "product": "WaterWolf", "version": "19.0", "_tcbs_mode": "byday" }, ) assert response.status_code == 200 assert today in smart_text(response.content) assert now not in smart_text(response.content)
def test_search_results_pagination(self): """Test that the pagination of results works as expected. """ def mocked_supersearch_get(**params): assert '_columns' in params # Make sure a negative page does not lead to negative offset value. # But instead it is considered as the page 1 and thus is not added. eq_(params.get('_results_offset'), 0) hits = [] for i in range(140): hits.append({ "signature": "hang | nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": i, "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }) return { "hits": self.only_certain_columns(hits, params['_columns']), "facets": "", "total": len(hits) } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) url = reverse('supersearch.search_results') response = self.client.get( url, { 'signature': 'hang | nsASDOMWindowEnumerator::GetNext()', '_columns': ['version'], '_facets': ['platform'], }) eq_(response.status_code, 200) ok_('140' in response.content) # Check that the pagination URL contains all three expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) ok_('_facets=platform' in next_page_url) ok_('_columns=version' in next_page_url) ok_('page=2' in next_page_url) ok_('#crash-reports' in next_page_url) # Verify white spaces are correctly encoded. ok_( # Note we use `quote` and not `quote_plus`, so white spaces are # turned into '%20' instead of '+'. urllib.quote('hang | nsASDOMWindowEnumerator::GetNext()') in next_page_url) # Test that a negative page value does not break it. response = self.client.get(url, {'page': '-1'}) eq_(response.status_code, 200)
def test_signature_reports_pagination(self): """Test that the pagination of results works as expected""" def mocked_supersearch_get(**params): assert "_columns" in params # Make sure a negative page does not lead to negative offset value. # But instead it is considered as the page 1 and thus is not added. assert params.get("_results_offset") == 0 hits = [] for i in range(140): hits.append( { "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": i, "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981, } ) return { "hits": self.only_certain_columns(hits, params["_columns"]), "facets": "", "total": len(hits), } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse("signature:signature_reports") response = self.client.get( url, { "signature": DUMB_SIGNATURE, "product": ["WaterWolf"], "_columns": ["platform"], }, ) assert response.status_code == 200 assert "140" in smart_text(response.content) # Check that the pagination URL contains all three expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc(".pagination a").eq(0)) assert "product=WaterWolf" in next_page_url assert "_columns=platform" in next_page_url assert "page=2" in next_page_url # Verify white spaces are correctly encoded. # Note we use `quote` and not `quote_plus`, so white spaces are # turned into '%20' instead of '+'. assert quote(DUMB_SIGNATURE) in next_page_url # Test that a negative page value does not break it. response = self.client.get(url, {"signature": DUMB_SIGNATURE, "page": "-1"}) assert response.status_code == 200
def test_parameters(self): def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. ok_('product' in params) ok_('WaterWolf' in params['product']) ok_('NightTrain' in params['product']) ok_('address' in params) ok_('0x0' in params['address']) ok_('0xa' in params['address']) ok_('reason' in params) ok_('^hello' in params['reason']) ok_('$thanks' in params['reason']) ok_('java_stack_trace' in params) ok_('Exception' in params['java_stack_trace']) return {"hits": [], "facets": "", "total": 0} SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) url = reverse('signature:signature_reports') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf', 'NightTrain'], 'address': ['0x0', '0xa'], 'reason': ['^hello', '$thanks'], 'java_stack_trace': 'Exception', }) eq_(response.status_code, 200)
def test_topcrashers_product_sans_featured_version(self): def mocked_supersearch_get(**params): if '_columns' not in params: params['_columns'] = [] # By default we range by date, so there should be no filter on # the build id. assert 'build_id' not in params if 'hang_type' not in params['_aggs.signature']: # Return results for the previous week. results = {'hits': [], 'facets': {'signature': []}, 'total': 0} else: # Return results for the current week. results = {'hits': [], 'facets': {'signature': []}, 'total': 0} results['hits'] = self.only_certain_columns( results['hits'], params['_columns']) return results SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) response = self.client.get(self.base_url, {'product': 'SeaMonkey'}) assert response.status_code == 302 actual_url = self.base_url + '?product=SeaMonkey&version=9.5' assert actual_url in response['Location'] response = self.client.get(self.base_url, { 'product': 'SeaMonkey', 'version': '9.5', }) assert response.status_code == 200
def test_search_results_parameters(self): def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. assert 'product' in params assert 'WaterWolf' in params['product'] assert 'NightTrain' in params['product'] assert 'address' in params assert '0x0' in params['address'] assert '0xa' in params['address'] assert 'reason' in params assert '^hello' in params['reason'] assert '$thanks' in params['reason'] assert 'java_stack_trace' in params assert 'Exception' in params['java_stack_trace'] return {"hits": [], "facets": "", "total": 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_results') response = self.client.get( url, { 'product': ['WaterWolf', 'NightTrain'], 'address': ['0x0', '0xa'], 'reason': ['^hello', '$thanks'], 'java_stack_trace': 'Exception', }) assert response.status_code == 200
def test_search_results_parameters(self): def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. assert "product" in params assert "WaterWolf" in params["product"] assert "NightTrain" in params["product"] assert "address" in params assert "0x0" in params["address"] assert "0xa" in params["address"] assert "reason" in params assert "^hello" in params["reason"] assert "$thanks" in params["reason"] assert "java_stack_trace" in params assert "Exception" in params["java_stack_trace"] return {"hits": [], "facets": "", "total": 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get url = reverse("supersearch:search_results") response = self.client.get( url, { "product": ["WaterWolf", "NightTrain"], "address": ["0x0", "0xa"], "reason": ["^hello", "$thanks"], "java_stack_trace": "Exception", }, ) assert response.status_code == 200
def test_search_custom_parameters(self): self.create_custom_query_perm() def mocked_supersearch_get(**params): assert "_return_query" in params assert "signature" in params assert params["signature"] == ["nsA"] return { "query": { "query": None }, "indices": ["socorro200000", "socorro200001"], } SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get url = reverse("supersearch:search_custom") response = self.client.get(url, {"signature": "nsA"}) assert response.status_code == 200 assert "Run a search to get some results" in smart_text( response.content) assert "{"query": null}" in smart_text(response.content) assert "socorro200000" in smart_text(response.content) assert "socorro200001" in smart_text(response.content)
def test_topcrasher_by_build(self, rpost): rpost.side_effect = mocked_post_123 def mocked_supersearch_get(**params): ok_('build_id' in params) return {'hits': [], 'facets': {'signature': []}, 'total': 0} SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_range_type': 'build', }) eq_(response.status_code, 200) # Test with a version that does not support builds. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '18.0', '_range_type': 'build', }) eq_(response.status_code, 200) ok_('versions do not support the by build date' in response.content) ok_('Range Type:' not in response.content)
def test_signature_reports_pagination(self): """Test that the pagination of results works as expected. """ def mocked_supersearch_get(**params): assert '_columns' in params # Make sure a negative page does not lead to negative offset value. # But instead it is considered as the page 1 and thus is not added. eq_(params.get('_results_offset'), 0) hits = [] for i in range(140): hits.append({ "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": i, "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }) return { "hits": self.only_certain_columns(hits, params['_columns']), "facets": "", "total": len(hits) } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('signature:signature_reports') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf'], '_columns': ['platform'] } ) eq_(response.status_code, 200) ok_('140' in response.content) # Check that the pagination URL contains all three expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) ok_('product=WaterWolf' in next_page_url) ok_('_columns=platform' in next_page_url) ok_('page=2' in next_page_url) # Test that a negative page value does not break it. response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'page': '-1', }) eq_(response.status_code, 200)
def test_signature_aggregation(self): def mocked_supersearch_get(**params): assert 'signature' in params assert params['signature'] == ['=' + DUMB_SIGNATURE] assert '_facets' in params if 'product' in params['_facets']: return { "hits": [], "facets": { "product": [ { "term": "windows", "count": 42, }, { "term": "linux", "count": 1337, }, { "term": "mac", "count": 3, }, ] }, "total": 1382 } # the default return { "hits": [], "facets": { "platform": [] }, "total": 0 } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get # Test with no results. url = reverse('signature:signature_aggregation', args=('platform',)) response = self.client.get(url, {'signature': DUMB_SIGNATURE}) assert response.status_code == 200 assert 'Product' not in smart_text(response.content) assert 'No results were found' in smart_text(response.content) # Test with results. url = reverse('signature:signature_aggregation', args=('product',)) response = self.client.get(url, {'signature': DUMB_SIGNATURE}) assert response.status_code == 200 assert 'Product' in smart_text(response.content) assert '1337' in smart_text(response.content) assert 'linux' in smart_text(response.content) assert str(int(1337 / 1382 * 100)) in smart_text(response.content) assert 'windows' in smart_text(response.content) assert 'mac' in smart_text(response.content)
def test_SuperSearchUnredacted(self): def mocked_supersearch_get(**params): assert 'exploitability' in params if 'product' in params: assert params['product'] == ['WaterWolf', 'NightTrain'] return { 'hits': [{ 'signature': 'abcdef', 'product': 'WaterWolf', 'version': '1.0', 'email': '*****@*****.**', 'exploitability': 'high', 'url': 'http://embarassing.website.com', 'user_comments': 'hey I am [email protected]', }], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) url = reverse('api:model_wrapper', args=('SuperSearchUnredacted', )) response = self.client.get(url, {'exploitability': 'high'}) assert response.status_code == 403 assert response['Content-Type'] == 'application/json' error = json.loads(response.content)['error'] permission = Permission.objects.get(codename='view_exploitability') assert permission.name in error # Log in to get permissions. user = self._login() self._add_permission(user, 'view_pii') self._add_permission(user, 'view_exploitability') response = self.client.get(url, {'exploitability': 'high'}) assert response.status_code == 200 res = json.loads(response.content) assert res['hits'] assert res['facets'] # Verify forbidden fields are exposed. assert 'email' in res['hits'][0] assert 'exploitability' in res['hits'][0] assert 'url' in res['hits'][0] # Verify user comments are not scrubbed. assert '*****@*****.**' in res['hits'][0]['user_comments'] # Verify values can be lists. response = self.client.get(url, { 'exploitability': 'high', 'product': ['WaterWolf', 'NightTrain'] }) assert response.status_code == 200
def test_SuperSearchUnredacted(self): def mocked_supersearch_get(**params): assert 'exploitability' in params if 'product' in params: assert params['product'] == ['WaterWolf', 'NightTrain'] return { 'hits': [ { 'signature': 'abcdef', 'product': 'WaterWolf', 'version': '1.0', 'email': '*****@*****.**', 'exploitability': 'high', 'url': 'http://embarassing.website.com', 'user_comments': 'hey I am [email protected]', } ], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse('api:model_wrapper', args=('SuperSearchUnredacted',)) response = self.client.get(url, {'exploitability': 'high'}) assert response.status_code == 403 assert response['Content-Type'] == 'application/json' error = json.loads(response.content)['error'] permission = Permission.objects.get( codename='view_exploitability' ) assert permission.name in error # Log in to get permissions. user = self._login() self._add_permission(user, 'view_pii') self._add_permission(user, 'view_exploitability') response = self.client.get(url, {'exploitability': 'high'}) assert response.status_code == 200 res = json.loads(response.content) assert res['hits'] assert res['facets'] # Verify forbidden fields are exposed. assert 'email' in res['hits'][0] assert 'exploitability' in res['hits'][0] assert 'url' in res['hits'][0] assert '*****@*****.**' in res['hits'][0]['user_comments'] # Verify values can be lists. response = self.client.get(url, { 'exploitability': 'high', 'product': ['WaterWolf', 'NightTrain'] }) assert response.status_code == 200
def test_signature_comments_pagination(self): """Test that the pagination of comments works as expected""" def mocked_supersearch_get(**params): assert '_columns' in params if params.get('_results_offset') != 0: hits_range = range(100, 140) else: hits_range = range(100) hits = [] for i in hits_range: hits.append({ "date": "2017-01-31T23:12:57", "uuid": i, "user_comments": "hi", }) return { 'hits': self.only_certain_columns(hits, params['_columns']), 'total': 140 } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get user = self._login() user.groups.add(self._create_group_with_permission('view_pii')) assert user.has_perm('crashstats.view_pii') url = reverse('signature:signature_comments') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf'], } ) assert response.status_code == 200 assert '140' in smart_text(response.content) assert '99' in smart_text(response.content) assert '139' not in smart_text(response.content) # Check that the pagination URL contains all expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) assert 'product=WaterWolf' in next_page_url assert 'page=2' in next_page_url response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'page': '2', }) assert response.status_code == 200 assert '140' in smart_text(response.content) assert '99' not in smart_text(response.content) assert '139' in smart_text(response.content)
def test_signature_comments_pagination(self): """Test that the pagination of comments works as expected. """ def mocked_supersearch_get(**params): assert '_columns' in params if params.get('_results_offset') != 0: hits_range = range(100, 140) else: hits_range = range(100) hits = [] for i in hits_range: hits.append({ "date": "2017-01-31T23:12:57", "uuid": i, "user_comments": "hi", }) return { "hits": self.only_certain_columns(hits, params['_columns']), "total": 140 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('signature:signature_comments') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf'], } ) eq_(response.status_code, 200) ok_('140' in response.content) ok_('99' in response.content) ok_('139' not in response.content) # Check that the pagination URL contains all expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) ok_('product=WaterWolf' in next_page_url) ok_('page=2' in next_page_url) response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'page': '2', }) eq_(response.status_code, 200) ok_('140' in response.content) ok_('99' not in response.content) ok_('139' in response.content)
def test_signature_comments_pagination(self): """Test that the pagination of comments works as expected. """ def mocked_supersearch_get(**params): assert '_columns' in params if params.get('_results_offset') != 0: hits_range = range(100, 140) else: hits_range = range(100) hits = [] for i in hits_range: hits.append({ "date": "2017-01-31T23:12:57", "uuid": i, "user_comments": "hi", }) return { 'hits': self.only_certain_columns(hits, params['_columns']), 'total': 140 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('signature:signature_comments') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf'], } ) assert response.status_code == 200 assert '140' in response.content assert '99' in response.content assert '139' not in response.content # Check that the pagination URL contains all expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc('.pagination a').eq(0)) assert 'product=WaterWolf' in next_page_url assert 'page=2' in next_page_url response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'page': '2', }) assert response.status_code == 200 assert '140' in response.content assert '99' not in response.content assert '139' in response.content
def test_SuperSearchUnredacted(self): def mocked_supersearch_get(**params): assert "exploitability" in params if "product" in params: assert params["product"] == ["WaterWolf", "NightTrain"] return { "hits": [{ "signature": "abcdef", "product": "WaterWolf", "version": "1.0", "email": "*****@*****.**", "exploitability": "high", "url": "http://embarassing.website.com", "user_comments": "hey I am [email protected]", }], "facets": { "signature": [] }, "total": 0, } SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get url = reverse("api:model_wrapper", args=("SuperSearchUnredacted", )) response = self.client.get(url, {"exploitability": "high"}) assert response.status_code == 403 assert response["Content-Type"] == "application/json" error = json.loads(response.content)["error"] permission = Permission.objects.get(codename="view_exploitability") assert permission.name in error # Log in to get permissions. user = self._login() self._add_permission(user, "view_pii") self._add_permission(user, "view_exploitability") response = self.client.get(url, {"exploitability": "high"}) assert response.status_code == 200 res = json.loads(response.content) assert res["hits"] assert res["facets"] # Verify forbidden fields are exposed. assert "email" in res["hits"][0] assert "exploitability" in res["hits"][0] assert "url" in res["hits"][0] assert "*****@*****.**" in res["hits"][0]["user_comments"] # Verify values can be lists. response = self.client.get(url, { "exploitability": "high", "product": ["WaterWolf", "NightTrain"] }) assert response.status_code == 200
def test_signature_comments_pagination(self): """Test that the pagination of comments works as expected""" def mocked_supersearch_get(**params): assert "_columns" in params if params.get("_results_offset") != 0: hits_range = range(100, 140) else: hits_range = range(100) hits = [] for i in hits_range: hits.append({ "date": "2017-01-31T23:12:57", "uuid": i, "user_comments": "hi" }) return { "hits": self.only_certain_columns(hits, params["_columns"]), "total": 140, } SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get user = self._login() user.groups.add(self._create_group_with_permission("view_pii")) assert user.has_perm("crashstats.view_pii") url = reverse("signature:signature_comments") response = self.client.get(url, { "signature": DUMB_SIGNATURE, "product": ["WaterWolf"] }) assert response.status_code == 200 assert "140" in smart_text(response.content) assert "99" in smart_text(response.content) assert "139" not in smart_text(response.content) # Check that the pagination URL contains all expected parameters. doc = pyquery.PyQuery(response.content) next_page_url = str(doc(".pagination a").eq(0)) assert "product=WaterWolf" in next_page_url assert "page=2" in next_page_url response = self.client.get(url, { "signature": DUMB_SIGNATURE, "page": "2" }) assert response.status_code == 200 assert "140" in smart_text(response.content) assert "99" not in smart_text(response.content) assert "139" in smart_text(response.content)
def test_signature_summary_with_many_hexes(self): get_calls = [] def mocked_get(**params): get_calls.append(1) ok_(len(params['vendor_hex']) <= 50) ok_(len(params['adapter_hex']) <= 50) return {'hits': [], 'total': 0} models.GraphicsDevices.implementation().get.side_effect = (mocked_get) def mocked_supersearch_get(**params): ok_('signature' in params) eq_(params['signature'], ['=' + DUMB_SIGNATURE]) adapters = [{ 'term': '0x{0:0>4}'.format(i), 'count': 1 } for i in range(50)] vendors = [{ 'term': '0x{0:0>4}'.format(i), 'count': 50, 'facets': { 'adapter_device_id': adapters } } for i in range(3)] res = { 'hits': [], 'total': 4, 'facets': { 'adapter_vendor_id': vendors, } } return res SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) # Test with no results url = reverse('signature:signature_summary') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': 'WaterWolf', 'version': '1.0', }) eq_(response.status_code, 200) # There are 150 different hexes, there should be 3 calls to the API. eq_(len(get_calls), 3)
def test_without_any_signatures(self): def mocked_supersearch_get(**params): return {"hits": [], "facets": {"signature": []}, "total": 0} SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get response = self.client.get( self.base_url, {"product": "WaterWolf", "version": "19.0"} ) assert response.status_code == 200
def test_signature_aggregation(self): def mocked_supersearch_get(**params): assert "signature" in params assert params["signature"] == ["=" + DUMB_SIGNATURE] assert "_facets" in params if "product" in params["_facets"]: return { "hits": [], "facets": { "product": [ { "term": "windows", "count": 42 }, { "term": "linux", "count": 1337 }, { "term": "mac", "count": 3 }, ] }, "total": 1382, } # the default return {"hits": [], "facets": {"platform": []}, "total": 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get # Test with no results. url = reverse("signature:signature_aggregation", args=("platform", )) response = self.client.get(url, {"signature": DUMB_SIGNATURE}) assert response.status_code == 200 assert "Product" not in smart_text(response.content) assert "No results were found" in smart_text(response.content) # Test with results. url = reverse("signature:signature_aggregation", args=("product", )) response = self.client.get(url, {"signature": DUMB_SIGNATURE}) assert response.status_code == 200 assert "Product" in smart_text(response.content) assert "1337" in smart_text(response.content) assert "linux" in smart_text(response.content) assert str(int(1337 / 1382 * 100)) in smart_text(response.content) assert "windows" in smart_text(response.content) assert "mac" in smart_text(response.content)
def test_without_any_signatures(self): def mocked_supersearch_get(**params): return {'hits': [], 'facets': {'signature': []}, 'total': 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0' }) assert response.status_code == 200
def test_by_build(self): def mocked_supersearch_get(**params): assert "build_id" in params return {"hits": [], "facets": {"signature": []}, "total": 0} SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get response = self.client.get( self.base_url, {"product": "WaterWolf", "version": "19.0", "_range_type": "build"}, ) assert response.status_code == 200
def test_search_custom(self): def mocked_supersearch_get(**params): return None SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get self.create_custom_query_perm() url = reverse('supersearch:search_custom') response = self.client.get(url) assert response.status_code == 200 assert 'Run a search to get some results' in smart_text(response.content)
def test_search_custom(self): def mocked_supersearch_get(**params): return None SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) self.create_custom_query_perm() url = reverse('supersearch.search_custom') response = self.client.get(url) eq_(response.status_code, 200) ok_('Run a search to get some results' in response.content)
def test_search_results_badargumenterror(self): def mocked_supersearch_get(**params): raise BadArgumentError("<script>xss") SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse("supersearch:search_results") params = {"product": "WaterWolf"} response = self.client.get(url, params, HTTP_X_REQUESTED_WITH="XMLHttpRequest") assert response.status_code == 400 assert response["content-type"] == "text/html; charset=utf-8" assert "<script>" not in smart_text(response.content) assert "<script>" in smart_text(response.content)
def test_by_build(self): def mocked_supersearch_get(**params): assert 'build_id' in params return {'hits': [], 'facets': {'signature': []}, 'total': 0} SuperSearchUnredacted.implementation( ).get.side_effect = mocked_supersearch_get response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_range_type': 'build', }) assert response.status_code == 200
def test_search_custom(self): def mocked_supersearch_get(**params): return None SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) self.create_custom_query_perm() url = reverse('supersearch.search_custom') response = self.client.get(url) eq_(response.status_code, 200) ok_('Run a search to get some results' in response.content)
def test_topcrashers_product_sans_featured_version(self): def mocked_supersearch_get(**params): if '_columns' not in params: params['_columns'] = [] # By default we range by date, so there should be no filter on # the build id. ok_('build_id' not in params) if 'hang_type' not in params['_aggs.signature']: # Return results for the previous week. results = { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } else: # Return results for the current week. results = { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) response = self.client.get(self.base_url, {'product': 'SeaMonkey'}) eq_(response.status_code, 302) actual_url = self.base_url + '?product=SeaMonkey&version=9.5' ok_(actual_url in response['Location']) response = self.client.get(self.base_url, { 'product': 'SeaMonkey', 'version': '9.5', }) eq_(response.status_code, 200)
def test_product_sans_featured_version(self): def mocked_supersearch_get(**params): if '_columns' not in params: params['_columns'] = [] # By default we range by date, so there should be no filter on # the build id. assert 'build_id' not in params if 'hang_type' not in params['_aggs.signature']: # Return results for the previous week. results = { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } else: # Return results for the current week. results = { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get self.set_product_versions(['20.0', '19.0', '18.0']) # Redirects to the most recent featured version response = self.client.get(self.base_url, {'product': 'SeaMonkey'}) assert response.status_code == 302 actual_url = self.base_url + '?product=SeaMonkey&version=20.0' assert actual_url in response['Location'] # This version doesn't exist, but it still renders something and # doesn't throw an error response = self.client.get(self.base_url, {'product': 'SeaMonkey', 'version': '9.5'}) assert response.status_code == 200
def test_search_results_parameters(self, rpost): def mocked_post(**options): assert 'bugs' in options['url'], options['url'] return Response({ "hits": [], "total": 0 }) rpost.side_effect = mocked_post def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. ok_('product' in params) ok_('WaterWolf' in params['product']) ok_('NightTrain' in params['product']) ok_('address' in params) ok_('0x0' in params['address']) ok_('0xa' in params['address']) ok_('reason' in params) ok_('^hello' in params['reason']) ok_('$thanks' in params['reason']) ok_('java_stack_trace' in params) ok_('Exception' in params['java_stack_trace']) return { "hits": [], "facets": "", "total": 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_results') response = self.client.get( url, { 'product': ['WaterWolf', 'NightTrain'], 'address': ['0x0', '0xa'], 'reason': ['^hello', '$thanks'], 'java_stack_trace': 'Exception', } ) eq_(response.status_code, 200)
def test_search_results_badargumenterror(self): def mocked_supersearch_get(**params): raise BadArgumentError('<script>xss') SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get) url = reverse('supersearch.search_results') params = {'product': 'WaterWolf'} response = self.client.get(url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(response.status_code, 400) eq_(response['content-type'], 'text/html; charset=utf-8') ok_('<script>' not in response.content) ok_('<script>' in response.content)
def test_search_results_badargumenterror(self): def mocked_supersearch_get(**params): raise BadArgumentError('<script>xss') SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_results') params = {'product': 'WaterWolf'} self.client.get(url, params) response = self.client.get(url, params) eq_(response.status_code, 400) eq_(response['content-type'], 'text/html; charset=utf-8') ok_('<script>' not in response.content) ok_('<script>' in response.content)
def test_without_any_signatures(self): def mocked_supersearch_get(**params): return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0' }) assert response.status_code == 200
def test_search_results_badargumenterror(self): def mocked_supersearch_get(**params): raise BadArgumentError('<script>xss') SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_results') params = {'product': 'WaterWolf'} response = self.client.get( url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) assert response.status_code == 400 assert response['content-type'] == 'text/html; charset=utf-8' assert '<script>' not in smart_text(response.content) assert '<script>' in smart_text(response.content)
def test_signature_summary_with_many_hexes(self): def mocked_supersearch_get(**params): assert 'signature' in params assert params['signature'] == ['=' + DUMB_SIGNATURE] adapters = [ { 'term': '0x{0:0>4}'.format(i), 'count': 1 } for i in range(50) ] vendors = [ { 'term': '0x{0:0>4}'.format(i), 'count': 50, 'facets': { 'adapter_device_id': adapters } } for i in range(3) ] res = { 'hits': [], 'total': 4, 'facets': { 'adapter_vendor_id': vendors, } } return res SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get # Test with no results url = reverse('signature:signature_summary') response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'product': 'WaterWolf', 'version': '1.0', }) assert response.status_code == 200
def test_by_build(self): def mocked_supersearch_get(**params): assert 'build_id' in params return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_range_type': 'build', }) assert response.status_code == 200
def test_topcrasher_modes(self, rpost): rpost.side_effect = mocked_post_123 def mocked_supersearch_get(**params): return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) now = datetime.datetime.utcnow() today = now.replace(hour=0, minute=0, second=0, microsecond=0) timestr = '%Y-%m-%d %H:%M:%S' now = now.strftime(timestr) today = today.strftime(timestr) with freezegun.freeze_time(now, tz_offset=0): # By default, it returns "real-time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', }) eq_(response.status_code, 200) ok_(now in response.content, now) ok_(today not in response.content) # Now test the "day time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_tcbs_mode': 'byday', }) eq_(response.status_code, 200) ok_(today in response.content) ok_(now not in response.content)
def test_parameters(self): def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. ok_('product' in params) ok_('WaterWolf' in params['product']) ok_('NightTrain' in params['product']) ok_('address' in params) ok_('0x0' in params['address']) ok_('0xa' in params['address']) ok_('reason' in params) ok_('^hello' in params['reason']) ok_('$thanks' in params['reason']) ok_('java_stack_trace' in params) ok_('Exception' in params['java_stack_trace']) return { "hits": [], "facets": "", "total": 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('signature:signature_reports') response = self.client.get( url, { 'signature': DUMB_SIGNATURE, 'product': ['WaterWolf', 'NightTrain'], 'address': ['0x0', '0xa'], 'reason': ['^hello', '$thanks'], 'java_stack_trace': 'Exception', } ) eq_(response.status_code, 200)
def test_search_results_ratelimited(self): def mocked_supersearch_get(**params): return {"hits": [], "facets": [], "total": 0} SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_results') limit = int(re.findall(r'(\d+)', settings.RATELIMIT_SUPERSEARCH)[0]) params = {'product': 'WaterWolf'} # double to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1148470 for i in range(limit * 2): self.client.get(url, params) response = self.client.get( url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) assert response.status_code == 429 assert smart_text(response.content) == 'Too Many Requests' assert response['content-type'] == 'text/plain'
def test_search_results_parameters(self): def mocked_supersearch_get(**params): # Verify that all expected parameters are in the URL. assert 'product' in params assert 'WaterWolf' in params['product'] assert 'NightTrain' in params['product'] assert 'address' in params assert '0x0' in params['address'] assert '0xa' in params['address'] assert 'reason' in params assert '^hello' in params['reason'] assert '$thanks' in params['reason'] assert 'java_stack_trace' in params assert 'Exception' in params['java_stack_trace'] return { "hits": [], "facets": "", "total": 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_results') response = self.client.get( url, { 'product': ['WaterWolf', 'NightTrain'], 'address': ['0x0', '0xa'], 'reason': ['^hello', '$thanks'], 'java_stack_trace': 'Exception', } ) assert response.status_code == 200
def test_topcrasher_modes(self): def mocked_supersearch_get(**params): return { 'hits': [], 'facets': { 'signature': [] }, 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) now = datetime.datetime.utcnow().replace(microsecond=0) today = now.replace(hour=0, minute=0, second=0) with freezegun.freeze_time(now, tz_offset=0): now = now.isoformat() today = today.isoformat() # By default, it returns "real-time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', }) assert response.status_code == 200 assert now in response.content assert today not in response.content # Now test the "day time" data. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_tcbs_mode': 'byday', }) assert response.status_code == 200 assert today in response.content assert now not in response.content
def test_search_custom_parameters(self): self.create_custom_query_perm() def mocked_supersearch_get(**params): assert '_return_query' in params assert 'signature' in params assert params['signature'] == ['nsA'] return { "query": {"query": None}, "indices": ["socorro200000", "socorro200001"] } SuperSearchUnredacted.implementation().get.side_effect = mocked_supersearch_get url = reverse('supersearch:search_custom') response = self.client.get(url, {'signature': 'nsA'}) assert response.status_code == 200 assert 'Run a search to get some results' in smart_text(response.content) assert '{"query": null}' in smart_text(response.content) assert 'socorro200000' in smart_text(response.content) assert 'socorro200001' in smart_text(response.content)
def test_search_custom_parameters(self): self.create_custom_query_perm() def mocked_supersearch_get(**params): ok_('_return_query' in params) ok_('signature' in params) eq_(params['signature'], ['nsA']) return { "query": {"query": None}, "indices": ["socorro200000", "socorro200001"] } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_custom') response = self.client.get(url, {'signature': 'nsA'}) eq_(response.status_code, 200) ok_('Run a search to get some results' in response.content) ok_('{"query": null}' in response.content) ok_('socorro200000' in response.content) ok_('socorro200001' in response.content)
def test_signature_summary_with_many_hexes(self): get_calls = [] def mocked_get(**params): get_calls.append(1) ok_(len(params['vendor_hex']) <= 50) ok_(len(params['adapter_hex']) <= 50) return { 'hits': [], 'total': 0 } models.GraphicsDevices.implementation().get.side_effect = ( mocked_get ) def mocked_supersearch_get(**params): ok_('signature' in params) eq_(params['signature'], ['=' + DUMB_SIGNATURE]) adapters = [ { 'term': '0x{0:0>4}'.format(i), 'count': 1 } for i in range(50) ] vendors = [ { 'term': '0x{0:0>4}'.format(i), 'count': 50, 'facets': { 'adapter_device_id': adapters } } for i in range(3) ] res = { 'hits': [], 'total': 4, 'facets': { 'adapter_vendor_id': vendors, } } return res SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) # Test with no results url = reverse('signature:signature_summary') response = self.client.get(url, { 'signature': DUMB_SIGNATURE, 'product': 'WaterWolf', 'version': '1.0', }) eq_(response.status_code, 200) # There are 150 different hexes, there should be 3 calls to the API. eq_(len(get_calls), 3)
def test_profile(self): def mocked_supersearch_get(**params): assert '_columns' in params assert '_sort' in params assert 'email' in params assert params['email'] == ['*****@*****.**'] results = { 'hits': [ { 'uuid': '1234abcd-ef56-7890-ab12-abcdef130802', 'date': '2000-01-02T00:00:00' }, { 'uuid': '1234abcd-ef56-7890-ab12-abcdef130801', 'date': '2000-01-01T00:00:00' }, ], 'total': 2 } return results def mocked_supersearch_get_no_data(**params): assert 'email' in params assert params['email'] == ['*****@*****.**'] return { 'hits': [], 'total': 0 } SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('profile:profile') # Test that the user must be signed in. response = self.client.get(url) eq_(response.status_code, 302) self.assertRedirects( response, reverse('crashstats:login') + '?next=%s' % url ) # Now log in for the remaining tests. user = self._login() # Test with results and check email is there. response = self.client.get(url) eq_(response.status_code, 200) ok_('1234abcd-ef56-7890-ab12-abcdef130801' in response.content) ok_('1234abcd-ef56-7890-ab12-abcdef130802' in response.content) ok_('*****@*****.**' in response.content) SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get_no_data ) # Test with no results. response = self.client.get(url) eq_(response.status_code, 200) ok_('*****@*****.**' in response.content) ok_('no crash report' in response.content) # Make some permissions. self._create_group_with_permission( 'view_pii', 'Group A' ) group_b = self._create_group_with_permission( 'view_exploitability', 'Group B' ) user.groups.add(group_b) assert not user.has_perm('crashstats.view_pii') assert user.has_perm('crashstats.view_exploitability') # Test permissions. response = self.client.get(url) ok_(PERMISSIONS['view_pii'] in response.content) ok_(PERMISSIONS['view_exploitability'] in response.content) doc = pyquery.PyQuery(response.content) for row in doc('table.permissions tbody tr'): cells = [] for td in doc('td', row): cells.append(td.text.strip()) if cells[0] == PERMISSIONS['view_pii']: eq_(cells[1], 'No') elif cells[0] == PERMISSIONS['view_exploitability']: eq_(cells[1], 'Yes!')
def test_search_results_admin_mode(self, rpost): """Test that an admin can see more fields, and that a non-admin cannot. """ def mocked_post(**options): assert 'bugs' in options['url'], options['url'] return Response({"hits": [], "total": 0}) rpost.side_effect = mocked_post def mocked_supersearch_get(**params): assert '_columns' in params if '_facets' in params and 'url' in params['_facets']: facets = { "platform": [ { "term": "Linux", "count": 3 } ], "url": [ { "term": "http://example.org", "count": 3 } ] } else: facets = { "platform": [ { "term": "Linux", "count": 3 } ] } results = { "hits": [ { "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa1", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981, "email": "*****@*****.**", "url": "http://example.org", "exploitability": "high" }, { "signature": "mySignatureIsCool", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa2", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981, "email": "*****@*****.**", "url": "http://example.org", "exploitability": "low" }, { "signature": "mineIsCoolerThanYours", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa3", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": None, "email": "*****@*****.**", "url": "http://example.org", "exploitability": "error" } ], "facets": facets, "total": 3 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_results') # Logged in user, can see the email field user = self._login() group = self._create_group_with_permission('view_pii') user.groups.add(group) response = self.client.get( url, { '_columns': ['version', 'email', 'url', 'exploitability'], '_facets': ['url', 'platform'] } ) eq_(response.status_code, 200) ok_('Email' in response.content) ok_('*****@*****.**' in response.content) ok_('Url facet' in response.content) ok_('http://example.org' in response.content) ok_('Version' in response.content) ok_('1.0' in response.content) # Without the correct permission the user cannot see exploitability. ok_('Exploitability' not in response.content) exp_group = self._create_group_with_permission('view_exploitability') user.groups.add(exp_group) response = self.client.get( url, { '_columns': ['version', 'email', 'url', 'exploitability'], '_facets': ['url', 'platform'] } ) eq_(response.status_code, 200) ok_('Email' in response.content) ok_('Exploitability' in response.content) ok_('high' in response.content) # Logged out user, cannot see the email field self._logout() response = self.client.get( url, { '_columns': ['version', 'email', 'url'], '_facets': ['url', 'platform'] } ) eq_(response.status_code, 200) ok_('Email' not in response.content) ok_('*****@*****.**' not in response.content) ok_('Url facet' not in response.content) ok_('http://example.org' not in response.content) ok_('Version' in response.content) ok_('1.0' in response.content)
def test_search_results(self, cpost): def mocked_post(**options): return { "hits": [ { "id": "123456", "signature": u"nsASDOMWindowEnumerator::GetNext()" } ], "total": 1 } cpost.side_effect = mocked_post def mocked_supersearch_get(**params): assert '_columns' in params if 'product' in params and 'WaterWolf' in params['product']: results = { "hits": [ { "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa1", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }, { "signature": "mySignatureIsCool", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa2", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }, { "signature": "mineIsCoolerThanYours", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa3", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": None }, { "signature": "EMPTY", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa4", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": None } ], "facets": { "signature": [ { "term": "nsASDOMWindowEnumerator::GetNext()", "count": 1 }, { "term": "mySignatureIsCool", "count": 1 }, { "term": "mineIsCoolerThanYours", "count": 1 }, { "term": "EMPTY", "count": 1 } ] }, "total": 4 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results elif 'product' in params and 'SeaMonkey' in params['product']: results = { "hits": [ { "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 }, { "signature": "mySignatureIsCool", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 888981 } ], "facets": { "build_id": [ { "term": "888981", "count": 2 } ] }, "total": 2 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results elif ( 'signature' in params and '~nsASDOMWindowEnumerator' in params['signature'] ): results = { "hits": [ { "signature": "nsASDOMWindowEnumerator::GetNext()", "date": "2017-01-31T23:12:57", "uuid": "aaaaaaaaaaaaa", "product": "WaterWolf", "version": "1.0", "platform": "Linux", "build_id": 12345678 } ], "facets": { "signature": [ { "term": "nsASDOMWindowEnumerator::GetNext()", "count": 1 } ] }, "total": 1 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results else: return {"hits": [], "facets": [], "total": 0} SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = reverse('supersearch.search_results') response = self.client.get( url, {'product': 'WaterWolf'} ) eq_(response.status_code, 200) # Test results are existing ok_('table id="reports-list"' in response.content) ok_('nsASDOMWindowEnumerator::GetNext()' in response.content) ok_('mySignatureIsCool' in response.content) ok_('mineIsCoolerThanYours' in response.content) ok_('EMPTY' in response.content) ok_('aaaaaaaaaaaaa1' in response.content) ok_('888981' in response.content) ok_('Linux' in response.content) ok_('2017-01-31 23:12:57' in response.content) # Test facets are existing ok_('table id="facets-list-' in response.content) # Test bugs are existing ok_('<th scope="col">Bugs</th>' in response.content) ok_('123456' in response.content) # Test links on terms are existing ok_('product=%3DWaterWolf' in response.content) # Test with empty results response = self.client.get(url, { 'product': 'NightTrain', 'date': '2012-01-01' }) eq_(response.status_code, 200) ok_('table id="reports-list"' not in response.content) ok_('No results were found' in response.content) # Test with a signature param response = self.client.get( url, {'signature': '~nsASDOMWindowEnumerator'} ) eq_(response.status_code, 200) ok_('table id="reports-list"' in response.content) ok_('nsASDOMWindowEnumerator::GetNext()' in response.content) ok_('123456' in response.content) # Test with a different facet response = self.client.get( url, {'_facets': 'build_id', 'product': 'SeaMonkey'} ) eq_(response.status_code, 200) ok_('table id="reports-list"' in response.content) ok_('table id="facets-list-' in response.content) ok_('888981' in response.content) # Bugs should not be there, they appear only in the signature facet ok_('<th>Bugs</th>' not in response.content) ok_('123456' not in response.content) # Test with a different columns list response = self.client.get( url, {'_columns': ['build_id', 'platform'], 'product': 'WaterWolf'} ) eq_(response.status_code, 200) ok_('table id="reports-list"' in response.content) ok_('table id="facets-list-' in response.content) # The build and platform appear ok_('888981' in response.content) ok_('Linux' in response.content) # The crash id is always shown ok_('aaaaaaaaaaaaa1' in response.content) # The version and date do not appear ok_('1.0' not in response.content) ok_('2017' not in response.content) # Test missing parameters don't raise an exception. response = self.client.get( url, {'product': 'WaterWolf', 'date': '', 'build_id': ''} ) eq_(response.status_code, 200)
def test_topcrashers(self, rpost, bugs_get): def mocked_bugs(**options): return { "hits": [ {"id": 123456789, "signature": "Something"}, {"id": 22222, "signature": u"FakeSignature1 \u7684 Japanese"}, {"id": 33333, "signature": u"FakeSignature1 \u7684 Japanese"} ] } bugs_get.side_effect = mocked_bugs def mocked_sigs(url, **options): if 'signature/first_date' in url: return Response({ "hits": [ { "signature": u"FakeSignature1 \u7684 Japanese", "first_date": "2000-01-01T12:23:34", "first_build": "20000101122334", }, ], "total": 1 }) raise NotImplementedError(url) rpost.side_effect = mocked_sigs def mocked_supersearch_get(**params): if '_columns' not in params: params['_columns'] = [] if 'hang_type' not in params['_aggs.signature']: # Return results for the previous week. results = { 'hits': [], 'facets': { 'signature': [{ 'term': u'FakeSignature1 \u7684 Japanese', 'count': 100, 'facets': { 'platform': [{ 'term': 'WaterWolf', 'count': 50, }], 'is_garbage_collecting': [{ 'term': 't', 'count': 50, }], 'hang_type': [{ 'term': 1, 'count': 50, }], 'process_type': [{ 'term': 'plugin', 'count': 50, }], 'histogram_uptime': [{ 'term': 0, 'count': 40, }], } }] }, 'total': 250 } else: # Return results for the current week. results = { 'hits': [], 'facets': { 'signature': [{ 'term': u'FakeSignature1 \u7684 Japanese', 'count': 100, 'facets': { 'platform': [{ 'term': 'WaterWolf', 'count': 50, }], 'is_garbage_collecting': [{ 'term': 't', 'count': 50, }], 'hang_type': [{ 'term': 1, 'count': 50, }], 'process_type': [{ 'term': 'plugin', 'count': 50, }], 'histogram_uptime': [{ 'term': 0, 'count': 60, }], } }, { 'term': u'mozCool()', 'count': 80, 'facets': { 'platform': [{ 'term': 'WaterWolf', 'count': 50, }], 'is_garbage_collecting': [{ 'term': 't', 'count': 50, }], 'hang_type': [{ 'term': 1, 'count': 50, }], 'process_type': [{ 'term': 'browser', 'count': 50, }], 'histogram_uptime': [{ 'term': 0, 'count': 40, }], } }] }, 'total': 250 } results['hits'] = self.only_certain_columns( results['hits'], params['_columns'] ) return results SuperSearchUnredacted.implementation().get.side_effect = ( mocked_supersearch_get ) url = self.base_url + '?product=WaterWolf&version=19.0' response = self.client.get(self.base_url, {'product': 'WaterWolf'}) ok_(url in response['Location']) # Test that several versions do not raise an error. response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0;20.0', }) eq_(response.status_code, 200) response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', }) eq_(response.status_code, 200) doc = pyquery.PyQuery(response.content) selected_count = doc('.tc-result-count a[class="selected"]') eq_(selected_count.text(), '50') # there's actually only one such TD bug_ids = [x.text for x in doc('td.bug_ids_more > a')] # higher bug number first eq_(bug_ids, ['33333', '22222']) # Check the first appearance date is there. ok_('2000-01-01 12:23:34' in response.content) response = self.client.get(self.base_url, { 'product': 'WaterWolf', 'version': '19.0', '_facets_size': '100', }) eq_(response.status_code, 200) doc = pyquery.PyQuery(response.content) selected_count = doc('.tc-result-count a[class="selected"]') eq_(selected_count.text(), '100') # Check the startup crash icon is there. ok_('Startup Crash' in response.content)