Highlight versions to be reviewed for MAD (#14936)

This commit is contained in:
William Durand 2020-07-15 11:15:54 +02:00 коммит произвёл GitHub
Родитель cbb65e4453
Коммит 1fbae3c94f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 173 добавлений и 84 удалений

Просмотреть файл

@ -28,7 +28,9 @@
{% endfor %}
</ol>
{% if versions_flagged_by_scanners_other %}
<strong class="other-needs-human-review risk-high">{{ _('{num} versions flagged by scanners on other pages.')|format_html(num=versions_flagged_by_scanners_other) }}</strong>
<strong class="other-flagged-by-scanners risk-high">{{ _('{num} versions flagged by scanners on other pages.')|format_html(num=versions_flagged_by_scanners_other) }}</strong>
{% elif versions_flagged_for_human_review_other %}
<strong class="other-flagged-for-human-review risk-medium">{{ _('{num} versions flagged for human review on other pages.')|format_html(num=versions_flagged_for_human_review_other) }}</strong>
{% endif %}
{% if versions_pending_rejection_other %}
<strong class="other-pending-rejection risk-high">{{ _('{num} versions pending rejection on other pages.')|format_html(num=versions_pending_rejection_other) }}</strong>

Просмотреть файл

@ -1,4 +1,4 @@
<tr class="listing-header {% if version.needs_human_review %}needs-human-review{% endif %}">
<tr class="listing-header{% if version.needs_human_review %} flagged-by-scanners{% elif version.needs_human_review_by_mad %} flagged-for-human-review{%endif %}">
<th colspan="2">
{% trans version = version.version, created = version.created|date, version_status = version_status(addon, version) %}
Version {{ version }} &middot; {{ created }} <span class="light">&middot; {{ version_status }}</span>
@ -46,7 +46,9 @@
<div class="file-weight" title="{{ version.autoapprovalsummary.get_pretty_weight_info()|join('\n') }}"><strong>{{ _('Weight:') }}</strong> {{ version.autoapprovalsummary.weight }}</div>
{% endif %}
{% if version.needs_human_review %}
<div><strong class="risk-high">{{ _('Flagged by automated scanners') }}</strong></div>
<div><strong class="risk-high">{{ _('Flagged by scanners') }}</strong></div>
{% elif version.needs_human_review_by_mad %}
<div><strong class="risk-medium">{{ _('Flagged for human review') }}</strong></div>
{% endif %}
{% else %}
<ul>

Просмотреть файл

@ -5397,7 +5397,7 @@ class TestReview(ReviewBase):
assert response.status_code == 200
assert b'Previously deleted entries' not in response.content
def test_versions_that_needs_human_review_are_highlighted(self):
def test_versions_that_are_flagged_by_scanners_are_highlighted(self):
self.addon.current_version.update(created=self.days_ago(366))
for i in range(0, 10):
# Add versions 1.0 to 1.9. Flag a few of them as needing human
@ -5415,10 +5415,10 @@ class TestReview(ReviewBase):
# Original version should not be there any more, it's on the second
# page. Versions on the page should be displayed in chronological order
# Versions 1.0, 1.3, 1.6, 1.9 are flagged for human review.
assert 'Flagged by automated scanners' in tds.eq(0).text()
assert 'Flagged by automated scanners' in tds.eq(3).text()
assert 'Flagged by automated scanners' in tds.eq(6).text()
assert 'Flagged by automated scanners' in tds.eq(9).text()
assert 'Flagged by scanners' in tds.eq(0).text()
assert 'Flagged by scanners' in tds.eq(3).text()
assert 'Flagged by scanners' in tds.eq(6).text()
assert 'Flagged by scanners' in tds.eq(9).text()
# There are no other flagged versions in the other page.
span = doc('#review-files-header .risk-high')
@ -5433,6 +5433,48 @@ class TestReview(ReviewBase):
assert span.length == 1
assert span.text() == '4 versions flagged by scanners on other pages.'
def test_versions_that_needs_human_review_are_highlighted(self):
self.addon.current_version.update(created=self.days_ago(366))
for i in range(0, 10):
# Add versions 1.0 to 1.9. Flag a few of them as needing human
# review.
version = version_factory(
addon=self.addon,
version=f'1.{i}',
created=self.days_ago(365 - i)
)
VersionReviewerFlags.objects.create(
version=version,
needs_human_review_by_mad=not bool(i % 3)
)
response = self.client.get(self.url)
assert response.status_code == 200
doc = pq(response.content)
tds = doc('#versions-history .review-files td.files')
assert tds.length == 10
# Original version should not be there any more, it's on the second
# page. Versions on the page should be displayed in chronological order
# Versions 1.0, 1.3, 1.6, 1.9 are flagged for human review.
assert 'Flagged for human review' in tds.eq(0).text()
assert 'Flagged for human review' in tds.eq(3).text()
assert 'Flagged for human review' in tds.eq(6).text()
assert 'Flagged for human review' in tds.eq(9).text()
# There are no other flagged versions in the other page.
span = doc('#review-files-header .risk-medium')
assert span.length == 0
# Load the second page. This time there should be a message indicating
# there are flagged versions in other pages.
response = self.client.get(self.url, {'page': 2})
assert response.status_code == 200
doc = pq(response.content)
span = doc('#review-files-header .risk-medium')
assert span.length == 1
assert (span.text() ==
'4 versions flagged for human review on other pages.')
def test_blocked_versions(self):
response = self.client.get(self.url)
assert response.status_code == 200

Просмотреть файл

@ -881,6 +881,9 @@ def review(request, addon, channel=None):
# paginated).
versions_flagged_by_scanners_other = versions_qs.filter(
needs_human_review=True).exclude(pk__in=version_ids).count()
versions_flagged_for_human_review_other = versions_qs.filter(
reviewerflags__needs_human_review_by_mad=True
).exclude(pk__in=version_ids).count()
versions_pending_rejection_other = versions_pending_rejection_qs.exclude(
pk__in=version_ids).count()
@ -937,6 +940,7 @@ def review(request, addon, channel=None):
user_ratings=user_ratings,
version=version,
versions_flagged_by_scanners_other=versions_flagged_by_scanners_other,
versions_flagged_for_human_review_other=versions_flagged_for_human_review_other, # noqa
versions_pending_rejection_other=versions_pending_rejection_other,
whiteboard_form=whiteboard_form,
whiteboard_url=whiteboard_url,

Просмотреть файл

@ -704,6 +704,13 @@ class Version(OnChangeMixin, ModelBase):
except VersionReviewerFlags.DoesNotExist:
return None
@property
def needs_human_review_by_mad(self):
try:
return self.reviewerflags.needs_human_review_by_mad
except VersionReviewerFlags.DoesNotExist:
return False
class VersionReviewerFlags(ModelBase):
version = models.OneToOneField(

Просмотреть файл

@ -670,6 +670,18 @@ class TestVersion(TestCase):
flags.update(pending_rejection=in_the_past)
assert version.pending_rejection == in_the_past
def test_needs_human_review_by_mad(self):
addon = Addon.objects.get(id=3615)
version = addon.current_version
# No flags: False
assert not version.needs_human_review_by_mad
# Flag present, value is None (default): False.
flags = VersionReviewerFlags.objects.create(version=version)
assert not version.needs_human_review_by_mad
# Flag present.
flags.update(needs_human_review_by_mad=True)
assert version.needs_human_review_by_mad
@pytest.mark.parametrize("addon_status,file_status,is_unreviewed", [
(amo.STATUS_NOMINATED, amo.STATUS_AWAITING_REVIEW, True),

Просмотреть файл

@ -1,3 +1,6 @@
@flagged-by-scanners-color: orange;
@flagged-for-human-review-color: green;
.site-title {
padding-top: 27px;
max-width: 530px;
@ -153,11 +156,11 @@ table.data-grid tr th a:visited {
}
table.data-grid tr th.ordered {
background: -webkit-gradient(
linear,
left bottom,
left top,
from(#FFFFFF),
to(#BCE0FF)
linear,
left bottom,
left top,
from(#FFFFFF),
to(#BCE0FF)
);
background: linear-gradient(#FFFFFF, #BCE0FF);
}
@ -559,11 +562,11 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
font-weight: normal;
}
.log-filter-outside input::-webkit-input-placeholder {
color: #BBB;
color: #BBB;
}
.log-filter-outside input:-moz-placeholder {
color: #BBB;
color: #BBB;
}
.log-filter-outside div.date_range {
@ -648,7 +651,7 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
}
.scroll_sidebar_parent #scroll_sidebar li a {
font-weight: normal;
font-weight: normal;
}
#scroll_sidebar {
@ -702,8 +705,8 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
width: 100%;
}
.review-files table.activity th {
width: 25%;
padding-right: 1em;
width: 25%;
padding-right: 1em;
}
.review-files table.activity tr {
border-top: 1px dotted #ccc;
@ -713,33 +716,50 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
}
.review-files .listing-header span.light {
font-weight: normal;
color: #999;
color: #000;
}
.review-files tr.listing-header:first-child {
border-top: none;
}
.review-files tr.listing-header {
border-top: 1px solid #A5BFCE;
border-top: 1px solid #A5BFCE;
}
.review-files tr.listing-header.needs-human-review {
background-color: #ffeec5;
border-top: 1px solid #fede94;
.review-files tr.listing-header.flagged-by-scanners {
background-color: lighten(@flagged-by-scanners-color, 20%);
border-top: 1px solid lighten(@flagged-by-scanners-color, 5%);
&:hover {
background: linear-gradient(lighten(@flagged-by-scanners-color, 20%), @flagged-by-scanners-color);
}
&:active {
background: linear-gradient(@flagged-by-scanners-color, lighten(@flagged-by-scanners-color, 20%));
}
}
.review-files tr.listing-header.needs-human-review:hover {
background: linear-gradient(#FFFFFF, #ffcf5d);
}
.review-files tr.listing-header.needs-human-review:active {
background: linear-gradient(#ffcf5d, #FFF);
.review-files tr.listing-header.flagged-for-human-review {
background-color: lighten(@flagged-for-human-review-color, 20%);
border-top: 1px solid lighten(@flagged-for-human-review-color, 5%);
&:hover {
background: linear-gradient(lighten(@flagged-for-human-review-color, 20%), @flagged-for-human-review-color);
}
&:active {
background: linear-gradient(@flagged-for-human-review-color, lighten(@flagged-for-human-review-color, 20%));
}
}
.review-files tr.listing-header:hover {
cursor: pointer;
background-color: #CCE6FF;
background: -webkit-gradient(
linear,
left bottom,
left top,
from(#FFFFFF),
to(#CCE6FF)
linear,
left bottom,
left top,
from(#FFFFFF),
to(#CCE6FF)
);
background: linear-gradient(#FFFFFF, #CCE6FF);
}
@ -747,11 +767,11 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
cursor: pointer;
background-color: #FFF;
background: -webkit-gradient(
linear,
left bottom,
left top,
from(#CCE6FF),
to(#FFFFFF)
linear,
left bottom,
left top,
from(#CCE6FF),
to(#FFFFFF)
);
background: linear-gradient(#E0EFFD, #FFF);
}
@ -1006,21 +1026,21 @@ span.currently_viewing_warning {
.paginator {
margin: 0pt;
overflow: auto;
margin: 0pt;
overflow: auto;
}
.paginator li {
float: left;
width: 33%;
float: left;
width: 33%;
}
.paginator .next {
text-align: right;
text-align: right;
}
.paginator .page {
text-align: center;
text-align: center;
}
h2.addon {
@ -1036,24 +1056,24 @@ p.is_recommendable {
}
#reviewers-score-bar {
background: #FCFDFE;
background-image: -webkit-gradient(linear, left bottom, left top, from(#fcfdfe), to(#f4f8fc));
background-image: linear-gradient(#fcfdfe, #f4f8fc);
background-image: -webkit-linear-gradient(#fcfdfe, #f4f8fc);
border: 1px solid #c9ddf2;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
-webkit-box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
display: block;
margin-bottom: 15px;
padding: 14px 14px 16px;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: #FCFDFE;
background-image: -webkit-gradient(linear, left bottom, left top, from(#fcfdfe), to(#f4f8fc));
background-image: linear-gradient(#fcfdfe, #f4f8fc);
background-image: -webkit-linear-gradient(#fcfdfe, #f4f8fc);
border: 1px solid #c9ddf2;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
-webkit-box-shadow: 0 -2px 0 rgba(204, 223, 243, 0.3) inset, 0 0 1px rgba(0, 0, 0, 0.1);
display: block;
margin-bottom: 15px;
padding: 14px 14px 16px;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#reviewers-score-bar p.total {
@ -1118,8 +1138,8 @@ p.is_recommendable {
-webkit-border-radius: 7px;
border-radius: 7px;
&.private {
background-color: #FFE4E4;
margin: 1em 0 1em 0;
background-color: #FFE4E4;
margin: 1em 0 1em 0;
}
.whiteboard-inner {
padding: 10px;
@ -1148,7 +1168,7 @@ p.is_recommendable {
}
li {
margin: 0 0 1em 0;
margin: 0 0 1em 0;
}
#force_disable_addon, #force_enable_addon,
@ -1172,28 +1192,28 @@ p.is_recommendable {
}
#addon-theme-previews-wrapper {
.all-backgrounds {
.background {
display: block;
height: 100px;
margin: 13px 0;
border: 2px solid #C9DDF2;
background: rgba(201,221,242,.1);
}
.zoombox {
overflow: hidden;
position: relative;
.all-backgrounds {
.background {
display: block;
height: 100px;
margin: 13px 0;
border: 2px solid #C9DDF2;
background: rgba(201,221,242,.1);
}
.zoombox {
overflow: hidden;
position: relative;
img {
position: absolute;
right: 0;
}
span {
position: absolute;
background-color: rgba(255,255,255,.75);
img {
position: absolute;
right: 0;
}
span {
position: absolute;
background-color: rgba(255,255,255,.75);
}
}
}
}
}
table.abuse_reports {