@@ -292,7 +292,7 @@ def test_run(self, incr_mock):
292292 assert narc_result .results == [
293293 {
294294 'meta' : {
295- 'is_normalized ' : True ,
295+ 'variant ' : 'normalized' ,
296296 'locale' : 'en-us' ,
297297 'pattern' : '.*' ,
298298 'source' : 'db_addon' ,
@@ -307,44 +307,44 @@ def test_run(self, incr_mock):
307307 },
308308 {
309309 'meta' : {
310- 'is_normalized' : True ,
311- 'locale' : None ,
310+ 'locale' : 'en-us' ,
312311 'pattern' : '.*' ,
313- 'source' : 'author ' ,
312+ 'source' : 'db_addon ' ,
314313 'span' : [
315314 0 ,
316- 3 ,
315+ 27 ,
317316 ],
318- 'string' : 'Foo' ,
319- 'original_string' : 'Fôo' ,
317+ 'string' : 'My Fancy WebExtension Addon' ,
320318 },
321319 'rule' : 'always_match_rule' ,
322320 },
323321 {
324322 'meta' : {
325- 'is_normalized ' : True ,
323+ 'variant ' : 'normalized' ,
326324 'locale' : None ,
327325 'pattern' : '.*' ,
328- 'source' : 'xpi ' ,
326+ 'source' : 'author ' ,
329327 'span' : [
330328 0 ,
331- 19 ,
329+ 3 ,
332330 ],
333- 'string' : 'MyWebExtensionAddon ' ,
334- 'original_string' : 'My WebExtension Addon ' ,
331+ 'string' : 'Foo ' ,
332+ 'original_string' : 'Fôo ' ,
335333 },
336334 'rule' : 'always_match_rule' ,
337335 },
338336 {
339337 'meta' : {
340- 'locale' : 'en-us' ,
338+ 'variant' : 'normalized' ,
339+ 'locale' : None ,
341340 'pattern' : '.*' ,
342- 'source' : 'db_addon ' ,
341+ 'source' : 'xpi ' ,
343342 'span' : [
344343 0 ,
345- 27 ,
344+ 19 ,
346345 ],
347- 'string' : 'My Fancy WebExtension Addon' ,
346+ 'string' : 'MyWebExtensionAddon' ,
347+ 'original_string' : 'My WebExtension Addon' ,
348348 },
349349 'rule' : 'always_match_rule' ,
350350 },
@@ -379,6 +379,104 @@ def test_run(self, incr_mock):
379379 ]
380380 )
381381
382+ @mock .patch ('olympia.scanners.tasks.statsd.incr' )
383+ def test_run_normalized_match (self , incr_mock ):
384+ self .addon .name = 'My\u2800 Fäncy WebExtension 𝕒ddon'
385+ self .addon .save ()
386+
387+ rule = ScannerRule .objects .create (
388+ name = 'always_match_rule' ,
389+ scanner = NARC ,
390+ definition = 'MyFancyWebExtensionAddon' ,
391+ )
392+
393+ run_narc_on_version (self .version .pk )
394+
395+ scanner_results = ScannerResult .objects .all ()
396+ assert len (scanner_results ) == 1
397+ narc_result = scanner_results [0 ]
398+ assert narc_result .scanner == NARC
399+ assert narc_result .upload is None
400+ assert narc_result .version == self .version
401+ assert narc_result .has_matches
402+ assert list (narc_result .matched_rules .all ()) == [rule ]
403+ assert len (narc_result .results ) == 1
404+ assert narc_result .results == [
405+ {
406+ 'meta' : {
407+ 'locale' : 'en-us' ,
408+ 'original_string' : 'My⠀ Fäncy WebExtension 𝕒ddon' ,
409+ 'pattern' : 'MyFancyWebExtensionAddon' ,
410+ 'source' : 'db_addon' ,
411+ 'span' : [
412+ 0 ,
413+ 24 ,
414+ ],
415+ 'string' : 'MyFancyWebExtensionaddon' ,
416+ 'variant' : 'normalized' ,
417+ },
418+ 'rule' : 'always_match_rule' ,
419+ },
420+ ]
421+ assert incr_mock .called
422+ assert incr_mock .call_count == 3
423+ incr_mock .assert_has_calls (
424+ [
425+ mock .call ('devhub.narc.has_matches' ),
426+ mock .call (f'devhub.narc.rule.{ rule .id } .match' ),
427+ mock .call ('devhub.narc.success' ),
428+ ]
429+ )
430+
431+ @mock .patch ('olympia.scanners.tasks.statsd.incr' )
432+ def test_run_homoglyph_match (self , incr_mock ):
433+ self .addon .name = 'My\u2800 Fäncy W\u0435 bExtѐnsion addon'
434+ self .addon .save ()
435+
436+ rule = ScannerRule .objects .create (
437+ name = 'always_match_rule' ,
438+ scanner = NARC ,
439+ definition = 'MyFancyWebExtensionAddon' ,
440+ )
441+
442+ run_narc_on_version (self .version .pk )
443+
444+ scanner_results = ScannerResult .objects .all ()
445+ assert len (scanner_results ) == 1
446+ narc_result = scanner_results [0 ]
447+ assert narc_result .scanner == NARC
448+ assert narc_result .upload is None
449+ assert narc_result .version == self .version
450+ assert narc_result .has_matches
451+ assert list (narc_result .matched_rules .all ()) == [rule ]
452+ assert len (narc_result .results ) == 1
453+ assert narc_result .results == [
454+ {
455+ 'meta' : {
456+ 'locale' : 'en-us' ,
457+ 'original_string' : 'My⠀ Fäncy WеbExtѐnsion addon' ,
458+ 'pattern' : 'MyFancyWebExtensionAddon' ,
459+ 'source' : 'db_addon' ,
460+ 'span' : [
461+ 0 ,
462+ 24 ,
463+ ],
464+ 'string' : 'myfancywebextensionaddon' ,
465+ 'variant' : 'homoglyph' ,
466+ },
467+ 'rule' : 'always_match_rule' ,
468+ },
469+ ]
470+ assert incr_mock .called
471+ assert incr_mock .call_count == 3
472+ incr_mock .assert_has_calls (
473+ [
474+ mock .call ('devhub.narc.has_matches' ),
475+ mock .call (f'devhub.narc.rule.{ rule .id } .match' ),
476+ mock .call ('devhub.narc.success' ),
477+ ]
478+ )
479+
382480 @mock .patch ('olympia.scanners.tasks.statsd.timer' )
383481 def test_calls_statsd_timer (self , timer_mock ):
384482 run_narc_on_version (self .version .pk )
@@ -515,7 +613,7 @@ def test_run_multiple_authors_match(self, incr_mock):
515613 assert narc_result .results == [
516614 {
517615 'meta' : {
518- 'is_normalized ' : True ,
616+ 'variant ' : 'normalized' ,
519617 'span' : [0 , 3 ],
520618 'locale' : None ,
521619 'source' : 'author' ,
0 commit comments