mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Remove repository review functionality from tool shed.
This commit is contained in:
@@ -1,535 +0,0 @@
|
||||
import logging
|
||||
|
||||
from markupsafe import escape
|
||||
from sqlalchemy import (
|
||||
and_,
|
||||
false,
|
||||
null,
|
||||
or_,
|
||||
true,
|
||||
)
|
||||
|
||||
from galaxy.web.legacy_framework import grids
|
||||
from tool_shed.grids.repository_grids import RepositoryGrid
|
||||
from tool_shed.util import (
|
||||
hg_util,
|
||||
metadata_util,
|
||||
)
|
||||
from tool_shed.webapp import model
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ComponentGrid(grids.Grid):
|
||||
class NameColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, component):
|
||||
return escape(component.name)
|
||||
|
||||
class DescriptionColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, component):
|
||||
return escape(component.description)
|
||||
|
||||
title = "Repository review components"
|
||||
model_class = model.Component
|
||||
template = "/webapps/tool_shed/repository_review/grid.mako"
|
||||
default_sort_key = "name"
|
||||
use_hide_message = False
|
||||
columns = [
|
||||
NameColumn(
|
||||
"Name", key="Component.name", link=(lambda item: dict(operation="edit", id=item.id)), attach_popup=False
|
||||
),
|
||||
DescriptionColumn("Description", key="Component.description", attach_popup=False),
|
||||
]
|
||||
global_actions = [
|
||||
grids.GridAction(
|
||||
"Add new component", dict(controller="repository_review", action="manage_components", operation="create")
|
||||
)
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
|
||||
|
||||
class RepositoriesWithReviewsGrid(RepositoryGrid):
|
||||
# This grid filters out repositories that have been marked as either deprecated or deleted.
|
||||
|
||||
class WithReviewsRevisionColumn(grids.GridColumn):
|
||||
def get_value(self, trans, grid, repository):
|
||||
# Restrict to revisions that have been reviewed.
|
||||
if repository.reviews:
|
||||
rval = ""
|
||||
repo = repository.hg_repo
|
||||
for review in repository.reviews:
|
||||
changeset_revision = review.changeset_revision
|
||||
rev, label = hg_util.get_rev_label_from_changeset_revision(repo, changeset_revision)
|
||||
rval += (
|
||||
'<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>'
|
||||
% (trans.security.encode_id(repository.id), changeset_revision, label)
|
||||
)
|
||||
return rval
|
||||
return ""
|
||||
|
||||
class WithoutReviewsRevisionColumn(grids.GridColumn):
|
||||
def get_value(self, trans, grid, repository):
|
||||
# Restrict the options to revisions that have not yet been reviewed.
|
||||
repository_metadata_revisions = metadata_util.get_repository_metadata_revisions_for_review(
|
||||
repository, reviewed=False
|
||||
)
|
||||
if repository_metadata_revisions:
|
||||
rval = ""
|
||||
for repository_metadata in repository_metadata_revisions:
|
||||
rev, label, changeset_revision = hg_util.get_rev_label_changeset_revision_from_repository_metadata(
|
||||
trans.app, repository_metadata, repository=repository, include_date=True, include_hash=False
|
||||
)
|
||||
rval += (
|
||||
'<a href="manage_repository_reviews_of_revision?id=%s&changeset_revision=%s">%s</a><br/>'
|
||||
% (trans.security.encode_id(repository.id), changeset_revision, label)
|
||||
)
|
||||
return rval
|
||||
return ""
|
||||
|
||||
class ReviewersColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, repository):
|
||||
rval = ""
|
||||
if repository.reviewers:
|
||||
for user in repository.reviewers:
|
||||
rval += f'<a class="view-info" href="repository_reviews_by_user?id={trans.security.encode_id(user.id)}">'
|
||||
rval += f"{user.username}</a> | "
|
||||
if rval[-3:] == " | ":
|
||||
rval = rval[:-3]
|
||||
return rval
|
||||
|
||||
class RatingColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, repository):
|
||||
rval = ""
|
||||
for review in repository.reviews:
|
||||
if review.rating:
|
||||
for index in range(1, 6):
|
||||
rval += "<input "
|
||||
rval += f'name="star1-{trans.security.encode_id(review.id)}" '
|
||||
rval += 'type="radio" '
|
||||
rval += 'class="community_rating_star star" '
|
||||
rval += 'disabled="disabled" '
|
||||
rval += f'value="{str(review.rating)}" '
|
||||
if review.rating > (index - 0.5) and review.rating < (index + 0.5):
|
||||
rval += 'checked="checked" '
|
||||
rval += "/>"
|
||||
rval += "<br/>"
|
||||
return rval
|
||||
|
||||
class ApprovedColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, repository):
|
||||
rval = ""
|
||||
for review in repository.reviews:
|
||||
if review.approved:
|
||||
rval += f"{review.approved}<br/>"
|
||||
return rval
|
||||
|
||||
title = "All reviewed repositories"
|
||||
model_class = model.Repository
|
||||
template = "/webapps/tool_shed/repository_review/grid.mako"
|
||||
default_sort_key = "Repository.name"
|
||||
columns = [
|
||||
RepositoryGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoryGrid.UserColumn("Owner", model_class=model.User, attach_popup=False, key="User.username"),
|
||||
WithReviewsRevisionColumn("Reviewed revisions"),
|
||||
ReviewersColumn("Reviewers", attach_popup=False),
|
||||
RatingColumn("Rating", attach_popup=False),
|
||||
ApprovedColumn("Approved", attach_popup=False),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name",
|
||||
cols_to_filter=[columns[0]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.filter(and_(model.Repository.table.c.deleted == false(), model.Repository.table.c.deprecated == false()))
|
||||
.join(
|
||||
(
|
||||
model.RepositoryReview.table,
|
||||
model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id,
|
||||
)
|
||||
)
|
||||
.join((model.User.table, model.User.table.c.id == model.Repository.table.c.user_id))
|
||||
.outerjoin(
|
||||
(
|
||||
model.ComponentReview.table,
|
||||
model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id,
|
||||
)
|
||||
)
|
||||
.outerjoin(
|
||||
(model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RepositoriesWithoutReviewsGrid(RepositoriesWithReviewsGrid):
|
||||
# This grid filters out repositories that have been marked as either deprecated or deleted.
|
||||
title = "Repositories with no reviews"
|
||||
columns = [
|
||||
RepositoriesWithReviewsGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoriesWithReviewsGrid.DescriptionColumn("Synopsis", key="description", attach_popup=False),
|
||||
RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn("Revisions for review"),
|
||||
RepositoriesWithReviewsGrid.UserColumn(
|
||||
"Owner", model_class=model.User, attach_popup=False, key="User.username"
|
||||
),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name, description",
|
||||
cols_to_filter=[columns[0], columns[1]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.filter(
|
||||
and_(
|
||||
model.Repository.table.c.deleted == false(),
|
||||
model.Repository.table.c.deprecated == false(),
|
||||
model.Repository.reviews == null(),
|
||||
)
|
||||
)
|
||||
.join(model.User.table)
|
||||
)
|
||||
|
||||
|
||||
class RepositoriesReadyForReviewGrid(RepositoriesWithoutReviewsGrid):
|
||||
# Repositories that are ready for human review are those that either:
|
||||
# 1) Have no tools
|
||||
# 2) Have tools that have been proven to be functionally correct within Galaxy.
|
||||
# This grid filters out repositories that have been marked as either deprecated or deleted.
|
||||
title = "Repositories ready for review"
|
||||
columns = [
|
||||
RepositoriesWithoutReviewsGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoriesWithoutReviewsGrid.DescriptionColumn("Synopsis", key="description", attach_popup=False),
|
||||
RepositoriesWithoutReviewsGrid.WithoutReviewsRevisionColumn("Revisions for review"),
|
||||
RepositoriesWithoutReviewsGrid.UserColumn(
|
||||
"Owner", model_class=model.User, attach_popup=False, key="User.username"
|
||||
),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name, description",
|
||||
cols_to_filter=[columns[0], columns[1]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.filter(
|
||||
and_(
|
||||
model.Repository.table.c.deleted == false(),
|
||||
model.Repository.table.c.deprecated == false(),
|
||||
model.Repository.reviews == null(),
|
||||
)
|
||||
)
|
||||
.join(model.RepositoryMetadata.table)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryMetadata.table.c.downloadable == true(),
|
||||
or_(
|
||||
model.RepositoryMetadata.table.c.includes_tools == false(),
|
||||
and_(
|
||||
model.RepositoryMetadata.table.c.includes_tools == true(),
|
||||
model.RepositoryMetadata.table.c.tools_functionally_correct == true(),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
.join(model.User.table)
|
||||
)
|
||||
|
||||
|
||||
class RepositoriesReviewedByMeGrid(RepositoriesWithReviewsGrid):
|
||||
# This grid filters out repositories that have been marked as either deprecated or deleted.
|
||||
|
||||
columns = [
|
||||
RepositoriesWithReviewsGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoriesWithReviewsGrid.UserColumn("Owner", attach_popup=False),
|
||||
RepositoriesWithReviewsGrid.WithReviewsRevisionColumn("Reviewed revisions"),
|
||||
RepositoriesWithReviewsGrid.ReviewersColumn("Reviewers", attach_popup=False),
|
||||
RepositoriesWithReviewsGrid.RatingColumn("Rating", attach_popup=False),
|
||||
RepositoriesWithReviewsGrid.ApprovedColumn("Approved", attach_popup=False),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name",
|
||||
cols_to_filter=[columns[0]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.filter(and_(model.Repository.table.c.deleted == false(), model.Repository.table.c.deprecated == false()))
|
||||
.join(
|
||||
(
|
||||
model.RepositoryReview.table,
|
||||
model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id,
|
||||
)
|
||||
)
|
||||
.filter(model.RepositoryReview.table.c.user_id == trans.user.id)
|
||||
.join((model.User.table, model.User.table.c.id == model.RepositoryReview.table.c.user_id))
|
||||
.outerjoin(
|
||||
(
|
||||
model.ComponentReview.table,
|
||||
model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id,
|
||||
)
|
||||
)
|
||||
.outerjoin(
|
||||
(model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RepositoryReviewsByUserGrid(grids.Grid):
|
||||
# This grid filters out repositories that have been marked as deprecated.
|
||||
|
||||
class RepositoryNameColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, review):
|
||||
return escape(review.repository.name)
|
||||
|
||||
class RepositoryDescriptionColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, review):
|
||||
return escape(review.repository.description)
|
||||
|
||||
class RevisionColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, review):
|
||||
encoded_review_id = trans.security.encode_id(review.id)
|
||||
rval = '<a class="action-button" href="'
|
||||
if review.user == trans.user:
|
||||
rval += "edit_review"
|
||||
else:
|
||||
rval += "browse_review"
|
||||
revision_label = hg_util.get_revision_label(
|
||||
trans.app, review.repository, review.changeset_revision, include_date=True, include_hash=False
|
||||
)
|
||||
rval += f'?id={encoded_review_id}">{revision_label}</a>'
|
||||
return rval
|
||||
|
||||
class RatingColumn(grids.TextColumn):
|
||||
def get_value(self, trans, grid, review):
|
||||
if review.rating:
|
||||
for index in range(1, 6):
|
||||
rval = "<input "
|
||||
rval += f'name="star1-{trans.security.encode_id(review.id)}" '
|
||||
rval += 'type="radio" '
|
||||
rval += 'class="community_rating_star star" '
|
||||
rval += 'disabled="disabled" '
|
||||
rval += f'value="{str(review.rating)}" '
|
||||
if review.rating > (index - 0.5) and review.rating < (index + 0.5):
|
||||
rval += 'checked="checked" '
|
||||
rval += "/>"
|
||||
return rval
|
||||
return ""
|
||||
|
||||
title = "Reviews by user"
|
||||
model_class = model.RepositoryReview
|
||||
template = "/webapps/tool_shed/repository_review/grid.mako"
|
||||
default_sort_key = "repository_id"
|
||||
use_hide_message = False
|
||||
columns = [
|
||||
RepositoryNameColumn(
|
||||
"Repository Name",
|
||||
model_class=model.Repository,
|
||||
key="Repository.name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoryDescriptionColumn(
|
||||
"Description", model_class=model.Repository, key="Repository.description", attach_popup=False
|
||||
),
|
||||
RevisionColumn("Revision", attach_popup=False),
|
||||
RatingColumn("Rating", attach_popup=False),
|
||||
]
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
user_id = trans.security.decode_id(kwd["id"])
|
||||
return (
|
||||
trans.sa_session.query(model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryReview.table.c.deleted == false(), model.RepositoryReview.table.c.user_id == user_id
|
||||
)
|
||||
)
|
||||
.join((model.Repository.table, model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id))
|
||||
.filter(model.Repository.table.c.deprecated == false())
|
||||
)
|
||||
|
||||
|
||||
class ReviewedRepositoriesIOwnGrid(RepositoriesWithReviewsGrid):
|
||||
title = "Reviewed repositories I own"
|
||||
columns = [
|
||||
RepositoriesWithReviewsGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoriesWithReviewsGrid.WithReviewsRevisionColumn("Reviewed revisions"),
|
||||
RepositoriesWithReviewsGrid.WithoutReviewsRevisionColumn("Revisions for review"),
|
||||
RepositoriesWithReviewsGrid.ReviewersColumn("Reviewers", attach_popup=False),
|
||||
RepositoryGrid.DeprecatedColumn("Deprecated"),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name",
|
||||
cols_to_filter=[columns[0]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.join(
|
||||
(
|
||||
model.RepositoryReview.table,
|
||||
model.RepositoryReview.table.c.repository_id == model.Repository.table.c.id,
|
||||
)
|
||||
)
|
||||
.filter(model.Repository.table.c.user_id == trans.user.id)
|
||||
.join((model.User.table, model.User.table.c.id == model.RepositoryReview.table.c.user_id))
|
||||
.outerjoin(
|
||||
(
|
||||
model.ComponentReview.table,
|
||||
model.ComponentReview.table.c.repository_review_id == model.RepositoryReview.table.c.id,
|
||||
)
|
||||
)
|
||||
.outerjoin(
|
||||
(model.Component.table, model.Component.table.c.id == model.ComponentReview.table.c.component_id)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class RepositoriesWithNoToolTestsGrid(RepositoriesWithoutReviewsGrid):
|
||||
# Repositories that are ready for human review are those that either:
|
||||
# 1) Have no tools
|
||||
# 2) Have tools that have been proven to be functionally correct within Galaxy.
|
||||
# This grid filters out repositories that have been marked as either deprecated or deleted.
|
||||
title = "Repositories that contain tools with no tests or test data"
|
||||
columns = [
|
||||
RepositoriesWithoutReviewsGrid.NameColumn(
|
||||
"Repository name",
|
||||
key="name",
|
||||
link=(lambda item: dict(operation="view_or_manage_repository", id=item.id)),
|
||||
attach_popup=True,
|
||||
),
|
||||
RepositoriesWithoutReviewsGrid.DescriptionColumn("Synopsis", key="description", attach_popup=False),
|
||||
RepositoriesWithoutReviewsGrid.WithoutReviewsRevisionColumn("Revisions for review"),
|
||||
RepositoriesWithoutReviewsGrid.UserColumn(
|
||||
"Owner", model_class=model.User, attach_popup=False, key="User.username"
|
||||
),
|
||||
]
|
||||
columns.append(
|
||||
grids.MulticolFilterColumn(
|
||||
"Search repository name, description",
|
||||
cols_to_filter=[columns[0], columns[1]],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
filterable="standard",
|
||||
)
|
||||
)
|
||||
operations = [
|
||||
grids.GridOperation(
|
||||
"Inspect repository revisions",
|
||||
allow_multiple=False,
|
||||
condition=(lambda item: not item.deleted),
|
||||
async_compatible=False,
|
||||
)
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
return (
|
||||
trans.sa_session.query(model.Repository)
|
||||
.filter(and_(model.Repository.table.c.deleted == false(), model.Repository.table.c.deprecated == false()))
|
||||
.join(model.RepositoryMetadata.table)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryMetadata.table.c.downloadable == true(),
|
||||
model.RepositoryMetadata.table.c.includes_tools == true(),
|
||||
model.RepositoryMetadata.table.c.tools_functionally_correct == false(),
|
||||
)
|
||||
)
|
||||
.join(model.User.table)
|
||||
)
|
||||
@@ -9,24 +9,12 @@ from tool_shed.util import (
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build_approved_select_field(trans, name, selected_value=None, for_component=True):
|
||||
options = [
|
||||
("No", trans.model.ComponentReview.approved_states.NO),
|
||||
("Yes", trans.model.ComponentReview.approved_states.YES),
|
||||
]
|
||||
if for_component:
|
||||
options.append(("Not applicable", trans.model.ComponentReview.approved_states.NA))
|
||||
if selected_value is None:
|
||||
selected_value = trans.model.ComponentReview.approved_states.NA
|
||||
select_field = SelectField(name=name)
|
||||
for option_tup in options:
|
||||
selected = selected_value and option_tup[1] == selected_value
|
||||
select_field.add_option(option_tup[0], option_tup[1], selected=selected)
|
||||
return select_field
|
||||
|
||||
|
||||
def build_changeset_revision_select_field(
|
||||
trans, repository, selected_value=None, add_id_to_name=True, downloadable=False, reviewed=False, not_reviewed=False
|
||||
trans,
|
||||
repository,
|
||||
selected_value=None,
|
||||
add_id_to_name=True,
|
||||
downloadable=False,
|
||||
):
|
||||
"""
|
||||
Build a SelectField whose options are the changeset_rev strings of certain revisions of the
|
||||
@@ -38,24 +26,6 @@ def build_changeset_revision_select_field(
|
||||
if downloadable:
|
||||
# Restrict the options to downloadable revisions.
|
||||
repository_metadata_revisions = repository.downloadable_revisions
|
||||
elif reviewed:
|
||||
# Restrict the options to revisions that have been reviewed.
|
||||
repository_metadata_revisions = []
|
||||
metadata_changeset_revision_hashes = []
|
||||
for metadata_revision in repository.metadata_revisions:
|
||||
metadata_changeset_revision_hashes.append(metadata_revision.changeset_revision)
|
||||
for review in repository.reviews:
|
||||
if review.changeset_revision in metadata_changeset_revision_hashes:
|
||||
repository_metadata_revisions.append(review.repository_metadata)
|
||||
elif not_reviewed:
|
||||
# Restrict the options to revisions that have not yet been reviewed.
|
||||
repository_metadata_revisions = []
|
||||
reviewed_metadata_changeset_revision_hashes = []
|
||||
for review in repository.reviews:
|
||||
reviewed_metadata_changeset_revision_hashes.append(review.changeset_revision)
|
||||
for metadata_revision in repository.metadata_revisions:
|
||||
if metadata_revision.changeset_revision not in reviewed_metadata_changeset_revision_hashes:
|
||||
repository_metadata_revisions.append(metadata_revision)
|
||||
else:
|
||||
# Restrict the options to all revisions that have associated metadata.
|
||||
repository_metadata_revisions = repository.metadata_revisions
|
||||
|
||||
@@ -138,56 +138,6 @@ def get_repository_role_association(repository_id, role_id):
|
||||
return rra
|
||||
|
||||
|
||||
def get_repository_reviews(repository_id, reviewer_user_id=None, changeset_revision=None):
|
||||
if reviewer_user_id and changeset_revision:
|
||||
reviews = (
|
||||
sa_session.query(model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryReview.table.c.repository_id == repository_id,
|
||||
model.RepositoryReview.table.c.deleted == false(),
|
||||
model.RepositoryReview.table.c.changeset_revision == changeset_revision,
|
||||
model.RepositoryReview.table.c.user_id == reviewer_user_id,
|
||||
)
|
||||
)
|
||||
.all()
|
||||
)
|
||||
elif reviewer_user_id:
|
||||
reviews = (
|
||||
sa_session.query(model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryReview.table.c.repository_id == repository_id,
|
||||
model.RepositoryReview.table.c.deleted == false(),
|
||||
model.RepositoryReview.table.c.user_id == reviewer_user_id,
|
||||
)
|
||||
)
|
||||
.all()
|
||||
)
|
||||
else:
|
||||
reviews = (
|
||||
sa_session.query(model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryReview.table.c.repository_id == repository_id,
|
||||
model.RepositoryReview.table.c.deleted == false(),
|
||||
)
|
||||
)
|
||||
.all()
|
||||
)
|
||||
return reviews
|
||||
|
||||
|
||||
def get_reviews_ordered_by_changeset_revision(repository_id, changelog_tuples, reviewer_user_id=None):
|
||||
reviews = get_repository_reviews(repository_id, reviewer_user_id=reviewer_user_id)
|
||||
ordered_reviews = []
|
||||
for _ctx_rev, changeset_hash in changelog_tuples:
|
||||
for review in reviews:
|
||||
if str(review.changeset_revision) == str(changeset_hash):
|
||||
ordered_reviews.append(review)
|
||||
return ordered_reviews
|
||||
|
||||
|
||||
def get_repository_by_id(repository_id):
|
||||
return sa_session.query(model.Repository).filter(model.Repository.table.c.id == repository_id).first()
|
||||
|
||||
@@ -220,21 +170,6 @@ def get_repository_metadata_for_changeset_revision(repository_id, changeset_revi
|
||||
return repository_metadata
|
||||
|
||||
|
||||
def get_repository_review_by_user_id_changeset_revision(user_id, repository_id, changeset_revision):
|
||||
review = (
|
||||
sa_session.query(model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
model.RepositoryReview.table.c.user_id == user_id,
|
||||
model.RepositoryReview.table.c.repository_id == repository_id,
|
||||
model.RepositoryReview.table.c.changeset_revision == changeset_revision,
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
return review
|
||||
|
||||
|
||||
def get_role_by_name(role_name):
|
||||
return sa_session.query(model.Role).filter(model.Role.table.c.name == role_name).first()
|
||||
|
||||
|
||||
@@ -237,11 +237,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
fh.write(smart_str(content))
|
||||
return fh.name
|
||||
|
||||
def add_repository_review_component(self, **kwd):
|
||||
params = {"operation": "create"}
|
||||
self.visit_url("/repository_review/create_component", params=params)
|
||||
self.submit_form(button="create_component_button", **kwd)
|
||||
|
||||
def assign_admin_role(self, repository, user):
|
||||
# As elsewhere, twill limits the possibility of submitting the form, this time due to not executing the javascript
|
||||
# attached to the role selection form. Visit the action url directly with the necessary parameters.
|
||||
@@ -262,11 +257,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
self.visit_url("/repository/browse_valid_categories", params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def browse_component_review(self, review, strings_displayed=None, strings_not_displayed=None):
|
||||
params = {"id": self.security.encode_id(review.id)}
|
||||
self.visit_url("/repository_review/browse_review", params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def browse_custom_datatypes(self, strings_displayed=None, strings_not_displayed=None):
|
||||
url = "/repository/browse_datatypes"
|
||||
self.visit_url(url)
|
||||
@@ -517,34 +507,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
strings_not_displayed=None,
|
||||
)
|
||||
|
||||
def create_repository_review(self, repository, review_contents_dict, changeset_revision=None, copy_from=None):
|
||||
strings_displayed = []
|
||||
if not copy_from:
|
||||
strings_displayed.append("Begin your review")
|
||||
strings_not_displayed = []
|
||||
if not changeset_revision:
|
||||
changeset_revision = self.get_repository_tip(repository)
|
||||
params = {"changeset_revision": changeset_revision, "id": self.security.encode_id(repository.id)}
|
||||
self.visit_url("/repository_review/create_review", params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
strings_displayed = []
|
||||
if copy_from:
|
||||
old_changeset_revision, review_id = copy_from
|
||||
strings_displayed = [
|
||||
"You have elected to create a new review",
|
||||
"Select previous revision",
|
||||
changeset_revision,
|
||||
]
|
||||
self.check_for_strings(strings_displayed)
|
||||
strings_displayed = []
|
||||
params = {
|
||||
"changeset_revision": self.get_repository_tip(repository),
|
||||
"id": self.security.encode_id(repository.id),
|
||||
"previous_review_id": self.security.encode_id(review_id),
|
||||
}
|
||||
self.visit_url("/repository_review/create_review", params=params)
|
||||
self.fill_review_form(review_contents_dict, strings_displayed, strings_not_displayed)
|
||||
|
||||
def create_user_in_galaxy(
|
||||
self, cntrller="user", email="test@bx.psu.edu", password="testuser", username="admin-user", redirect=""
|
||||
):
|
||||
@@ -668,16 +630,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
self.visit_url(url, params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def display_reviewed_repositories_owned_by_user(self, strings_displayed=None, strings_not_displayed=None):
|
||||
url = "/repository_review/reviewed_repositories_i_own"
|
||||
self.visit_url(url)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def display_repository_reviews_by_user(self, user, strings_displayed=None, strings_not_displayed=None):
|
||||
params = {"id": self.security.encode_id(user.id)}
|
||||
self.visit_url("/repository_review/repository_reviews_by_user", params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def edit_repository_categories(
|
||||
self, repository, categories_to_add=None, categories_to_remove=None, restore_original=True
|
||||
):
|
||||
@@ -754,25 +706,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
self.visit_url(url)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def fill_review_form(self, review_contents_dict, strings_displayed=None, strings_not_displayed=None):
|
||||
kwd = dict()
|
||||
changed = False
|
||||
for label, contents in review_contents_dict.items():
|
||||
if contents:
|
||||
changed = True
|
||||
kwd[f"{label}__ESEP__comment"] = contents["comment"]
|
||||
kwd[f"{label}__ESEP__rating"] = contents["rating"]
|
||||
if "private" in contents:
|
||||
kwd[f"{label}__ESEP__private"] = contents["private"]
|
||||
kwd[f"{label}__ESEP__approved"] = contents["approved"]
|
||||
else:
|
||||
kwd[f"{label}__ESEP__approved"] = "not_applicable"
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
self.submit_form(button="Workflows__ESEP__review_button", **kwd)
|
||||
if changed:
|
||||
strings_displayed.append("Reviews were saved")
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def galaxy_token(self):
|
||||
self.visit_galaxy_url("/")
|
||||
html = self.last_page()
|
||||
@@ -882,17 +815,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
def get_hg_repo(self, path):
|
||||
return hg.repository(ui.ui(), path.encode("utf-8"))
|
||||
|
||||
def get_last_reviewed_revision_by_user(self, user, repository):
|
||||
changelog_tuples = self.get_repository_changelog_tuples(repository)
|
||||
reviews = test_db_util.get_reviews_ordered_by_changeset_revision(
|
||||
repository.id, changelog_tuples, reviewer_user_id=user.id
|
||||
)
|
||||
if reviews:
|
||||
last_review = reviews[-1]
|
||||
else:
|
||||
last_review = None
|
||||
return last_review
|
||||
|
||||
def get_repositories_category_api(self, categories, strings_displayed=None, strings_not_displayed=None):
|
||||
for category in categories:
|
||||
url = f"/api/categories/{self.security.encode_id(category.id)}/repositories"
|
||||
@@ -1261,11 +1183,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
self.visit_galaxy_url("/tool_runner", params=params)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def manage_review_components(self, strings_displayed=None, strings_not_displayed=None):
|
||||
url = "/repository_review/manage_components"
|
||||
self.visit_url(url)
|
||||
self.check_for_strings(strings_displayed, strings_not_displayed)
|
||||
|
||||
def preview_repository_in_tool_shed(
|
||||
self, name, owner, changeset_revision=None, strings_displayed=None, strings_not_displayed=None
|
||||
):
|
||||
@@ -1355,19 +1272,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
self.visit_url("/repository/reset_all_metadata", params=params)
|
||||
self.check_for_strings(["All repository metadata has been reset."])
|
||||
|
||||
def review_repository(self, repository, review_contents_dict, user=None, changeset_revision=None):
|
||||
strings_displayed = []
|
||||
strings_not_displayed = []
|
||||
if not changeset_revision:
|
||||
changeset_revision = self.get_repository_tip(repository)
|
||||
if user:
|
||||
review = test_db_util.get_repository_review_by_user_id_changeset_revision(
|
||||
user.id, repository.id, changeset_revision
|
||||
)
|
||||
params = {"id": self.security.encode_id(review.id)}
|
||||
self.visit_url("/repository_review/edit_review", params=params)
|
||||
self.fill_review_form(review_contents_dict, strings_displayed, strings_not_displayed)
|
||||
|
||||
def revoke_write_access(self, repository, username):
|
||||
params = {"user_access_button": "Remove", "id": self.security.encode_id(repository.id), "remove_auth": username}
|
||||
self.visit_url("/repository/manage_repository", params=params)
|
||||
@@ -1651,20 +1555,6 @@ class ShedTwillTestCase(ShedBaseTestCase):
|
||||
# or we know that the repository was not correctly installed!
|
||||
assert found, f"No entry for {required_data_table_entry} in {self.shed_tool_data_table_conf}."
|
||||
|
||||
def verify_repository_reviews(self, repository, reviewer=None, strings_displayed=None, strings_not_displayed=None):
|
||||
changeset_revision = self.get_repository_tip(repository)
|
||||
# Verify that the currently logged in user has a repository review for the specified repository, reviewer, and changeset revision.
|
||||
strings_displayed = [repository.name, reviewer.username]
|
||||
self.display_reviewed_repositories_owned_by_user(strings_displayed=strings_displayed)
|
||||
# Verify that the reviewer has reviewed the specified repository's changeset revision.
|
||||
strings_displayed = [repository.name, repository.description]
|
||||
self.display_repository_reviews_by_user(reviewer, strings_displayed=strings_displayed)
|
||||
# Load the review and check for the components passed in strings_displayed.
|
||||
review = test_db_util.get_repository_review_by_user_id_changeset_revision(
|
||||
reviewer.id, repository.id, changeset_revision
|
||||
)
|
||||
self.browse_component_review(review, strings_displayed=strings_displayed)
|
||||
|
||||
def verify_tool_metadata_for_installed_repository(
|
||||
self, installed_repository, strings_displayed=None, strings_not_displayed=None
|
||||
):
|
||||
|
||||
@@ -1,666 +0,0 @@
|
||||
from ..base.twilltestcase import (
|
||||
common,
|
||||
ShedTwillTestCase,
|
||||
)
|
||||
|
||||
repository_name = "filtering_0400"
|
||||
repository_description = "Galaxy filtering tool for test 0400"
|
||||
repository_long_description = "Long description of Galaxy filtering tool for test 0400"
|
||||
|
||||
"""
|
||||
1. Create users.
|
||||
2. Grant reviewer role to test_user_2.
|
||||
3. Check that the review components that are to be tested are defined in this tool shed instance.
|
||||
4. Create a repository, owned by test_user_1, to be reviewed by test_user_2.
|
||||
5. Review the datatypes component on the repository.
|
||||
6. Check that no other components besides datatypes display as reviewed.
|
||||
7. Review the functional tests component on the repository.
|
||||
8. Check that only functional tests and datatypes display as reviewed.
|
||||
9. Review the readme component on the repository.
|
||||
10. Check that only functional tests, datatypes, and readme display as reviewed.
|
||||
11. Review the repository dependencies component.
|
||||
12. Check that only repository dependencies, functional tests, datatypes, and readme display as reviewed.
|
||||
13. Review the tool dependencies component.
|
||||
14. Check that only tool dependencies, repository dependencies, functional tests, datatypes, and readme display as reviewed.
|
||||
15. Review the tools component.
|
||||
16. Check that only tools, tool dependencies, repository dependencies, functional tests, datatypes, and readme display as reviewed.
|
||||
17. Review the workflows component.
|
||||
18. Check that all components display as reviewed.
|
||||
19. Upload readme.txt to the repository.
|
||||
20. Copy the previous review, and update the readme component review to reflect the existence of a readme file.
|
||||
21. Check that the readme component review has been updated, and the other component reviews are present.
|
||||
22. Upload test data to the repository. This will also create a new changeset revision.
|
||||
23. Review the functional tests component on the repository, copying the other components from the previous review.
|
||||
24. Verify that the functional tests component review has been updated, and as in step 21, the other reviews are unchanged.
|
||||
25. Upload a new version of the tool.
|
||||
26. Review the new revision's functional tests component.
|
||||
27. Verify that the functional tests component review displays correctly.
|
||||
"""
|
||||
|
||||
|
||||
class TestRepositoryComponentReviews(ShedTwillTestCase):
|
||||
"""Test repository component review features."""
|
||||
|
||||
def test_0000_initiate_users(self):
|
||||
"""Create necessary user accounts and login as an admin user.
|
||||
|
||||
We are at step 1.
|
||||
Create all the user accounts that are needed for this test script to run independently of other test.
|
||||
Previously created accounts will not be re-created.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
|
||||
assert (
|
||||
test_user_1 is not None
|
||||
), f"Problem retrieving user with email {common.test_user_1_email} from the database"
|
||||
self.test_db_util.get_private_role(test_user_1)
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
test_user_2 = self.test_db_util.get_user(common.test_user_2_email)
|
||||
assert (
|
||||
test_user_2 is not None
|
||||
), f"Problem retrieving user with email {common.test_user_2_email} from the database"
|
||||
self.test_db_util.get_private_role(test_user_2)
|
||||
self.login(email=common.admin_email, username=common.admin_username)
|
||||
admin_user = self.test_db_util.get_user(common.admin_email)
|
||||
assert admin_user is not None, f"Problem retrieving user with email {common.admin_email} from the database"
|
||||
self.test_db_util.get_private_role(admin_user)
|
||||
|
||||
def test_0005_grant_reviewer_role(self):
|
||||
"""Grant the repository reviewer role to test_user_2.
|
||||
|
||||
We are at step 2.
|
||||
We now have an admin user (admin_user) and two non-admin users (test_user_1 and test_user_2). Grant the repository
|
||||
reviewer role to test_user_2, who will not be the owner of the reviewed repositories.
|
||||
"""
|
||||
reviewer_role = self.test_db_util.get_role_by_name("Repository Reviewer")
|
||||
test_user_2 = self.test_db_util.get_user(common.test_user_2_email)
|
||||
self.grant_role_to_user(test_user_2, reviewer_role)
|
||||
|
||||
def test_0010_verify_repository_review_components(self):
|
||||
"""Ensure that the required review components exist.
|
||||
|
||||
We are at step 3.
|
||||
We now have an admin user (admin_user) and two non-admin users (test_user_1 and test_user_2). Grant the repository
|
||||
reviewer role to test_user_2, who will not be the owner of the reviewed repositories.
|
||||
"""
|
||||
strings_not_displayed = ["Repository dependencies"]
|
||||
self.manage_review_components(strings_not_displayed=strings_not_displayed)
|
||||
self.add_repository_review_component(
|
||||
name="Repository dependencies",
|
||||
description="Repository dependencies defined in a file named repository_dependencies.xml included in the repository",
|
||||
)
|
||||
strings_displayed = [
|
||||
"Data types",
|
||||
"Functional tests",
|
||||
"README",
|
||||
"Repository dependencies",
|
||||
"Tool dependencies",
|
||||
"Tools",
|
||||
"Workflows",
|
||||
]
|
||||
self.manage_review_components(strings_displayed=strings_displayed)
|
||||
|
||||
def test_0015_create_repository(self):
|
||||
"""Create and populate the filtering repository
|
||||
|
||||
We are at step 4.
|
||||
Log in as test_user_1 and create the filtering repository, then upload a basic set of
|
||||
components to be reviewed in subsequent tests.
|
||||
"""
|
||||
category = self.create_category(
|
||||
name="Test 0400 Repository Component Reviews", description="Test 0400 Repository Component Reviews"
|
||||
)
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
strings_displayed = self.expect_repo_created_strings(repository_name)
|
||||
repository = self.get_or_create_repository(
|
||||
name=repository_name,
|
||||
description=repository_description,
|
||||
long_description=repository_long_description,
|
||||
owner=common.test_user_1_name,
|
||||
category_id=self.security.encode_id(category.id),
|
||||
strings_displayed=strings_displayed,
|
||||
)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="filtering/filtering_1.1.0.tar",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded filtering 1.1.0 tarball.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
|
||||
def test_0020_review_initial_revision_data_types(self):
|
||||
"""Review the datatypes component for the current tip revision.
|
||||
|
||||
We are at step 5.
|
||||
Log in as test_user_2 and review the data types component of the filtering repository owned by test_user_1.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {"Data types": dict()}
|
||||
self.create_repository_review(repository, review_contents_dict)
|
||||
|
||||
def test_0025_verify_datatype_review(self):
|
||||
"""Verify that the datatypes component review displays correctly.
|
||||
|
||||
We are at step 6.
|
||||
Log in as test_user_1 and check that the filtering repository only has a review for the data types component.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Data types", "not_applicable"]
|
||||
strings_not_displayed = [
|
||||
"Functional tests",
|
||||
"README",
|
||||
"Repository dependencies",
|
||||
"Tool dependencies",
|
||||
"Tools",
|
||||
"Workflows",
|
||||
]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0030_review_initial_revision_functional_tests(self):
|
||||
"""Review the functional tests component for the current tip revision.
|
||||
|
||||
We are at step 7.
|
||||
Log in as test_user_2 and review the functional tests component for this repository. Since the repository
|
||||
has not been altered, this will update the existing review to add a component.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {
|
||||
"Functional tests": dict(rating=1, comment="Functional tests missing", approved="no", private="yes")
|
||||
}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
# def test_0030_verify_review_display( self ):
|
||||
# """Verify that private reviews are restricted to owner and reviewer, and non-private views are viewable by others."""
|
||||
# # Currently not implemented because third parties cannot view reviews whether they are private or not.
|
||||
# self.login( email=common.test_user_3_email, username=common.test_user_3_name )
|
||||
|
||||
def test_0035_verify_functional_test_review(self):
|
||||
"""Verify that the functional tests component review displays correctly.
|
||||
|
||||
We are at step 8.
|
||||
Log in as test_user_1 and check that the filtering repository now has reviews
|
||||
for the data types and functional tests components. Since the functional tests component was not marked as 'Not applicable',
|
||||
also check for the review comment.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Functional tests", "Functional tests missing", "no"]
|
||||
strings_not_displayed = ["README", "Repository dependencies", "Tool dependencies", "Tools", "Workflows"]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0040_review_readme(self):
|
||||
"""Review the readme component for the current tip revision.
|
||||
|
||||
We are at step 9.
|
||||
Log in as test_user_2 and update the review with the readme component marked as 'Not applicable'.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
# README (N/A)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {"README": dict()}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
def test_0045_verify_readme_review(self):
|
||||
"""Verify that the readme component review displays correctly.
|
||||
|
||||
We are at step 10.
|
||||
Log in as test_user_1 and verify that the repository component reviews now include a review for the readme component.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["README", "not_applicable"]
|
||||
strings_not_displayed = ["Repository dependencies", "Tool dependencies", "Tools", "Workflows"]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0050_review_repository_dependencies(self):
|
||||
"""Review the repository dependencies component for the current tip revision.
|
||||
|
||||
We are at step 11.
|
||||
Log in as test_user_2 and update the review with the repository dependencies component marked as 'Not applicable'.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
# README (N/A)
|
||||
# Repository dependencies (N/A)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {"Repository dependencies": dict()}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
def test_0055_verify_repository_dependency_review(self):
|
||||
"""Verify that the repository dependencies component review displays correctly.
|
||||
|
||||
We are at step 12.
|
||||
Log in as test_user_1 and verify that the repository component reviews now include a review
|
||||
for the repository dependencies component.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Repository dependencies", "not_applicable"]
|
||||
strings_not_displayed = ["Tool dependencies", "Tools", "Workflows"]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0060_review_tool_dependencies(self):
|
||||
"""Review the tool dependencies component for the current tip revision.
|
||||
|
||||
We are at step 13.
|
||||
Log in as test_user_2 and update the review with the tool dependencies component marked as 'Not applicable'.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
# README (N/A)
|
||||
# Repository dependencies (N/A)
|
||||
# Tool dependencies (N/A)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {"Tool dependencies": dict()}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
def test_0065_verify_tool_dependency_review(self):
|
||||
"""Verify that the tool dependencies component review displays correctly.
|
||||
|
||||
We are at step 14.
|
||||
Log in as test_user_1 and verify that the repository component reviews now include a review
|
||||
for the tool dependencies component.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Tool dependencies", "not_applicable"]
|
||||
strings_not_displayed = ["Tools", "Workflows"]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0070_review_tools(self):
|
||||
"""Review the tools component for the current tip revision.
|
||||
|
||||
We are at step 15.
|
||||
Log in as test_user_2 and update the review with the tools component given
|
||||
a favorable review, with 5 stars, and approved status.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
# README (N/A)
|
||||
# Repository dependencies (N/A)
|
||||
# Tool dependencies (N/A)
|
||||
# Tools (5 stars, good review)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {
|
||||
"Tools": dict(rating=5, comment="Excellent tool, easy to use.", approved="yes", private="no")
|
||||
}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
def test_0075_verify_tools_review(self):
|
||||
"""Verify that the tools component review displays correctly.
|
||||
|
||||
We are at step 16.
|
||||
Log in as test_user_1 and verify that the repository component reviews now include a review
|
||||
for the tools component. As before, check for the presence of the comment on this review.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Tools", "yes", "Excellent tool, easy to use."]
|
||||
strings_not_displayed = ["Workflows"]
|
||||
self.verify_repository_reviews(
|
||||
repository, reviewer=user, strings_displayed=strings_displayed, strings_not_displayed=strings_not_displayed
|
||||
)
|
||||
|
||||
def test_0080_review_workflows(self):
|
||||
"""Review the workflows component for the current tip revision.
|
||||
|
||||
We are at step 17.
|
||||
Log in as test_user_2 and update the review with the workflows component marked as 'Not applicable'.
|
||||
# Review this revision:
|
||||
# Data types (N/A)
|
||||
# Functional tests (One star, comment 'functional tests missing')
|
||||
# README (N/A)
|
||||
# Repository dependencies (N/A)
|
||||
# Tool dependencies (N/A)
|
||||
# Tools (5 stars, good review)
|
||||
# Workflows (N/A)
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {"Workflows": dict()}
|
||||
self.review_repository(repository, review_contents_dict, user)
|
||||
|
||||
def test_0085_verify_workflows_review(self):
|
||||
"""Verify that the workflows component review displays correctly.
|
||||
|
||||
We are at step 18.
|
||||
Log in as test_user_1 and verify that the repository component reviews now include a review
|
||||
for the workflows component.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Workflows", "not_applicable"]
|
||||
self.verify_repository_reviews(repository, reviewer=user, strings_displayed=strings_displayed)
|
||||
|
||||
def test_0090_upload_readme_file(self):
|
||||
"""Upload a readme file to the filtering repository.
|
||||
|
||||
We are at step 19.
|
||||
Log in as test_user_1, the repository owner, and upload readme.txt to the repository. This will create
|
||||
a new changeset revision for this repository, which will need to be reviewed.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="readme.txt",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=False,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded readme.txt.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
|
||||
def test_0095_review_new_changeset_readme_component(self):
|
||||
"""Update the filtering repository's readme component review to reflect the presence of the readme file.
|
||||
|
||||
We are at step 20.
|
||||
There is now a new changeset revision in the repository's changelog, but it has no review associated with it.
|
||||
Get the previously reviewed changeset hash, and pass that and the review id to the create_repository_review
|
||||
method, in order to copy the previous review's contents. Then update the new review to reflect the presence of
|
||||
a readme file.
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# Get the last changeset revision that has a review associated with it.
|
||||
last_review = self.get_last_reviewed_revision_by_user(user, repository)
|
||||
if last_review is None:
|
||||
raise AssertionError("Previous review expected, none found.")
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {
|
||||
"README": dict(
|
||||
rating=5,
|
||||
comment="Clear and concise readme file, a true pleasure to read.",
|
||||
approved="yes",
|
||||
private="no",
|
||||
)
|
||||
}
|
||||
self.create_repository_review(
|
||||
repository,
|
||||
review_contents_dict,
|
||||
changeset_revision=self.get_repository_tip(repository),
|
||||
copy_from=(str(last_review.changeset_revision), last_review.id),
|
||||
)
|
||||
|
||||
def test_0100_verify_readme_review(self):
|
||||
"""Verify that the readme component review displays correctly.
|
||||
|
||||
We are at step 21.
|
||||
Log in as the repository owner (test_user_1) and check the repository component reviews to
|
||||
verify that the readme component is now reviewed and approved.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["README", "yes", "Clear and concise readme file, a true pleasure to read."]
|
||||
self.verify_repository_reviews(repository, reviewer=user, strings_displayed=strings_displayed)
|
||||
|
||||
def test_0105_upload_test_data(self):
|
||||
"""Upload the missing test data to the filtering repository.
|
||||
|
||||
We are at step 22.
|
||||
Remain logged in as test_user_1 and upload test data to the repository. This will also create a
|
||||
new changeset revision that needs to be reviewed. This will replace the changeset hash associated with
|
||||
the last dowloadable revision, but the last repository review will still be associated with the
|
||||
last dowloadable revision hash.
|
||||
"""
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="filtering/filtering_test_data.tar",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded filtering test data.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
|
||||
def test_0110_review_new_changeset_functional_tests(self):
|
||||
"""Update the filtering repository's readme component review to reflect the presence of the readme file.
|
||||
|
||||
We are at step 23.
|
||||
Log in as test_user_2 and get the last reviewed changeset hash, and pass that and the review id to
|
||||
the create_repository_review method, then update the copied review to approve the functional tests
|
||||
component.
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
# Get the changeset immediately prior to the tip, and pass it to the create review method.
|
||||
last_review = self.get_last_reviewed_revision_by_user(user, repository)
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {
|
||||
"Functional tests": dict(rating=5, comment="A good set of functional tests.", approved="yes", private="no")
|
||||
}
|
||||
self.create_repository_review(
|
||||
repository,
|
||||
review_contents_dict,
|
||||
changeset_revision=self.get_repository_tip(repository),
|
||||
copy_from=(str(last_review.changeset_revision), last_review.id),
|
||||
)
|
||||
|
||||
def test_0115_verify_functional_tests_review(self):
|
||||
"""Verify that the functional tests component review displays correctly.
|
||||
|
||||
We are at step 24.
|
||||
Log in as the repository owner, test_user_1, and verify that the new revision's functional tests component
|
||||
review has been updated with an approved status and favorable comment.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = ["Functional tests", "yes", "A good set of functional tests."]
|
||||
self.verify_repository_reviews(repository, reviewer=user, strings_displayed=strings_displayed)
|
||||
|
||||
def test_0120_upload_new_tool_version(self):
|
||||
"""Upload filtering 2.2.0 to the filtering repository.
|
||||
|
||||
We are at step 25.
|
||||
Log in as test_user_1 and upload a new version of the tool to the filtering repository. This will create
|
||||
a new downloadable revision, with no associated repository component reviews.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="filtering/filtering_2.2.0.tar",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded filtering 2.2.0 tarball.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
|
||||
def test_0125_review_new_changeset_functional_tests(self):
|
||||
"""Update the filtering repository's review to apply to the new changeset with filtering 2.2.0.
|
||||
|
||||
We are at step 26.
|
||||
Log in as test_user_2 and copy the last review for this repository to the new changeset. Then
|
||||
update the tools component review to refer to the new tool version.
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
last_review = self.get_last_reviewed_revision_by_user(user, repository)
|
||||
# Something needs to change so that the review will save.
|
||||
# The create_repository_review method takes a dict( component label=review contents ).
|
||||
# If review_contents is empty, it marks that component as not applicable. The review
|
||||
# contents dict should have the structure:
|
||||
# {
|
||||
# rating: 1-5,
|
||||
# comment: <text>
|
||||
# approved: yes/no
|
||||
# private: yes/no
|
||||
# }
|
||||
review_contents_dict = {
|
||||
"Tools": dict(
|
||||
rating=5,
|
||||
comment="Version 2.2.0 does the impossible and improves this tool.",
|
||||
approved="yes",
|
||||
private="yes",
|
||||
)
|
||||
}
|
||||
self.create_repository_review(
|
||||
repository,
|
||||
review_contents_dict,
|
||||
changeset_revision=self.get_repository_tip(repository),
|
||||
copy_from=(str(last_review.changeset_revision), last_review.id),
|
||||
)
|
||||
|
||||
def test_0135_verify_review_for_new_version(self):
|
||||
"""Verify that the reviews display correctly for this changeset revision.
|
||||
|
||||
We are at step 27.
|
||||
Log in as test_user_1 and check that the tools component review is for filtering 2.2.0, but that the other component
|
||||
reviews had their contents copied from the last reviewed changeset.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = [
|
||||
"Data types",
|
||||
"Functional tests",
|
||||
"yes",
|
||||
"A good set of functional tests.",
|
||||
"README",
|
||||
"yes",
|
||||
"Workflows",
|
||||
"Tools",
|
||||
]
|
||||
strings_displayed.extend(
|
||||
["Clear and concise readme file, a true pleasure to read.", "Tool dependencies", "not_applicable"]
|
||||
)
|
||||
strings_displayed.extend(
|
||||
["Repository dependencies", "Version 2.2.0 does the impossible and improves this tool."]
|
||||
)
|
||||
self.verify_repository_reviews(repository, reviewer=user, strings_displayed=strings_displayed)
|
||||
-246
@@ -1,246 +0,0 @@
|
||||
from ..base.twilltestcase import (
|
||||
common,
|
||||
ShedTwillTestCase,
|
||||
)
|
||||
|
||||
repository_name = "filtering_0410"
|
||||
repository_description = "Galaxy filtering tool for test 0410"
|
||||
repository_long_description = "Long description of Galaxy filtering tool for test 0410"
|
||||
|
||||
"""
|
||||
1. Create a repository in the tool shed owned by test_user_1.
|
||||
2. Have test_user_2 complete a review of the repository.
|
||||
3. Have test_user_1 browse the review.
|
||||
4. Have test_user_3 browse the repository and make sure they are not allowed to browse the review.
|
||||
5. Have test_user_1 give write permission on the repository to the test_user_3.
|
||||
6. Have test_user_3 browse the repository again and they should now have the ability to browse the review.
|
||||
7. Have test_user_3 browse the review.
|
||||
"""
|
||||
|
||||
|
||||
class TestRepositoryComponentReviews(ShedTwillTestCase):
|
||||
"""Test repository component review features."""
|
||||
|
||||
def test_0000_initiate_users(self):
|
||||
"""Create necessary user accounts and login as an admin user.
|
||||
|
||||
Create all the user accounts that are needed for this test script to run independently of other test.
|
||||
Previously created accounts will not be re-created.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
test_user_1 = self.test_db_util.get_user(common.test_user_1_email)
|
||||
assert (
|
||||
test_user_1 is not None
|
||||
), f"Problem retrieving user with email {common.test_user_1_email} from the database"
|
||||
self.test_db_util.get_private_role(test_user_1)
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
test_user_2 = self.test_db_util.get_user(common.test_user_2_email)
|
||||
assert (
|
||||
test_user_2 is not None
|
||||
), f"Problem retrieving user with email {common.test_user_2_email} from the database"
|
||||
self.test_db_util.get_private_role(test_user_2)
|
||||
self.login(email=common.test_user_3_email, username=common.test_user_3_name)
|
||||
test_user_3 = self.test_db_util.get_user(common.test_user_3_email)
|
||||
assert (
|
||||
test_user_3 is not None
|
||||
), f"Problem retrieving user with email {common.test_user_3_email} from the database"
|
||||
self.test_db_util.get_private_role(test_user_3)
|
||||
self.login(email=common.admin_email, username=common.admin_username)
|
||||
admin_user = self.test_db_util.get_user(common.admin_email)
|
||||
assert admin_user is not None, f"Problem retrieving user with email {common.admin_email} from the database"
|
||||
self.test_db_util.get_private_role(admin_user)
|
||||
|
||||
def test_0005_grant_reviewer_role(self):
|
||||
"""Grant the repository reviewer role to test_user_2.
|
||||
|
||||
We now have an admin user (admin_user) and three non-admin users (test_user_1, test_user_2, and test_user_3). Grant the repository
|
||||
reviewer role to test_user_2, who will not be the owner of the reviewed repositories, and do not grant any roles to test_user_3 yet.
|
||||
"""
|
||||
reviewer_role = self.test_db_util.get_role_by_name("Repository Reviewer")
|
||||
test_user_2 = self.test_db_util.get_user(common.test_user_2_email)
|
||||
self.grant_role_to_user(test_user_2, reviewer_role)
|
||||
|
||||
def test_0010_verify_repository_review_components(self):
|
||||
"""Ensure that the required review components exist.
|
||||
|
||||
Make sure all the components we are to review are recorded in the database.
|
||||
"""
|
||||
self.add_repository_review_component(
|
||||
name="Repository dependencies",
|
||||
description="Repository dependencies defined in a file named repository_dependencies.xml included in the repository",
|
||||
)
|
||||
strings_displayed = [
|
||||
"Data types",
|
||||
"Functional tests",
|
||||
"README",
|
||||
"Repository dependencies",
|
||||
"Tool dependencies",
|
||||
"Tools",
|
||||
"Workflows",
|
||||
]
|
||||
self.manage_review_components(strings_displayed=strings_displayed)
|
||||
|
||||
def test_0015_create_repository(self):
|
||||
"""Create and populate the filtering repository
|
||||
|
||||
We are at step 1.
|
||||
Log in as test_user_1 and create the filtering repository, then upload a basic set of
|
||||
components to be reviewed in subsequent tests.
|
||||
"""
|
||||
category = self.create_category(
|
||||
name="Test 0400 Repository Component Reviews", description="Test 0400 Repository Component Reviews"
|
||||
)
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
strings_displayed = self.expect_repo_created_strings(repository_name)
|
||||
repository = self.get_or_create_repository(
|
||||
name=repository_name,
|
||||
description=repository_description,
|
||||
long_description=repository_long_description,
|
||||
owner=common.test_user_1_name,
|
||||
category_id=self.security.encode_id(category.id),
|
||||
strings_displayed=strings_displayed,
|
||||
)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="filtering/filtering_1.1.0.tar",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded filtering 1.1.0 tarball.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="filtering/filtering_test_data.tar",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded filtering test data.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
self.upload_file(
|
||||
repository,
|
||||
filename="readme.txt",
|
||||
filepath=None,
|
||||
valid_tools_only=True,
|
||||
uncompress_file=True,
|
||||
remove_repo_files_not_in_tar=False,
|
||||
commit_message="Uploaded readme.txt.",
|
||||
strings_displayed=[],
|
||||
strings_not_displayed=[],
|
||||
)
|
||||
|
||||
def test_0020_review_repository(self):
|
||||
"""Complete a review of the filtering repository.
|
||||
|
||||
We are at step 2 - Have test_user_2 complete a review of the repository.
|
||||
Review all components of the filtering repository, with the appropriate contents and approved/not approved/not applicable status.
|
||||
"""
|
||||
self.login(email=common.test_user_2_email, username=common.test_user_2_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
review_contents_dict = {
|
||||
"Data types": dict(),
|
||||
"README": dict(
|
||||
rating=5,
|
||||
comment="Clear and concise readme file, a true pleasure to read.",
|
||||
approved="yes",
|
||||
private="no",
|
||||
),
|
||||
"Functional tests": dict(rating=5, comment="A good set of functional tests.", approved="yes", private="no"),
|
||||
"Repository dependencies": dict(),
|
||||
"Tool dependencies": dict(),
|
||||
"Tools": dict(rating=5, comment="Excellent tool, easy to use.", approved="yes", private="no"),
|
||||
"Workflows": dict(),
|
||||
}
|
||||
self.create_repository_review(repository, review_contents_dict)
|
||||
|
||||
def test_0025_verify_repository_review(self):
|
||||
"""Verify that the review was completed and displays properly.
|
||||
|
||||
We are at step 3 - Have test_user_1 browse the review.
|
||||
Verify that all the review components were submitted, and that the repository owner can see the review.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = [
|
||||
"Data types",
|
||||
"Functional tests",
|
||||
"yes",
|
||||
"A good set of functional tests.",
|
||||
"README",
|
||||
"yes",
|
||||
"Workflows",
|
||||
"Tools",
|
||||
]
|
||||
strings_displayed.extend(
|
||||
["Clear and concise readme file, a true pleasure to read.", "Tool dependencies", "not_applicable"]
|
||||
)
|
||||
strings_displayed.extend(["Repository dependencies", "Excellent tool, easy to use."])
|
||||
strings_displayed = ["Browse reviews of this repository"]
|
||||
self.display_manage_repository_page(repository, strings_displayed=strings_displayed)
|
||||
self.verify_repository_reviews(repository, reviewer=user, strings_displayed=strings_displayed)
|
||||
|
||||
def test_0030_browse_with_other_user(self):
|
||||
"""Verify that test_user_3 is blocked from browsing the review.
|
||||
|
||||
We are at step 4 - Have test_user_3 browse the repository and make sure they are not allowed to browse the review.
|
||||
"""
|
||||
self.login(email=common.test_user_3_email, username=common.test_user_3_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_not_displayed = ["Browse reviews of this repository"]
|
||||
self.display_manage_repository_page(repository, strings_not_displayed=strings_not_displayed)
|
||||
strings_not_displayed = [
|
||||
"A good set of functional tests.",
|
||||
"Clear and concise readme file, a true pleasure to read.",
|
||||
]
|
||||
strings_not_displayed.append("Excellent tool, easy to use.")
|
||||
changeset_revision = self.get_repository_tip(repository)
|
||||
review = self.test_db_util.get_repository_review_by_user_id_changeset_revision(
|
||||
user.id, repository.id, changeset_revision
|
||||
)
|
||||
self.browse_component_review(review, strings_not_displayed=strings_not_displayed)
|
||||
|
||||
def test_0035_grant_write_access_to_other_user(self):
|
||||
"""Grant write access on the filtering_0410 repository to test_user_3.
|
||||
|
||||
We are at step 5 - Have test_user_1 give write permission on the repository to the test_user_3.
|
||||
"""
|
||||
self.login(email=common.test_user_1_email, username=common.test_user_1_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
self.grant_write_access(repository, usernames=[common.test_user_3_name])
|
||||
|
||||
def test_0040_verify_test_user_3_can_browse_reviews(self):
|
||||
"""Check that test_user_3 can now browse reviews.
|
||||
|
||||
We are at step 6 - Have test_user_3 browse the repository again and they should now have the ability to browse the review.
|
||||
"""
|
||||
self.login(email=common.test_user_3_email, username=common.test_user_3_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
strings_displayed = ["Browse reviews of this repository"]
|
||||
self.display_manage_repository_page(repository, strings_displayed=strings_displayed)
|
||||
|
||||
def test_0045_verify_browse_review_with_write_access(self):
|
||||
"""Check that test_user_3 can now display reviews.
|
||||
|
||||
We are at step 7 - Have test_user_3 browse the review.
|
||||
"""
|
||||
self.login(email=common.test_user_3_email, username=common.test_user_3_name)
|
||||
repository = self.test_db_util.get_repository_by_name_and_owner(repository_name, common.test_user_1_name)
|
||||
user = self.test_db_util.get_user(common.test_user_2_email)
|
||||
strings_displayed = [
|
||||
"A good set of functional tests.",
|
||||
"Clear and concise readme file",
|
||||
"a true pleasure to read.",
|
||||
"Excellent tool, easy to use.",
|
||||
]
|
||||
changeset_revision = self.get_repository_tip(repository)
|
||||
review = self.test_db_util.get_repository_review_by_user_id_changeset_revision(
|
||||
user.id, repository.id, changeset_revision
|
||||
)
|
||||
self.browse_component_review(review, strings_displayed=strings_displayed)
|
||||
@@ -272,27 +272,6 @@ def get_repository_metadata_by_repository_id_changeset_revision(app, id, changes
|
||||
return get_repository_metadata_by_changeset_revision(app, id, changeset_revision)
|
||||
|
||||
|
||||
def get_repository_metadata_revisions_for_review(repository, reviewed=True):
|
||||
repository_metadata_revisions = []
|
||||
metadata_changeset_revision_hashes = []
|
||||
if reviewed:
|
||||
for metadata_revision in repository.metadata_revisions:
|
||||
metadata_changeset_revision_hashes.append(metadata_revision.changeset_revision)
|
||||
for review in repository.reviews:
|
||||
if review.changeset_revision in metadata_changeset_revision_hashes:
|
||||
rmcr_hashes = [rmr.changeset_revision for rmr in repository_metadata_revisions]
|
||||
if review.changeset_revision not in rmcr_hashes:
|
||||
repository_metadata_revisions.append(review.repository_metadata)
|
||||
else:
|
||||
for review in repository.reviews:
|
||||
if review.changeset_revision not in metadata_changeset_revision_hashes:
|
||||
metadata_changeset_revision_hashes.append(review.changeset_revision)
|
||||
for metadata_revision in repository.metadata_revisions:
|
||||
if metadata_revision.changeset_revision not in metadata_changeset_revision_hashes:
|
||||
repository_metadata_revisions.append(metadata_revision)
|
||||
return repository_metadata_revisions
|
||||
|
||||
|
||||
def get_updated_changeset_revisions(app, name, owner, changeset_revision):
|
||||
"""
|
||||
Return a string of comma-separated changeset revision hashes for all available updates to the received changeset
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
import logging
|
||||
|
||||
from sqlalchemy import and_
|
||||
|
||||
from tool_shed.util import hg_util
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def can_browse_repository_reviews(app, user, repository):
|
||||
"""
|
||||
Determine if there are any reviews of the received repository for which the
|
||||
current user has permission to browse any component reviews.
|
||||
"""
|
||||
if user:
|
||||
for review in repository.reviews:
|
||||
for component_review in review.component_reviews:
|
||||
if app.security_agent.user_can_browse_component_review(app, repository, component_review, user):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def changeset_revision_reviewed_by_user(user, repository, changeset_revision):
|
||||
"""Determine if the current changeset revision has been reviewed by the current user."""
|
||||
for review in repository.reviews:
|
||||
if review.changeset_revision == changeset_revision and review.user == user:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_component(app, id):
|
||||
"""Get a component from the database."""
|
||||
sa_session = app.model.session
|
||||
return sa_session.query(app.model.Component).get(app.security.decode_id(id))
|
||||
|
||||
|
||||
def get_component_review(app, id):
|
||||
"""Get a component_review from the database"""
|
||||
sa_session = app.model.session
|
||||
return sa_session.query(app.model.ComponentReview).get(app.security.decode_id(id))
|
||||
|
||||
|
||||
def get_component_by_name(app, name):
|
||||
"""Get a component from the database via a name."""
|
||||
sa_session = app.model.session
|
||||
return sa_session.query(app.model.Component).filter(app.model.Component.table.c.name == name).first()
|
||||
|
||||
|
||||
def get_component_review_by_repository_review_id_component_id(app, repository_review_id, component_id):
|
||||
"""Get a component_review from the database via repository_review_id and component_id."""
|
||||
sa_session = app.model.session
|
||||
return (
|
||||
sa_session.query(app.model.ComponentReview)
|
||||
.filter(
|
||||
and_(
|
||||
app.model.ComponentReview.table.c.repository_review_id == app.security.decode_id(repository_review_id),
|
||||
app.model.ComponentReview.table.c.component_id == app.security.decode_id(component_id),
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
|
||||
def get_components(app):
|
||||
sa_session = app.model.session
|
||||
return sa_session.query(app.model.Component).order_by(app.model.Component.name).all()
|
||||
|
||||
|
||||
def get_previous_repository_reviews(app, repository, changeset_revision):
|
||||
"""
|
||||
Return an ordered dictionary of repository reviews up to and including the
|
||||
received changeset revision.
|
||||
"""
|
||||
repo = repository.hg_repo
|
||||
reviewed_revision_hashes = [review.changeset_revision for review in repository.reviews]
|
||||
previous_reviews_dict = {}
|
||||
for changeset in hg_util.reversed_upper_bounded_changelog(repo, changeset_revision):
|
||||
previous_changeset_revision = str(repo[changeset])
|
||||
if previous_changeset_revision in reviewed_revision_hashes:
|
||||
previous_rev, previous_changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(
|
||||
repo, previous_changeset_revision
|
||||
)
|
||||
revision_reviews = get_reviews_by_repository_id_changeset_revision(
|
||||
app, app.security.encode_id(repository.id), previous_changeset_revision
|
||||
)
|
||||
previous_reviews_dict[previous_changeset_revision] = dict(
|
||||
changeset_revision_label=previous_changeset_revision_label, reviews=revision_reviews
|
||||
)
|
||||
return previous_reviews_dict
|
||||
|
||||
|
||||
def get_review(app, id):
|
||||
"""Get a repository_review from the database via id."""
|
||||
sa_session = app.model.session
|
||||
return sa_session.query(app.model.RepositoryReview).get(app.security.decode_id(id))
|
||||
|
||||
|
||||
def get_review_by_repository_id_changeset_revision_user_id(app, repository_id, changeset_revision, user_id):
|
||||
"""
|
||||
Get a repository_review from the database via repository id, changeset_revision
|
||||
and user_id.
|
||||
"""
|
||||
sa_session = app.model.session
|
||||
return (
|
||||
sa_session.query(app.model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
app.model.RepositoryReview.repository_id == app.security.decode_id(repository_id),
|
||||
app.model.RepositoryReview.changeset_revision == changeset_revision,
|
||||
app.model.RepositoryReview.user_id == app.security.decode_id(user_id),
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
|
||||
def get_reviews_by_repository_id_changeset_revision(app, repository_id, changeset_revision):
|
||||
"""Get all repository_reviews from the database via repository id and changeset_revision."""
|
||||
sa_session = app.model.session
|
||||
return (
|
||||
sa_session.query(app.model.RepositoryReview)
|
||||
.filter(
|
||||
and_(
|
||||
app.model.RepositoryReview.repository_id == app.security.decode_id(repository_id),
|
||||
app.model.RepositoryReview.changeset_revision == changeset_revision,
|
||||
)
|
||||
)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
def has_previous_repository_reviews(app, repository, changeset_revision):
|
||||
"""
|
||||
Determine if a repository has a changeset revision review prior to the
|
||||
received changeset revision.
|
||||
"""
|
||||
repo = repository.hg_repo
|
||||
reviewed_revision_hashes = [review.changeset_revision for review in repository.reviews]
|
||||
for changeset in hg_util.reversed_upper_bounded_changelog(repo, changeset_revision):
|
||||
previous_changeset_revision = str(repo[changeset])
|
||||
if previous_changeset_revision in reviewed_revision_hashes:
|
||||
return True
|
||||
return False
|
||||
@@ -123,12 +123,6 @@ def get_repos(sa_session, file_path, hgweb_config_dir, **kwargs):
|
||||
user = sa_session.query(model.User).filter(model.User.id == repo.user_id).one()
|
||||
repo_owner_username = user.username.lower()
|
||||
|
||||
approved = "no"
|
||||
for review in repo.reviews:
|
||||
if review.approved == "yes":
|
||||
approved = "yes"
|
||||
break
|
||||
|
||||
last_updated = pretty_print_time_interval(repo.update_time)
|
||||
full_last_updated = repo.update_time.strftime("%Y-%m-%d %I:%M %p")
|
||||
|
||||
@@ -165,7 +159,7 @@ def get_repos(sa_session, file_path, hgweb_config_dir, **kwargs):
|
||||
remote_repository_url=unicodify(remote_repository_url),
|
||||
repo_owner_username=unicodify(repo_owner_username),
|
||||
times_downloaded=unicodify(times_downloaded),
|
||||
approved=unicodify(approved),
|
||||
approved=unicodify("no"),
|
||||
last_updated=unicodify(last_updated),
|
||||
full_last_updated=unicodify(full_last_updated),
|
||||
tools_list=tools_list,
|
||||
|
||||
@@ -125,15 +125,7 @@ class GroupsController(BaseAPIController):
|
||||
time_repo_updated_full = repo.update_time.strftime("%Y-%m-%d %I:%M %p")
|
||||
time_repo_created = pretty_print_time_interval(repo.create_time, True)
|
||||
time_repo_updated = pretty_print_time_interval(repo.update_time, True)
|
||||
approved = ""
|
||||
ratings = []
|
||||
for review in repo.reviews:
|
||||
if review.rating:
|
||||
ratings.append(review.rating)
|
||||
if review.approved == "yes":
|
||||
approved = "yes"
|
||||
# TODO add user ratings
|
||||
ratings_mean = str(float(sum(ratings)) / len(ratings)) if len(ratings) > 0 else ""
|
||||
total_downloads += repo.times_downloaded
|
||||
group_repos.append(
|
||||
{
|
||||
@@ -145,8 +137,6 @@ class GroupsController(BaseAPIController):
|
||||
"time_updated_full": time_repo_updated_full,
|
||||
"time_updated": time_repo_updated,
|
||||
"description": repo.description,
|
||||
"approved": approved,
|
||||
"ratings_mean": ratings_mean,
|
||||
"categories": categories,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -263,10 +263,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository", action="browse_repositories_by_user", **kwd)
|
||||
)
|
||||
elif operation == "reviewed_repositories_i_own":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="reviewed_repositories_i_own")
|
||||
)
|
||||
elif operation == "repositories_by_category":
|
||||
category_id = kwd.get("id", None)
|
||||
message = escape(kwd.get("message", ""))
|
||||
@@ -1632,14 +1628,8 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
# TODO: move the following to some in-memory register so these queries can be done once
|
||||
# at startup. The in-memory register can then be managed during the current session.
|
||||
can_administer_repositories = False
|
||||
has_reviewed_repositories = False
|
||||
has_deprecated_repositories = False
|
||||
if current_user:
|
||||
# See if the current user owns any repositories that have been reviewed.
|
||||
for repository in current_user.active_repositories:
|
||||
if repository.reviews:
|
||||
has_reviewed_repositories = True
|
||||
break
|
||||
# See if the current user has any repositories that have been marked as deprecated.
|
||||
for repository in current_user.active_repositories:
|
||||
if repository.deprecated:
|
||||
@@ -1666,7 +1656,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
"/webapps/tool_shed/index.mako",
|
||||
repository_metadata=repository_metadata,
|
||||
can_administer_repositories=can_administer_repositories,
|
||||
has_reviewed_repositories=has_reviewed_repositories,
|
||||
has_deprecated_repositories=has_deprecated_repositories,
|
||||
user_id=user_id,
|
||||
repository_id=repository_id,
|
||||
@@ -1822,7 +1811,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
description = kwd.get("description", repository.description)
|
||||
long_description = kwd.get("long_description", repository.long_description)
|
||||
avg_rating, num_ratings = self.get_ave_item_rating_data(trans.sa_session, repository, webapp_model=trans.model)
|
||||
display_reviews = util.string_as_bool(kwd.get("display_reviews", False))
|
||||
alerts = kwd.get("alerts", "")
|
||||
alerts_checked = CheckboxField.is_checked(alerts)
|
||||
category_ids = util.listify(kwd.get("category_id", ""))
|
||||
@@ -2016,7 +2004,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
categories=categories,
|
||||
metadata=metadata,
|
||||
avg_rating=avg_rating,
|
||||
display_reviews=display_reviews,
|
||||
num_ratings=num_ratings,
|
||||
alerts_check_box=alerts_check_box,
|
||||
malicious_check_box=malicious_check_box,
|
||||
@@ -2074,13 +2061,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("review repository revision")
|
||||
def manage_repository_reviews_of_revision(self, trans, **kwd):
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repository_reviews_of_revision", **kwd)
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("multi select email alerts")
|
||||
def multi_select_email_alerts(self, trans, **kwd):
|
||||
@@ -2268,7 +2248,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
comment = kwd.get("comment", "")
|
||||
rating = self.rate_item(trans, trans.user, repository, rating, comment)
|
||||
avg_rating, num_ratings = self.get_ave_item_rating_data(trans.sa_session, repository, webapp_model=trans.model)
|
||||
display_reviews = util.string_as_bool(kwd.get("display_reviews", False))
|
||||
rra = self.get_user_item_rating(trans.sa_session, trans.user, repository, webapp_model=trans.model)
|
||||
metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision(
|
||||
trans.app, id, changeset_revision, metadata_only=True
|
||||
@@ -2281,7 +2260,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
metadata=metadata,
|
||||
revision_label=revision_label,
|
||||
avg_rating=avg_rating,
|
||||
display_reviews=display_reviews,
|
||||
num_ratings=num_ratings,
|
||||
rra=rra,
|
||||
repository_type_select_field=repository_type_select_field,
|
||||
@@ -2763,7 +2741,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
repository, changeset_revision=changeset_revision
|
||||
)
|
||||
repository.clone_url = common_util.generate_clone_url_for_repository_in_tool_shed(trans.user, repository)
|
||||
display_reviews = kwd.get("display_reviews", False)
|
||||
alerts = kwd.get("alerts", "")
|
||||
alerts_checked = CheckboxField.is_checked(alerts)
|
||||
if repository.email_alerts:
|
||||
@@ -2833,7 +2810,6 @@ class RepositoryController(BaseUIController, ratings_util.ItemRatings):
|
||||
metadata=metadata,
|
||||
containers_dict=containers_dict,
|
||||
avg_rating=avg_rating,
|
||||
display_reviews=display_reviews,
|
||||
num_ratings=num_ratings,
|
||||
alerts_check_box=alerts_check_box,
|
||||
changeset_revision=changeset_revision,
|
||||
|
||||
@@ -1,670 +0,0 @@
|
||||
import logging
|
||||
|
||||
from sqlalchemy import (
|
||||
and_,
|
||||
false,
|
||||
func,
|
||||
)
|
||||
|
||||
import tool_shed.grids.repository_review_grids as repository_review_grids
|
||||
import tool_shed.grids.util as grids_util
|
||||
from galaxy import (
|
||||
util,
|
||||
web,
|
||||
)
|
||||
from galaxy.web.form_builder import CheckboxField
|
||||
from galaxy.webapps.base.controller import BaseUIController
|
||||
from tool_shed.util import (
|
||||
hg_util,
|
||||
metadata_util,
|
||||
repository_util,
|
||||
review_util,
|
||||
shed_util_common as suc,
|
||||
)
|
||||
from tool_shed.util.container_util import STRSEP
|
||||
from tool_shed.util.web_util import escape
|
||||
from tool_shed.webapp.framework.decorators import require_login
|
||||
from tool_shed.webapp.util import ratings_util
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RepositoryReviewController(BaseUIController, ratings_util.ItemRatings):
|
||||
|
||||
component_grid = repository_review_grids.ComponentGrid()
|
||||
repositories_ready_for_review_grid = repository_review_grids.RepositoriesReadyForReviewGrid()
|
||||
repositories_reviewed_by_me_grid = repository_review_grids.RepositoriesReviewedByMeGrid()
|
||||
repositories_with_reviews_grid = repository_review_grids.RepositoriesWithReviewsGrid()
|
||||
repositories_without_reviews_grid = repository_review_grids.RepositoriesWithoutReviewsGrid()
|
||||
repository_reviews_by_user_grid = repository_review_grids.RepositoryReviewsByUserGrid()
|
||||
reviewed_repositories_i_own_grid = repository_review_grids.ReviewedRepositoriesIOwnGrid()
|
||||
repositories_with_no_tool_tests_grid = repository_review_grids.RepositoriesWithNoToolTestsGrid()
|
||||
|
||||
@web.expose
|
||||
@require_login("approve repository review")
|
||||
def approve_repository_review(self, trans, **kwd):
|
||||
# The value of the received id is the encoded review id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
encoded_review_id = kwd["id"]
|
||||
review = review_util.get_review(trans.app, encoded_review_id)
|
||||
if kwd.get("approve_repository_review_button", False):
|
||||
approved_select_field_name = f"{encoded_review_id}{STRSEP}approved"
|
||||
approved_select_field_value = str(kwd[approved_select_field_name])
|
||||
review.approved = approved_select_field_value
|
||||
trans.sa_session.add(review)
|
||||
trans.sa_session.flush()
|
||||
message = f"Approved value <b>{escape(approved_select_field_value)}</b> saved for this revision."
|
||||
repository_id = trans.security.encode_id(review.repository_id)
|
||||
changeset_revision = review.changeset_revision
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(
|
||||
controller="repository_review",
|
||||
action="manage_repository_reviews_of_revision",
|
||||
id=repository_id,
|
||||
changeset_revision=changeset_revision,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("browse components")
|
||||
def browse_components(self, trans, **kwd):
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "create":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="create_component", **kwd)
|
||||
)
|
||||
return self.component_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("browse review")
|
||||
def browse_review(self, trans, **kwd):
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
review = review_util.get_review(trans.app, kwd["id"])
|
||||
repository = review.repository
|
||||
repo = repository.hg_repo
|
||||
rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(repo, review.changeset_revision)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/browse_review.mako",
|
||||
repository=repository,
|
||||
changeset_revision_label=changeset_revision_label,
|
||||
review=review,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
def copy_review(self, trans, review_to_copy, review):
|
||||
for component_review in review_to_copy.component_reviews:
|
||||
copied_component_review = trans.model.ComponentReview(
|
||||
repository_review_id=review.id,
|
||||
component_id=component_review.component.id,
|
||||
comment=component_review.comment,
|
||||
private=component_review.private,
|
||||
approved=component_review.approved,
|
||||
rating=component_review.rating,
|
||||
)
|
||||
trans.sa_session.add(copied_component_review)
|
||||
trans.sa_session.flush()
|
||||
review.approved = review_to_copy.approved
|
||||
review.rating = review_to_copy.rating
|
||||
trans.sa_session.add(review)
|
||||
trans.sa_session.flush()
|
||||
|
||||
@web.expose
|
||||
@require_login("create component")
|
||||
def create_component(self, trans, **kwd):
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
name = kwd.get("name", "")
|
||||
description = kwd.get("description", "")
|
||||
if kwd.get("create_component_button", False):
|
||||
if not name or not description:
|
||||
message = "Enter a valid name and a description"
|
||||
status = "error"
|
||||
elif review_util.get_component_by_name(trans.app, name):
|
||||
message = "A component with that name already exists"
|
||||
status = "error"
|
||||
else:
|
||||
component = trans.app.model.Component(name=name, description=description)
|
||||
trans.sa_session.add(component)
|
||||
trans.sa_session.flush()
|
||||
message = f"Component '{escape(component.name)}' has been created"
|
||||
status = "done"
|
||||
trans.response.send_redirect(
|
||||
web.url_for(
|
||||
controller="repository_review", action="manage_components", message=message, status=status
|
||||
)
|
||||
)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/create_component.mako",
|
||||
name=name,
|
||||
description=description,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("create review")
|
||||
def create_review(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
repository_id = kwd.get("id", None)
|
||||
changeset_revision = kwd.get("changeset_revision", None)
|
||||
previous_review_id = kwd.get("previous_review_id", None)
|
||||
create_without_copying = "create_without_copying" in kwd
|
||||
if repository_id:
|
||||
if changeset_revision:
|
||||
# Make sure there is not already a review of the revision by the user.
|
||||
repository = repository_util.get_repository_in_tool_shed(trans.app, repository_id)
|
||||
if review_util.get_review_by_repository_id_changeset_revision_user_id(
|
||||
app=trans.app,
|
||||
repository_id=repository_id,
|
||||
changeset_revision=changeset_revision,
|
||||
user_id=trans.security.encode_id(trans.user.id),
|
||||
):
|
||||
message = f"You have already created a review for revision <b>{changeset_revision}</b> of repository <b>{escape(repository.name)}</b>."
|
||||
status = "error"
|
||||
else:
|
||||
# See if there are any reviews for previous changeset revisions that the user can copy.
|
||||
if (
|
||||
not create_without_copying
|
||||
and not previous_review_id
|
||||
and review_util.has_previous_repository_reviews(trans.app, repository, changeset_revision)
|
||||
):
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="select_previous_review", **kwd)
|
||||
)
|
||||
# A review can be initially performed only on an installable revision of a repository, so make sure we have metadata associated
|
||||
# with the received changeset_revision.
|
||||
repository_metadata = metadata_util.get_repository_metadata_by_changeset_revision(
|
||||
trans.app, repository_id, changeset_revision
|
||||
)
|
||||
if repository_metadata:
|
||||
metadata = repository_metadata.metadata
|
||||
if metadata:
|
||||
review = trans.app.model.RepositoryReview(
|
||||
repository_id=repository_metadata.repository_id,
|
||||
changeset_revision=changeset_revision,
|
||||
user_id=trans.user.id,
|
||||
rating=None,
|
||||
deleted=False,
|
||||
)
|
||||
trans.sa_session.add(review)
|
||||
trans.sa_session.flush()
|
||||
if previous_review_id:
|
||||
review_to_copy = review_util.get_review(trans.app, previous_review_id)
|
||||
self.copy_review(trans, review_to_copy, review)
|
||||
review_id = trans.security.encode_id(review.id)
|
||||
message = f"Begin your review of revision <b>{changeset_revision}</b> of repository <b>{repository.name}</b>."
|
||||
status = "done"
|
||||
trans.response.send_redirect(
|
||||
web.url_for(
|
||||
controller="repository_review",
|
||||
action="edit_review",
|
||||
id=review_id,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
)
|
||||
else:
|
||||
message = (
|
||||
"A new review cannot be created for revision <b>%s</b> of repository <b>%s</b>. Select a valid revision and try again."
|
||||
% (changeset_revision, escape(repository.name))
|
||||
)
|
||||
kwd["message"] = message
|
||||
kwd["status"] = "error"
|
||||
else:
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repository_reviews", **kwd)
|
||||
)
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("edit component")
|
||||
def edit_component(self, trans, **kwd):
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
id = kwd.get("id", None)
|
||||
if not id:
|
||||
message = "No component ids received for editing"
|
||||
trans.response.send_redirect(
|
||||
web.url_for(controller="admin", action="manage_categories", message=message, status="error")
|
||||
)
|
||||
component = review_util.get_component(trans.app, id)
|
||||
if kwd.get("edit_component_button", False):
|
||||
new_description = kwd.get("description", "").strip()
|
||||
if component.description != new_description:
|
||||
component.description = new_description
|
||||
trans.sa_session.add(component)
|
||||
trans.sa_session.flush()
|
||||
message = f"The information has been saved for the component named <b>{escape(component.name)}</b>"
|
||||
status = "done"
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(
|
||||
controller="repository_review", action="manage_components", message=message, status=status
|
||||
)
|
||||
)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/edit_component.mako",
|
||||
component=component,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("edit review")
|
||||
def edit_review(self, trans, **kwd):
|
||||
# The value of the received id is the encoded review id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
review_id = kwd.get("id", None)
|
||||
review = review_util.get_review(trans.app, review_id)
|
||||
components_dict = {}
|
||||
for component in review_util.get_components(trans.app):
|
||||
components_dict[component.name] = dict(component=component, component_review=None)
|
||||
repository = review.repository
|
||||
repo = repository.hg_repo
|
||||
for component_review in review.component_reviews:
|
||||
if component_review and component_review.component:
|
||||
component_name = component_review.component.name
|
||||
if component_name in components_dict:
|
||||
component_review_dict = components_dict[component_name]
|
||||
component_review_dict["component_review"] = component_review
|
||||
components_dict[component_name] = component_review_dict
|
||||
# Handle a Save button click.
|
||||
save_button_clicked = False
|
||||
save_buttons = [f"{comp_name}{STRSEP}review_button" for comp_name in components_dict.keys()]
|
||||
save_buttons.append("revision_approved_button")
|
||||
for save_button in save_buttons:
|
||||
if save_button in kwd:
|
||||
save_button_clicked = True
|
||||
break
|
||||
if save_button_clicked:
|
||||
# Handle the revision_approved_select_field value.
|
||||
revision_approved = kwd.get("revision_approved", None)
|
||||
revision_approved_setting_changed = False
|
||||
if revision_approved:
|
||||
revision_approved = str(revision_approved)
|
||||
if review.approved != revision_approved:
|
||||
revision_approved_setting_changed = True
|
||||
review.approved = revision_approved
|
||||
trans.sa_session.add(review)
|
||||
trans.sa_session.flush()
|
||||
saved_component_names = []
|
||||
for component_name in components_dict.keys():
|
||||
flushed = False
|
||||
# Retrieve the review information from the form.
|
||||
# The star rating form field is a radio button list, so it will not be received if it was not clicked in the form.
|
||||
# Due to this behavior, default the value to 0.
|
||||
rating = 0
|
||||
private = False
|
||||
for k, v in kwd.items():
|
||||
if k.startswith(f"{component_name}{STRSEP}"):
|
||||
component_review_attr = k.replace(f"{component_name}{STRSEP}", "")
|
||||
if component_review_attr == "component_id":
|
||||
component_id = str(v)
|
||||
elif component_review_attr == "comment":
|
||||
comment = str(v)
|
||||
elif component_review_attr == "private":
|
||||
private = CheckboxField.is_checked(v)
|
||||
elif component_review_attr == "approved":
|
||||
approved = str(v)
|
||||
elif component_review_attr == "rating":
|
||||
rating = int(str(v))
|
||||
component = review_util.get_component(trans.app, component_id)
|
||||
component_review = review_util.get_component_review_by_repository_review_id_component_id(
|
||||
trans.app, review_id, component_id
|
||||
)
|
||||
if component_review:
|
||||
# See if the existing component review should be updated.
|
||||
if (
|
||||
component_review.comment != comment
|
||||
or component_review.private != private
|
||||
or component_review.approved != approved
|
||||
or component_review.rating != rating
|
||||
):
|
||||
component_review.comment = comment
|
||||
component_review.private = private
|
||||
component_review.approved = approved
|
||||
component_review.rating = rating
|
||||
trans.sa_session.add(component_review)
|
||||
trans.sa_session.flush()
|
||||
flushed = True
|
||||
saved_component_names.append(component_name)
|
||||
else:
|
||||
# See if a new component_review should be created.
|
||||
if comment or private or approved != trans.model.ComponentReview.approved_states.NO or rating:
|
||||
component_review = trans.model.ComponentReview(
|
||||
repository_review_id=review.id,
|
||||
component_id=component.id,
|
||||
comment=comment,
|
||||
approved=approved,
|
||||
rating=rating,
|
||||
)
|
||||
trans.sa_session.add(component_review)
|
||||
trans.sa_session.flush()
|
||||
flushed = True
|
||||
saved_component_names.append(component_name)
|
||||
if flushed:
|
||||
# Update the repository rating value to be the average of all component review ratings.
|
||||
average_rating = (
|
||||
trans.sa_session.query(func.avg(trans.model.ComponentReview.table.c.rating))
|
||||
.filter(
|
||||
and_(
|
||||
trans.model.ComponentReview.table.c.repository_review_id == review.id,
|
||||
trans.model.ComponentReview.table.c.deleted == false(),
|
||||
trans.model.ComponentReview.table.c.approved
|
||||
!= trans.model.ComponentReview.approved_states.NA,
|
||||
)
|
||||
)
|
||||
.scalar()
|
||||
)
|
||||
if average_rating is not None:
|
||||
review.rating = int(average_rating)
|
||||
trans.sa_session.add(review)
|
||||
trans.sa_session.flush()
|
||||
# Update the information in components_dict.
|
||||
if component_name in components_dict:
|
||||
component_review_dict = components_dict[component_name]
|
||||
component_review_dict["component_review"] = component_review
|
||||
components_dict[component_name] = component_review_dict
|
||||
if revision_approved_setting_changed:
|
||||
message += f"Approved value <b>{review.approved}</b> saved for this revision.<br/>"
|
||||
if saved_component_names:
|
||||
message += f"Reviews were saved for components: {', '.join(saved_component_names)}"
|
||||
if not revision_approved_setting_changed and not saved_component_names:
|
||||
message += "No changes were made to this review, so nothing was saved."
|
||||
if review and review.approved:
|
||||
selected_value = review.approved
|
||||
else:
|
||||
selected_value = trans.model.ComponentReview.approved_states.NO
|
||||
revision_approved_select_field = grids_util.build_approved_select_field(
|
||||
trans, name="revision_approved", selected_value=selected_value, for_component=False
|
||||
)
|
||||
rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(repo, review.changeset_revision)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/edit_review.mako",
|
||||
repository=repository,
|
||||
review=review,
|
||||
changeset_revision_label=changeset_revision_label,
|
||||
revision_approved_select_field=revision_approved_select_field,
|
||||
components_dict=components_dict,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage components")
|
||||
def manage_components(self, trans, **kwd):
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "create":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="create_component", **kwd)
|
||||
)
|
||||
elif operation == "edit":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="edit_component", **kwd)
|
||||
)
|
||||
if "message" not in kwd:
|
||||
message = "This is a list of repository components (features) that can be reviewed. You can add new components or change "
|
||||
message += "the description of an existing component if appropriate. Click on the name link to change the description."
|
||||
status = "warning"
|
||||
kwd["message"] = message
|
||||
kwd["status"] = status
|
||||
return self.component_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repositories ready for review")
|
||||
def manage_repositories_ready_for_review(self, trans, **kwd):
|
||||
"""
|
||||
A repository is ready to be reviewed if one of the following conditions is met:
|
||||
|
||||
1) It contains no tools
|
||||
2) It contains tools the tools_functionally_correct flag is set to True. This implies that the repository metadata revision was installed and tested
|
||||
by the Tool Shed's install and test framework.
|
||||
"""
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="create_review", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
message = "Any of these repositories that contain tools have been installed into Galaxy and proven to be functionally correct by executing the tests defined "
|
||||
message += "for each tool. Repositories that do not contain tools have not been installed into Galaxy. "
|
||||
kwd["message"] = message
|
||||
kwd["status"] = "warning"
|
||||
return self.repositories_ready_for_review_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repositories reviewed by me")
|
||||
def manage_repositories_reviewed_by_me(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
if "operation" in kwd:
|
||||
kwd["mine"] = True
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repositories_with_reviews", **kwd)
|
||||
)
|
||||
self.repositories_reviewed_by_me_grid.title = "Repositories reviewed by me"
|
||||
return self.repositories_reviewed_by_me_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repositories with invalid tests")
|
||||
def manage_repositories_with_invalid_tests(self, trans, **kwd):
|
||||
"""
|
||||
Display a list of repositories that contain tools, have not yet been reviewed, and have invalid functional tests. Tests are defined as
|
||||
invalid if they are missing from the tool config or if defined test data is not included in the repository.
|
||||
"""
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="create_review", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
message = "These repositories contain tools with missing functional tests or test data. "
|
||||
kwd["message"] = message
|
||||
kwd["status"] = "warning"
|
||||
return self.repositories_with_no_tool_tests_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repositories with reviews")
|
||||
def manage_repositories_with_reviews(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repository_reviews", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
return self.repositories_with_reviews_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repositories without reviews")
|
||||
def manage_repositories_without_reviews(self, trans, **kwd):
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="create_review", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
return self.repositories_without_reviews_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repository reviews")
|
||||
def manage_repository_reviews(self, trans, mine=False, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
repository_id = kwd.get("id", None)
|
||||
if repository_id:
|
||||
repository = suc.get_repository_in_tool_shed(trans.app, repository_id)
|
||||
repo = repository.hg_repo
|
||||
metadata_revision_hashes = [
|
||||
metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions
|
||||
]
|
||||
reviewed_revision_hashes = [review.changeset_revision for review in repository.reviews]
|
||||
reviews_dict = {}
|
||||
for changeset in hg_util.get_reversed_changelog_changesets(repo):
|
||||
changeset_revision = str(repo[changeset])
|
||||
if changeset_revision in metadata_revision_hashes or changeset_revision in reviewed_revision_hashes:
|
||||
rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(
|
||||
repo, changeset_revision
|
||||
)
|
||||
if changeset_revision in reviewed_revision_hashes:
|
||||
# Find the review for this changeset_revision
|
||||
repository_reviews = review_util.get_reviews_by_repository_id_changeset_revision(
|
||||
trans.app, repository_id, changeset_revision
|
||||
)
|
||||
# Determine if the current user can add a review to this revision.
|
||||
can_add_review = trans.user not in [
|
||||
repository_review.user for repository_review in repository_reviews
|
||||
]
|
||||
repository_metadata = metadata_util.get_repository_metadata_by_changeset_revision(
|
||||
trans.app, repository_id, changeset_revision
|
||||
)
|
||||
if repository_metadata:
|
||||
repository_metadata_reviews = util.listify(repository_metadata.reviews)
|
||||
else:
|
||||
repository_metadata_reviews = []
|
||||
else:
|
||||
repository_reviews = []
|
||||
repository_metadata_reviews = []
|
||||
can_add_review = True
|
||||
installable = changeset_revision in metadata_revision_hashes
|
||||
revision_dict = dict(
|
||||
changeset_revision_label=changeset_revision_label,
|
||||
repository_reviews=repository_reviews,
|
||||
repository_metadata_reviews=repository_metadata_reviews,
|
||||
installable=installable,
|
||||
can_add_review=can_add_review,
|
||||
)
|
||||
reviews_dict[changeset_revision] = revision_dict
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/reviews_of_repository.mako",
|
||||
repository=repository,
|
||||
reviews_dict=reviews_dict,
|
||||
mine=mine,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("manage repository reviews of revision")
|
||||
def manage_repository_reviews_of_revision(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
repository_id = kwd.get("id", None)
|
||||
changeset_revision = kwd.get("changeset_revision", None)
|
||||
repository = repository_util.get_repository_in_tool_shed(trans.app, repository_id)
|
||||
repo = repository.hg_repo
|
||||
installable = changeset_revision in [
|
||||
metadata_revision.changeset_revision for metadata_revision in repository.metadata_revisions
|
||||
]
|
||||
rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(repo, changeset_revision)
|
||||
reviews = review_util.get_reviews_by_repository_id_changeset_revision(
|
||||
trans.app, repository_id, changeset_revision
|
||||
)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/reviews_of_changeset_revision.mako",
|
||||
repository=repository,
|
||||
changeset_revision=changeset_revision,
|
||||
changeset_revision_label=changeset_revision_label,
|
||||
reviews=reviews,
|
||||
installable=installable,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("repository reviews by user")
|
||||
def repository_reviews_by_user(self, trans, **kwd):
|
||||
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
# The value of the received id is the encoded review id.
|
||||
review = review_util.get_review(trans.app, kwd["id"])
|
||||
repository = review.repository
|
||||
kwd["id"] = trans.security.encode_id(repository.id)
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repository_reviews", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
kwd["changeset_revision"] = review.changeset_revision
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
# The user may not be the current user. The value of the received id is the encoded user id.
|
||||
user = suc.get_user(trans.app, kwd["id"])
|
||||
self.repository_reviews_by_user_grid.title = f"All repository revision reviews for user '{user.username}'"
|
||||
return self.repository_reviews_by_user_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("reviewed repositories i own")
|
||||
def reviewed_repositories_i_own(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
if "operation" in kwd:
|
||||
operation = kwd["operation"].lower()
|
||||
if operation == "inspect repository revisions":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="manage_repository_reviews", **kwd)
|
||||
)
|
||||
if operation == "view_or_manage_repository":
|
||||
return trans.response.send_redirect(
|
||||
web.url_for(controller="repository_review", action="view_or_manage_repository", **kwd)
|
||||
)
|
||||
return self.reviewed_repositories_i_own_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@require_login("select previous review")
|
||||
def select_previous_review(self, trans, **kwd):
|
||||
# The value of the received id is the encoded repository id.
|
||||
message = escape(kwd.get("message", ""))
|
||||
status = kwd.get("status", "done")
|
||||
repository = repository_util.get_repository_in_tool_shed(trans.app, kwd["id"])
|
||||
changeset_revision = kwd.get("changeset_revision", None)
|
||||
repo = repository.hg_repo
|
||||
previous_reviews_dict = review_util.get_previous_repository_reviews(trans.app, repository, changeset_revision)
|
||||
rev, changeset_revision_label = hg_util.get_rev_label_from_changeset_revision(repo, changeset_revision)
|
||||
return trans.fill_template(
|
||||
"/webapps/tool_shed/repository_review/select_previous_review.mako",
|
||||
repository=repository,
|
||||
changeset_revision=changeset_revision,
|
||||
changeset_revision_label=changeset_revision_label,
|
||||
previous_reviews_dict=previous_reviews_dict,
|
||||
message=message,
|
||||
status=status,
|
||||
)
|
||||
|
||||
@web.expose
|
||||
@require_login("view or manage repository")
|
||||
def view_or_manage_repository(self, trans, **kwd):
|
||||
repository = repository_util.get_repository_in_tool_shed(trans.app, kwd["id"])
|
||||
if trans.user_is_admin or repository.user == trans.user:
|
||||
return trans.response.send_redirect(web.url_for(controller="repository", action="manage_repository", **kwd))
|
||||
else:
|
||||
return trans.response.send_redirect(web.url_for(controller="repository", action="view_repository", **kwd))
|
||||
@@ -20,7 +20,6 @@ from sqlalchemy import (
|
||||
Column,
|
||||
DateTime,
|
||||
desc,
|
||||
false,
|
||||
ForeignKey,
|
||||
Integer,
|
||||
not_,
|
||||
@@ -132,7 +131,6 @@ class User(Base, Dictifiable, _HasTable):
|
||||
& not_(Role.name == User.email) # type: ignore[has-type]
|
||||
),
|
||||
)
|
||||
repository_reviews = relationship("RepositoryReview", back_populates="user")
|
||||
|
||||
def __init__(self, email=None, password=None):
|
||||
self.email = email
|
||||
@@ -375,8 +373,6 @@ class Repository(Base, Dictifiable, _HasTable):
|
||||
back_populates="repository",
|
||||
)
|
||||
roles = relationship("RepositoryRoleAssociation", back_populates="repository")
|
||||
reviews = relationship("RepositoryReview", back_populates="repository")
|
||||
reviewers = relationship("User", secondary=lambda: RepositoryReview.__table__, viewonly=True) # type: ignore
|
||||
|
||||
dict_collection_visible_keys = [
|
||||
"id",
|
||||
@@ -541,114 +537,6 @@ class Repository(Base, Dictifiable, _HasTable):
|
||||
return rval
|
||||
|
||||
|
||||
class RepositoryReview(Base, Dictifiable, _HasTable):
|
||||
__tablename__ = "repository_review"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
create_time = Column(DateTime, default=now)
|
||||
update_time = Column(DateTime, default=now, onupdate=now)
|
||||
repository_id = Column(ForeignKey("repository.id"), index=True)
|
||||
changeset_revision = Column(TrimmedString(255), index=True)
|
||||
user_id = Column(ForeignKey("galaxy_user.id"), index=True, nullable=False)
|
||||
approved = Column(TrimmedString(255))
|
||||
rating = Column(Integer, index=True)
|
||||
deleted = Column(Boolean, index=True, default=False)
|
||||
repository = relationship("Repository", back_populates="reviews")
|
||||
# Take care when using the mapper below! It should be used only when a new review is being created for a repository change set revision.
|
||||
# Keep in mind that repository_metadata records can be removed from the database for certain change set revisions when metadata is being
|
||||
# reset on a repository!
|
||||
repository_metadata = relationship(
|
||||
"RepositoryMetadata",
|
||||
viewonly=True,
|
||||
foreign_keys=lambda: [RepositoryReview.repository_id, RepositoryReview.changeset_revision],
|
||||
primaryjoin=lambda: (
|
||||
(RepositoryReview.repository_id == RepositoryMetadata.repository_id) # type: ignore[has-type]
|
||||
& (RepositoryReview.changeset_revision == RepositoryMetadata.changeset_revision) # type: ignore[has-type]
|
||||
),
|
||||
back_populates="reviews",
|
||||
)
|
||||
user = relationship("User", back_populates="repository_reviews")
|
||||
|
||||
component_reviews = relationship(
|
||||
"ComponentReview",
|
||||
viewonly=True,
|
||||
primaryjoin=lambda: (
|
||||
(RepositoryReview.id == ComponentReview.repository_review_id) # type: ignore[has-type]
|
||||
& (ComponentReview.deleted == false()) # type: ignore[has-type]
|
||||
),
|
||||
back_populates="repository_review",
|
||||
)
|
||||
|
||||
private_component_reviews = relationship(
|
||||
"ComponentReview",
|
||||
viewonly=True,
|
||||
primaryjoin=lambda: (
|
||||
(RepositoryReview.id == ComponentReview.repository_review_id) # type: ignore[has-type]
|
||||
& (ComponentReview.deleted == false()) # type: ignore[has-type]
|
||||
& (ComponentReview.private == true()) # type: ignore[has-type]
|
||||
),
|
||||
)
|
||||
|
||||
dict_collection_visible_keys = ["id", "repository_id", "changeset_revision", "user_id", "rating", "deleted"]
|
||||
dict_element_visible_keys = ["id", "repository_id", "changeset_revision", "user_id", "rating", "deleted"]
|
||||
approved_states = Bunch(NO="no", YES="yes")
|
||||
|
||||
def __init__(self, deleted=False, **kwd):
|
||||
super().__init__(**kwd)
|
||||
self.deleted = deleted
|
||||
|
||||
|
||||
class ComponentReview(Base, Dictifiable, _HasTable):
|
||||
__tablename__ = "component_review"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
create_time = Column(DateTime, default=now)
|
||||
update_time = Column(DateTime, default=now, onupdate=now)
|
||||
repository_review_id = Column(ForeignKey("repository_review.id"), index=True)
|
||||
component_id = Column(ForeignKey("component.id"), index=True)
|
||||
comment = Column(TEXT)
|
||||
private = Column(Boolean, default=False)
|
||||
approved = Column(TrimmedString(255))
|
||||
rating = Column(Integer)
|
||||
deleted = Column(Boolean, index=True, default=False)
|
||||
repository_review = relationship("RepositoryReview", back_populates="component_reviews")
|
||||
component = relationship("Component")
|
||||
|
||||
dict_collection_visible_keys = [
|
||||
"id",
|
||||
"repository_review_id",
|
||||
"component_id",
|
||||
"private",
|
||||
"approved",
|
||||
"rating",
|
||||
"deleted",
|
||||
]
|
||||
dict_element_visible_keys = [
|
||||
"id",
|
||||
"repository_review_id",
|
||||
"component_id",
|
||||
"private",
|
||||
"approved",
|
||||
"rating",
|
||||
"deleted",
|
||||
]
|
||||
approved_states = Bunch(NO="no", YES="yes", NA="not_applicable")
|
||||
|
||||
def __init__(self, private=False, approved=False, deleted=False, **kwd):
|
||||
super().__init__(**kwd)
|
||||
self.private = private
|
||||
self.approved = approved
|
||||
self.deleted = deleted
|
||||
|
||||
|
||||
class Component(Base, _HasTable):
|
||||
__tablename__ = "component"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(TrimmedString(255))
|
||||
description = Column(TEXT)
|
||||
|
||||
|
||||
class ItemRatingAssociation(_HasTable):
|
||||
def __init__(self, id=None, user=None, item=None, rating=0, comment=""):
|
||||
self.id = id
|
||||
@@ -841,23 +729,13 @@ class RepositoryMetadata(Dictifiable, _HasTable):
|
||||
|
||||
|
||||
# After the map_imperatively statement has been executed, the members of the
|
||||
# properties dictionary (repository, reviews) will be available as instrumented
|
||||
# properties dictionary (repository) will be available as instrumented
|
||||
# class attributes on RepositoryMetadata.
|
||||
mapper_registry.map_imperatively(
|
||||
RepositoryMetadata,
|
||||
RepositoryMetadata.table,
|
||||
properties=dict(
|
||||
repository=relationship(Repository, back_populates="metadata_revisions"),
|
||||
reviews=relationship(
|
||||
RepositoryReview,
|
||||
viewonly=True,
|
||||
foreign_keys=lambda: [RepositoryReview.repository_id, RepositoryReview.changeset_revision],
|
||||
primaryjoin=lambda: (
|
||||
(RepositoryReview.repository_id == RepositoryMetadata.repository_id)
|
||||
& (RepositoryReview.changeset_revision == RepositoryMetadata.changeset_revision)
|
||||
),
|
||||
back_populates="repository_metadata",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -164,18 +164,6 @@ class CommunityRBACAgent(RBACAgent):
|
||||
return None
|
||||
return role
|
||||
|
||||
def get_repository_reviewer_role(self):
|
||||
return (
|
||||
self.sa_session.query(self.model.Role)
|
||||
.filter(
|
||||
and_(
|
||||
self.model.Role.table.c.name == "Repository Reviewer",
|
||||
self.model.Role.table.c.type == self.model.Role.types.SYSTEM,
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
|
||||
def set_entity_group_associations(self, groups=None, users=None, roles=None, delete_existing_assocs=True):
|
||||
if groups is None:
|
||||
groups = []
|
||||
@@ -283,26 +271,6 @@ class CommunityRBACAgent(RBACAgent):
|
||||
return True
|
||||
return False
|
||||
|
||||
def user_can_review_repositories(self, user):
|
||||
if user:
|
||||
roles = user.all_roles()
|
||||
if roles:
|
||||
repository_reviewer_role = self.get_repository_reviewer_role()
|
||||
if repository_reviewer_role:
|
||||
return repository_reviewer_role in roles
|
||||
return False
|
||||
|
||||
def user_can_browse_component_review(self, app, repository, component_review, user):
|
||||
if component_review and user:
|
||||
if self.can_push(app, user, repository):
|
||||
# A user with write permission on the repository can access private/public component reviews.
|
||||
return True
|
||||
else:
|
||||
if self.user_can_review_repositories(user):
|
||||
# Reviewers can access private/public component reviews.
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_permitted_actions(filter=None):
|
||||
"""Utility method to return a subset of RBACAgent's permitted actions"""
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
</%def>
|
||||
|
||||
<%def name="left_panel()">
|
||||
<% can_review_repositories = trans.app.security_agent.user_can_review_repositories( trans.user ) %>
|
||||
<div class="unified-panel-header" unselectable="on">
|
||||
<div class='unified-panel-header-inner'>Administration</div>
|
||||
</div>
|
||||
|
||||
@@ -152,19 +152,3 @@
|
||||
${heads_str}
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
<%def name="render_review_comment( comment_text )">
|
||||
<style type="text/css">
|
||||
#reviews_table{ table-layout:fixed;
|
||||
width:100%;
|
||||
overflow-wrap:normal;
|
||||
overflow:hidden;
|
||||
border:0px;
|
||||
word-break:keep-all;
|
||||
word-wrap:break-word;
|
||||
line-break:strict; }
|
||||
</style>
|
||||
<table id="reviews_table">
|
||||
<tr><td>${comment_text}</td></tr>
|
||||
</table>
|
||||
</%def>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
<%def name="render_tool_shed_repository_actions( repository, metadata=None, changeset_revision=None )">
|
||||
<%
|
||||
from tool_shed.util.review_util import can_browse_repository_reviews, changeset_revision_reviewed_by_user, get_review_by_repository_id_changeset_revision_user_id
|
||||
from tool_shed.util.metadata_util import is_malicious
|
||||
|
||||
if repository.metadata_revisions:
|
||||
@@ -34,11 +33,6 @@
|
||||
|
||||
can_browse_contents = not is_new
|
||||
|
||||
if can_browse_repository_reviews( trans.app, trans.user, repository ):
|
||||
can_browse_reviews = True
|
||||
else:
|
||||
can_browse_reviews = False
|
||||
|
||||
if trans.user and trans.user != repository.user:
|
||||
can_contact_owner = True
|
||||
else:
|
||||
@@ -73,28 +67,6 @@
|
||||
can_rate = True
|
||||
else:
|
||||
can_rate = False
|
||||
|
||||
if metadata is not None and changeset_revision is not None:
|
||||
if has_metadata and not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user ):
|
||||
can_review_repository = True
|
||||
else:
|
||||
can_review_repository = False
|
||||
if changeset_revision_reviewed_by_user( trans.user, repository, changeset_revision ):
|
||||
reviewed_by_user = True
|
||||
else:
|
||||
reviewed_by_user = False
|
||||
else:
|
||||
can_review_repository = False
|
||||
reviewed_by_user = False
|
||||
|
||||
if reviewed_by_user:
|
||||
review = get_review_by_repository_id_changeset_revision_user_id( app=trans.app,
|
||||
repository_id=trans.security.encode_id( repository.id ),
|
||||
changeset_revision=changeset_revision,
|
||||
user_id=trans.security.encode_id( trans.user.id ) )
|
||||
review_id = trans.security.encode_id( review.id )
|
||||
else:
|
||||
review_id = None
|
||||
|
||||
if not is_new and not is_deprecated:
|
||||
can_set_metadata = True
|
||||
@@ -134,16 +106,6 @@
|
||||
%else:
|
||||
<li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li>
|
||||
<div popupmenu="repository-${repository.id}-popup">
|
||||
%if can_review_repository:
|
||||
%if reviewed_by_user:
|
||||
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository_review', action='edit_review', id=review_id )}">Manage my review of this revision</a>
|
||||
%else:
|
||||
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository_review', action='create_review', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Add a review to this revision</a>
|
||||
%endif
|
||||
%endif
|
||||
%if can_browse_reviews:
|
||||
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_repository_reviews', id=trans.app.security.encode_id( repository.id ) )}">Browse reviews of this repository</a>
|
||||
%endif
|
||||
%if can_upload:
|
||||
<a class="action-button" target="galaxy_main" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}">Upload files to repository</a>
|
||||
%endif
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
</%def>
|
||||
|
||||
<%def name="left_panel()">
|
||||
<% can_review_repositories = trans.app.security_agent.user_can_review_repositories( trans.user ) %>
|
||||
<div class="unified-panel-header" unselectable="on">
|
||||
<div class='unified-panel-header-inner'>${trans.app.shed_counter.unique_valid_tools | h} valid tools on ${util.unicodify( trans.app.shed_counter.generation_time ) | h}</div>
|
||||
</div>
|
||||
@@ -93,11 +92,6 @@
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_i_can_administer' )}">Repositories I can administer</a>
|
||||
</div>
|
||||
%endif
|
||||
%if has_reviewed_repositories:
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='reviewed_repositories_i_own' )}">Reviewed repositories I own</a>
|
||||
</div>
|
||||
%endif
|
||||
%if has_deprecated_repositories:
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_deprecated_repositories_i_own' )}">Deprecated repositories I own</a>
|
||||
@@ -128,59 +122,6 @@
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='create_galaxy_docker_image' )}">Create Galaxy Docker Image</a>
|
||||
</div>
|
||||
%endif
|
||||
%if can_review_repositories:
|
||||
<div class="toolSectionPad"></div>
|
||||
<div class="toolSectionTitle">
|
||||
Reviewing Repositories
|
||||
</div>
|
||||
<div class="toolSectionBody">
|
||||
<div class="toolSectionBg">
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_repositories_ready_for_review' )}">Repositories ready for review</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_repositories_without_reviews' )}">All repositories with no reviews</a>
|
||||
</div>
|
||||
%if trans.user.repository_reviews:
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_repositories_reviewed_by_me' )}">Repositories reviewed by me</a>
|
||||
</div>
|
||||
%endif
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_repositories_with_reviews' )}">All reviewed repositories</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository_review', action='manage_components' )}">Manage review components</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toolSectionPad"></div>
|
||||
<div class="toolSectionTitle">
|
||||
Reviewing Repositories With Tools
|
||||
</div>
|
||||
<div class="toolSectionBody">
|
||||
<div class="toolSectionBg">
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_missing_tool_test_components' )}">Latest revision: missing tool tests</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_with_install_errors' )}">Latest revision: installation errors</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_with_failing_tool_tests' )}">Latest revision: failing tool tests</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_with_skip_tool_test_checked' )}">Latest revision: skip tool tests</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_with_no_failing_tool_tests' )}">Latest revision: all tool tests pass</a>
|
||||
</div>
|
||||
<div class="toolTitle">
|
||||
<a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories_with_invalid_tools' )}">Latest revision: invalid tools</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
%else:
|
||||
<div class="toolSectionPad"></div>
|
||||
<div class="toolSectionTitle">
|
||||
|
||||
@@ -38,11 +38,6 @@
|
||||
else:
|
||||
can_download = False
|
||||
|
||||
if has_metadata and not is_deprecated and trans.app.security_agent.user_can_review_repositories( trans.user ):
|
||||
can_review_repository = True
|
||||
else:
|
||||
can_review_repository = False
|
||||
|
||||
if not is_new and not is_deprecated:
|
||||
can_set_metadata = True
|
||||
else:
|
||||
@@ -132,11 +127,7 @@ ${render_tool_shed_repository_actions( repository, metadata=metadata, changeset_
|
||||
<div class="form-row">
|
||||
${render_select(changeset_revision_select_field)} <i>${tip_str}</i>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
%if can_review_repository:
|
||||
Select a revision to inspect for adding or managing a review or for download or installation.
|
||||
%else:
|
||||
Select a revision to inspect for download or installation.
|
||||
%endif
|
||||
Select a revision to inspect for download or installation.
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -343,47 +334,6 @@ ${render_repository_items( metadata, containers_dict, can_set_metadata=True, ren
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormBody">
|
||||
%if display_reviews:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='view_repository', id=trans.security.encode_id( repository.id ), display_reviews=False )}"><label>Hide Reviews</label></a>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rating</th>
|
||||
<th>Comments</th>
|
||||
<th>Reviewed</th>
|
||||
<th>User</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<% count = 0 %>
|
||||
%for review in repository.ratings:
|
||||
<%
|
||||
count += 1
|
||||
name = 'rating%d' % count
|
||||
%>
|
||||
<tr>
|
||||
<td>${render_star_rating( name, review.rating, disabled=True )}</td>
|
||||
<td>${render_review_comment( to_html_string( review.comment ) )}</td>
|
||||
<td>${time_ago( review.update_time )}</td>
|
||||
<td>${review.user.username | h}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='view_repository', id=trans.security.encode_id( repository.id ), display_reviews=True )}"><label>Display Reviews</label></a>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
<p/>
|
||||
%if can_set_malicious:
|
||||
|
||||
@@ -92,19 +92,6 @@ ${render_tool_shed_repository_actions( repository, metadata=None, changeset_revi
|
||||
${render_star_rating( 'rating', rating )}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Review:</label>
|
||||
%if rra and rra.comment:
|
||||
<div class="form-row-input">
|
||||
<pre><textarea name="comment" rows="5" cols="80">${rra.comment | h}</textarea></pre>
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row-input">
|
||||
<textarea name="comment" rows="5" cols="80"></textarea>
|
||||
</div>
|
||||
%endif
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="rate_button" id="rate_button" value="Submit" />
|
||||
</div>
|
||||
@@ -112,42 +99,4 @@ ${render_tool_shed_repository_actions( repository, metadata=None, changeset_revi
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
%if repository.ratings and ( len( repository.ratings ) > 1 or repository.ratings[0] != rra ):
|
||||
<div class="toolForm">
|
||||
<div class="toolFormBody">
|
||||
%if display_reviews:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ), display_reviews=False )}"><label>Hide Reviews</label></a>
|
||||
</div>
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rating</th>
|
||||
<th>Comments</th>
|
||||
<th>Reviewed</th>
|
||||
<th>User</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<% count = 0 %>
|
||||
%for review in repository.ratings:
|
||||
<%
|
||||
count += 1
|
||||
name = 'rating%d' % count
|
||||
%>
|
||||
<tr>
|
||||
<td>${render_star_rating( name, review.rating, disabled=True )}</td>
|
||||
<td><pre>${review.comment | h}</pre></td>
|
||||
<td>${time_ago( review.update_time )}</td>
|
||||
<td>${review.user.username | h}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='rate_repository', id=trans.security.encode_id( repository.id ), display_reviews=True )}"><label>Display Reviews</label></a>
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
|
||||
@@ -230,47 +230,5 @@ ${render_repository_items( metadata, containers_dict, can_set_metadata=False, re
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormBody">
|
||||
%if display_reviews:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='view_repository', id=trans.security.encode_id( repository.id ), display_reviews=False )}"><label>Hide Reviews</label></a>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Rating</th>
|
||||
<th>Comments</th>
|
||||
<th>Reviewed</th>
|
||||
<th>User</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<% count = 0 %>
|
||||
%for review in repository.ratings:
|
||||
<%
|
||||
count += 1
|
||||
name = 'rating%d' % count
|
||||
%>
|
||||
<tr>
|
||||
<td>${render_star_rating( name, review.rating, disabled=True )}</td>
|
||||
<td>${render_review_comment( to_html_string( review.comment ) )}</td>
|
||||
<td>${time_ago( review.update_time )}</td>
|
||||
<td>${review.user.username}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
<a href="${h.url_for( controller='repository', action='view_repository', id=trans.security.encode_id( repository.id ), display_reviews=True )}"><label>Display Reviews</label></a>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
<p/>
|
||||
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
|
||||
|
||||
<%
|
||||
from galaxy.web.form_builder import CheckboxField
|
||||
from tool_shed.util.container_util import STRSEP
|
||||
from tool_shed.util.basic_util import to_html_string
|
||||
%>
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${h.css('base')}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
</%def>
|
||||
|
||||
${render_tool_shed_repository_actions( repository=repository, changeset_revision=review.changeset_revision )}
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Review of repository '${repository.name | h}'</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Reviewer:</label>
|
||||
${review.user.username}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Repository revision:</label>
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label}</a>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Repository owner:</label>
|
||||
${repository.user.username | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Repository synopsis:</label>
|
||||
${repository.description | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
%if review.component_reviews:
|
||||
<table class="grid">
|
||||
%for component_review in review.component_reviews:
|
||||
<%
|
||||
can_browse = trans.app.security_agent.user_can_browse_component_review( trans.app, repository, component_review, trans.user )
|
||||
component = component_review.component
|
||||
if can_browse:
|
||||
# Initialize Private check box.
|
||||
private_check_box_name = '%s%sprivate' % ( component.name, STRSEP )
|
||||
private_check_box = CheckboxField( name=private_check_box_name, value=component_review.private )
|
||||
|
||||
# Initialize star rating.
|
||||
rating_name = '%s%srating' % ( component.name, STRSEP )
|
||||
%>
|
||||
<tr>
|
||||
<td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
|
||||
<td bgcolor="#D8D8D8">${component.description | h}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
%if can_browse:
|
||||
<table class="grid">
|
||||
<tr>
|
||||
<td>
|
||||
<label>Private:</label>
|
||||
${render_checkbox(private_check_box, disabled=True)}
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
A private review can be accessed only by the owner of the repository and authorized repository reviewers.
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
%if component_review.comment:
|
||||
<tr>
|
||||
<td>
|
||||
<div overflow-wrap:normal;overflow:hidden;word-break:keep-all;word-wrap:break-word;line-break:strict;>
|
||||
${ to_html_string( component_review.comment ) }
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
%endif
|
||||
<tr>
|
||||
<td>
|
||||
<label>Approved:</label>
|
||||
${component_review.approved | h}
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label>Rating:</label>
|
||||
${render_star_rating( rating_name, component_review.rating, disabled=True )}
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
%else:
|
||||
You are not authorized to access the review of this component since it has been marked private.
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
%else:
|
||||
This review has not yet been started.
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$("input:text:first").focus();
|
||||
})
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Create Component</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="create_component" id="create_component" action="${h.url_for( controller='repository_review', action='create_component' )}" method="post" >
|
||||
<div class="form-row">
|
||||
<label>Name:</label>
|
||||
<input name="name" type="textfield" value="${name | h}" size=40"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Description:</label>
|
||||
<input name="description" type="textfield" value="${description | h}" size=40"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="create_component_button" value="Save"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Change component description</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="edit_component" action="${h.url_for( controller='repository_review', action='edit_component' )}" method="post" >
|
||||
<div class="form-row">
|
||||
<label>Name:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
${component.name | h}
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Description:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input name="description" type="textfield" value="${component.description | h}" size=40"/>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="hidden" name="id" value="${trans.security.encode_id( component.id )}"/>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="edit_component_button" value="Save"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,162 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
|
||||
|
||||
<%
|
||||
from galaxy.web.form_builder import CheckboxField
|
||||
from tool_shed.grids.util import build_approved_select_field
|
||||
from tool_shed.util.container_util import STRSEP
|
||||
%>
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${h.css('base')}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
</%def>
|
||||
|
||||
${render_tool_shed_repository_actions( repository=repository, changeset_revision=review.changeset_revision )}
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">My review of repository '${repository.name | h}'</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="edit_review" action="${h.url_for( controller='repository_review', action='edit_review', id=trans.security.encode_id( review.id ) )}" method="post" >
|
||||
<div class="form-row">
|
||||
<label>Repository revision:</label>
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=review.changeset_revision )}">${changeset_revision_label}</a>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Repository owner:</label>
|
||||
${repository.user.username | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Repository synopsis:</label>
|
||||
${repository.description | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Approve this repository revision?</label>
|
||||
${render_select(revision_approved_select_field)}
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Individual components below may be approved without approving the repository revision.
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="revision_approved_button" value="Save"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
All changes made on this page will be saved when any <b>Save</b> button is clicked.
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
%for component_name, component_review_dict in components_dict.items():
|
||||
<%
|
||||
component = component_review_dict[ 'component' ]
|
||||
encoded_component_id = trans.security.encode_id( component.id )
|
||||
|
||||
component_review = component_review_dict[ 'component_review' ]
|
||||
if component_review:
|
||||
comment = component_review.comment or ''
|
||||
rating = component_review.rating
|
||||
approved_select_field_selected_value = component_review.approved
|
||||
private = component_review.private
|
||||
else:
|
||||
comment = ''
|
||||
rating = 0
|
||||
approved_select_field_selected_value = None
|
||||
private = False
|
||||
|
||||
# Initialize Approved select field.
|
||||
approved_select_field_name = '%s%sapproved' % ( component_name, STRSEP )
|
||||
approved_select_field = build_approved_select_field( trans, name=approved_select_field_name, selected_value=approved_select_field_selected_value, for_component=True )
|
||||
|
||||
# Initialize Private check box.
|
||||
private_check_box_name = '%s%sprivate' % ( component_name, STRSEP )
|
||||
private_check_box = CheckboxField( name=private_check_box_name, value=private )
|
||||
|
||||
# Initialize star rating.
|
||||
rating_name = '%s%srating' % ( component_name, STRSEP )
|
||||
|
||||
# Initialize comment text area.
|
||||
comment_name = '%s%scomment' % ( component_name, STRSEP )
|
||||
|
||||
# Initialize the component id form field name.
|
||||
component_id_name = '%s%scomponent_id' % ( component_name, STRSEP )
|
||||
|
||||
# Initialize the Save button.
|
||||
review_button_name = '%s%sreview_button' % ( component_name, STRSEP )
|
||||
%>
|
||||
<tr>
|
||||
<td bgcolor="#D8D8D8"><b>${component.name | h}</b></td>
|
||||
<td bgcolor="#D8D8D8">${component.description | h}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<table class="grid">
|
||||
<tr>
|
||||
<td>
|
||||
<label>Mark private:</label>
|
||||
${render_checkbox(private_check_box)}
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
A private review can be accessed only by the owner of the repository and authorized repository reviewers.
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label>Comments:</label>
|
||||
%if component_review:
|
||||
<pre><textarea name="${comment_name}" rows="3" cols="80">${comment | h}</textarea></pre>
|
||||
%else:
|
||||
<textarea name="${comment_name}" rows="3" cols="80"></textarea>
|
||||
%endif
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label>Approved:</label>
|
||||
${render_select(approved_select_field)}
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label>Rating:</label>
|
||||
${render_star_rating( rating_name, rating )}
|
||||
<div style="clear: both"></div>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Rate this component only - the average of all component ratings defines the value of the repository rating.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="hidden" name="${component_id_name}" value="${encoded_component_id}"/>
|
||||
<input type="submit" name="${review_button_name}" value="Save"/>
|
||||
<div style="clear: both"></div>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
All changes made on this page will be saved when any <b>Save</b> button is clicked.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
<%inherit file="/legacy/grid_base.mako"/>
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/repository/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
|
||||
|
||||
<%
|
||||
from tool_shed.grids.util import build_approved_select_field
|
||||
from tool_shed.util.container_util import STRSEP
|
||||
|
||||
if installable:
|
||||
installable_str = 'yes'
|
||||
else:
|
||||
installable_str = 'no'
|
||||
can_review_repositories = trans.app.security_agent.user_can_review_repositories( trans.user )
|
||||
%>
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
if context.get('use_panels'):
|
||||
return '/webapps/tool_shed/base_panels.mako'
|
||||
else:
|
||||
return '/base.mako'
|
||||
%>
|
||||
<%inherit file="${inherit(context)}"/>
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${h.css('base')}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${common_javascripts(repository)}
|
||||
</%def>
|
||||
|
||||
${render_tool_shed_repository_actions( repository=repository, changeset_revision=changeset_revision )}
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Revision reviews of repository '${repository.name | h}'</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Revision:</label>
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Revision is installable:</label>
|
||||
${installable_str | h}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
%if reviews:
|
||||
<table class="grid">
|
||||
<tr>
|
||||
<th>Reviewer</th>
|
||||
<th>Repository rating</th>
|
||||
<th>Approved</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
%for review in reviews:
|
||||
<%
|
||||
encoded_review_id = trans.security.encode_id( review.id )
|
||||
approved_select_field_name = '%s%sapproved' % ( encoded_review_id, STRSEP )
|
||||
approved_select_field_selected_value = review.approved
|
||||
approved_select_field = build_approved_select_field( trans, name=approved_select_field_name, selected_value=approved_select_field_selected_value, for_component=False )
|
||||
if review.approved not in [ None, 'None', 'none' ]:
|
||||
approved_str = review.approved
|
||||
else:
|
||||
approved_str = ''
|
||||
repository_rating_name = '%srepository_rating' % encoded_review_id
|
||||
%>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
|
||||
<a class="view-info" href="${h.url_for( controller='repository_review', action='repository_reviews_by_user', id=trans.security.encode_id( review.user.id ) )}">${review.user.username | h}</a>
|
||||
</div>
|
||||
<div popupmenu="${encoded_review_id}-popup">
|
||||
%if review.user == trans.user:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='edit_review', id=encoded_review_id )}">Edit my review</a>
|
||||
%else:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">Browse this review</a>
|
||||
%endif
|
||||
</div>
|
||||
</td>
|
||||
<td>${render_star_rating( repository_rating_name, review.rating, disabled=True )}</td>
|
||||
%if review.user == trans.user:
|
||||
<form name="approve_repository_review" action="${h.url_for( controller='repository_review', action='approve_repository_review', id=encoded_review_id ) }" method="post" >
|
||||
<td>${render_select(approved_select_field)}</td>
|
||||
<td><input type="submit" name="approve_repository_review_button" value="Save"/></td>
|
||||
</form>
|
||||
%else:
|
||||
<td>${approved_str | h}</td>
|
||||
<td></td>
|
||||
%endif
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
%else:
|
||||
<label>This repository revision has not yet been reviewed:</label>
|
||||
%if can_review_repositories:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Add a review to this revision</a>
|
||||
<div style="clear: both"></div>
|
||||
%endif
|
||||
%endif
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</div>
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/repository/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
|
||||
|
||||
<%
|
||||
if mine:
|
||||
title = "My reviews of repository '%s'" % repository.name
|
||||
else:
|
||||
title = "All reviews of repository '%s'" % repository.name
|
||||
%>
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
if context.get('use_panels'):
|
||||
return '/webapps/tool_shed/base_panels.mako'
|
||||
else:
|
||||
return '/base.mako'
|
||||
%>
|
||||
<%inherit file="${inherit(context)}"/>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${common_javascripts(repository)}
|
||||
</%def>
|
||||
|
||||
${render_tool_shed_repository_actions( repository=repository )}
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">${title | h}</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<tr>
|
||||
<th>Revision</th>
|
||||
<th>Reviewers</th>
|
||||
<th>Installable</th>
|
||||
</tr>
|
||||
%for changeset_revision, revision_dict in reviews_dict.items():
|
||||
<%
|
||||
changeset_revision_label = revision_dict[ 'changeset_revision_label' ]
|
||||
repository_reviews = revision_dict[ 'repository_reviews' ]
|
||||
repository_metadata_reviews = revision_dict[ 'repository_metadata_reviews' ]
|
||||
reviewers_str = ''
|
||||
if repository_reviews:
|
||||
for repository_review in repository_reviews:
|
||||
reviewers_str += '<a class="view-info" href="'
|
||||
if repository_review.user == trans.user:
|
||||
reviewers_str += 'edit_review'
|
||||
else:
|
||||
reviewers_str += 'browse_review'
|
||||
reviewers_str += '?id=%s">%s</a>' % ( trans.security.encode_id( repository_review.id ), repository_review.user.username )
|
||||
reviewers_str += ' | '
|
||||
reviewers_str = reviewers_str.rstrip( '| ' )
|
||||
if revision_dict[ 'installable' ]:
|
||||
installable_str = 'yes'
|
||||
else:
|
||||
installable_str = ''
|
||||
can_add_review = revision_dict[ 'can_add_review' ]
|
||||
%>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="float:left;" class="menubutton split popup" id="${changeset_revision}-popup">
|
||||
<a class="view-info" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
|
||||
</div>
|
||||
<div popupmenu="${changeset_revision}-popup">
|
||||
%if repository_reviews:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='manage_repository_reviews_of_revision', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Browse reviews of this revision</a>
|
||||
%elif can_add_review:
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">Add a review to this revision</a>
|
||||
%endif
|
||||
</div>
|
||||
</td>
|
||||
<td>${reviewers_str}</td>
|
||||
<td>${installable_str | h}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</div>
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/webapps/tool_shed/common/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/repository/common.mako" import="*" />
|
||||
<%namespace file="/webapps/tool_shed/common/repository_actions_menu.mako" import="render_tool_shed_repository_actions" />
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
if context.get('use_panels'):
|
||||
return '/webapps/tool_shed/base_panels.mako'
|
||||
else:
|
||||
return '/base.mako'
|
||||
%>
|
||||
<%inherit file="${inherit(context)}"/>
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${h.css('base')}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${common_javascripts(repository)}
|
||||
</%def>
|
||||
|
||||
${render_tool_shed_repository_actions( repository=repository )}
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="warningmessage">
|
||||
You have elected to create a new review for revision <b>${changeset_revision_label}</b>of this repository. Since previous revisions have been reviewed,
|
||||
you can select a previous review to copy to your new review, or click the <b>Create a review without copying</b> button.
|
||||
</div>
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Select previous revision review of repository '${repository.name | h}'</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Revision for new review:</label>
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='view_or_manage_repository', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision )}">${changeset_revision_label}</a>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<tr>
|
||||
</tr>
|
||||
<td bgcolor="#D8D8D8" colspan="4"><b>Previous revision reviews of repository '${repository.name | h}' that can be copied to your new review</b></td>
|
||||
<tr>
|
||||
<th>Reviewer</th>
|
||||
<th>Revision reviewed</th>
|
||||
<th>Repository rating</th>
|
||||
<th>Approved</th>
|
||||
</tr>
|
||||
%for previous_changeset_revision, previous_changeset_revision_dict in previous_reviews_dict.items():
|
||||
<%
|
||||
previous_changeset_revision_label = previous_changeset_revision_dict[ 'changeset_revision_label' ]
|
||||
previous_reviews = previous_changeset_revision_dict[ 'reviews' ]
|
||||
%>
|
||||
%for review in previous_reviews:
|
||||
<%
|
||||
encoded_review_id = trans.security.encode_id( review.id )
|
||||
if review.approved not in [ None, 'None', 'none' ]:
|
||||
approved_str = review.approved
|
||||
else:
|
||||
approved_str = ''
|
||||
repository_rating_name = '%srepository_rating' % encoded_review_id
|
||||
%>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="float:left;" class="menubutton split popup" id="${encoded_review_id}-popup">
|
||||
<a class="view-info" href="${h.url_for( controller='repository_review', action='browse_review', id=encoded_review_id )}">${review.user.username | h}</a>
|
||||
</div>
|
||||
<div popupmenu="${encoded_review_id}-popup">
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.security.encode_id( repository.id ), changeset_revision=changeset_revision, previous_review_id=encoded_review_id )}">Copy this review</a>
|
||||
</div>
|
||||
</td>
|
||||
<td>${previous_changeset_revision_label}</td>
|
||||
<td>${render_star_rating( repository_rating_name, review.rating, disabled=True )}</td>
|
||||
<td>${approved_str | h}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<a class="action-button" href="${h.url_for( controller='repository_review', action='create_review', id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, create_without_copying=True )}">Create a review without copying</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,69 +94,6 @@ class TestCategory(BaseTest):
|
||||
assert stored_obj.repositories == [repository_category_association]
|
||||
|
||||
|
||||
class TestComponent(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "component"
|
||||
|
||||
def test_columns(self, session, cls_):
|
||||
name, description = "a", "b"
|
||||
obj = cls_(name=name, description=description)
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.id == obj_id
|
||||
assert stored_obj.name == name
|
||||
assert stored_obj.description == description
|
||||
|
||||
|
||||
class TestComponentReview(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "component_review"
|
||||
|
||||
def test_columns(self, session, cls_, repository_review, component):
|
||||
create_time = datetime.now()
|
||||
update_time = create_time + timedelta(hours=1)
|
||||
comment = "a"
|
||||
private = True
|
||||
approved = "b"
|
||||
rating = 1
|
||||
deleted = True
|
||||
|
||||
obj = cls_()
|
||||
obj.create_time = create_time
|
||||
obj.update_time = update_time
|
||||
obj.repository_review = repository_review
|
||||
obj.component = component
|
||||
obj.comment = comment
|
||||
obj.private = private
|
||||
obj.approved = approved
|
||||
obj.rating = rating
|
||||
obj.deleted = deleted
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.id == obj_id
|
||||
assert stored_obj.create_time == create_time
|
||||
assert stored_obj.update_time == update_time
|
||||
assert stored_obj.repository_review_id == repository_review.id
|
||||
assert stored_obj.component_id == component.id
|
||||
assert stored_obj.comment == comment
|
||||
assert stored_obj.private == private
|
||||
assert stored_obj.approved == approved
|
||||
assert stored_obj.rating == rating
|
||||
assert stored_obj.deleted == deleted
|
||||
|
||||
def test_relationships(self, session, cls_, repository_review, component):
|
||||
obj = cls_()
|
||||
obj.repository_review = repository_review
|
||||
obj.component = component
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.repository_review.id == repository_review.id
|
||||
assert stored_obj.component.id == component.id
|
||||
|
||||
|
||||
class TestGalaxySession(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "galaxy_session"
|
||||
@@ -364,9 +301,7 @@ class TestRepository(BaseTest):
|
||||
repository_rating_association,
|
||||
repository_metadata_factory,
|
||||
repository_role_association,
|
||||
repository_review_factory,
|
||||
user,
|
||||
user_factory,
|
||||
):
|
||||
obj = cls_()
|
||||
obj.user = user
|
||||
@@ -374,16 +309,6 @@ class TestRepository(BaseTest):
|
||||
obj.ratings.append(repository_rating_association)
|
||||
obj.roles.append(repository_role_association)
|
||||
|
||||
reviewer1 = user_factory()
|
||||
review1 = repository_review_factory()
|
||||
review1.user = reviewer1
|
||||
review1.repository = obj
|
||||
|
||||
reviewer2 = user_factory()
|
||||
review2 = repository_review_factory()
|
||||
review2.user = reviewer2
|
||||
review2.repository = obj
|
||||
|
||||
metadata1 = repository_metadata_factory()
|
||||
metadata1.repository = obj
|
||||
metadata1.downloadable = False
|
||||
@@ -400,12 +325,10 @@ class TestRepository(BaseTest):
|
||||
assert stored_obj.categories == [repository_category_association]
|
||||
assert stored_obj.ratings == [repository_rating_association]
|
||||
assert stored_obj.roles == [repository_role_association]
|
||||
assert collection_consists_of_objects(stored_obj.reviews, review1, review2)
|
||||
assert collection_consists_of_objects(stored_obj.reviewers, reviewer1, reviewer2)
|
||||
assert collection_consists_of_objects(stored_obj.metadata_revisions, metadata1, metadata2)
|
||||
assert stored_obj.downloadable_revisions == [metadata2]
|
||||
|
||||
delete_from_database(session, [reviewer1, reviewer2, review1, review2, metadata1, metadata2])
|
||||
delete_from_database(session, [metadata1, metadata2])
|
||||
|
||||
|
||||
class TestRepositoryCategoryAssociation(BaseTest):
|
||||
@@ -491,7 +414,6 @@ class TestRepositoryMetadata(BaseTest):
|
||||
session,
|
||||
cls_,
|
||||
repository,
|
||||
repository_review_factory,
|
||||
user,
|
||||
):
|
||||
|
||||
@@ -499,38 +421,6 @@ class TestRepositoryMetadata(BaseTest):
|
||||
obj.repository = repository
|
||||
obj.changeset_revision = "nonempty"
|
||||
|
||||
# create 3 reviews
|
||||
review1 = repository_review_factory()
|
||||
review2 = repository_review_factory()
|
||||
review3 = repository_review_factory()
|
||||
|
||||
# set the same user for all reviews
|
||||
review1.user = user
|
||||
review2.user = user
|
||||
review3.user = user
|
||||
|
||||
# set the same repository for all reviews
|
||||
review1.repository = obj.repository
|
||||
review2.repository = obj.repository
|
||||
review3.repository = obj.repository
|
||||
|
||||
# set the same changeset for reviews 1,2
|
||||
review1.changeset_revision = obj.changeset_revision
|
||||
review2.changeset_revision = obj.changeset_revision
|
||||
review3.changeset_revision = "something else" # this won't be in reviews for this metadata
|
||||
|
||||
# add to session
|
||||
session.add(review1)
|
||||
session.add(review2)
|
||||
session.add(review3)
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.repository.id == repository.id
|
||||
assert collection_consists_of_objects(stored_obj.reviews, review1, review2)
|
||||
|
||||
delete_from_database(session, [review1, review2, review3])
|
||||
|
||||
|
||||
class TestRepositoryRatingAssociation(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
@@ -571,106 +461,6 @@ class TestRepositoryRatingAssociation(BaseTest):
|
||||
assert stored_obj.user.id == user.id
|
||||
|
||||
|
||||
class TestRepositoryReview(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "repository_review"
|
||||
|
||||
def test_columns(self, session, cls_, repository, user):
|
||||
create_time = datetime.now()
|
||||
update_time = create_time + timedelta(hours=1)
|
||||
changeset_revision = "a"
|
||||
approved = "b"
|
||||
rating = 1
|
||||
deleted = True
|
||||
|
||||
obj = cls_()
|
||||
obj.create_time = create_time
|
||||
obj.update_time = update_time
|
||||
obj.repository = repository
|
||||
obj.changeset_revision = changeset_revision
|
||||
obj.user = user
|
||||
obj.approved = approved
|
||||
obj.rating = rating
|
||||
obj.deleted = deleted
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.id == obj_id
|
||||
assert stored_obj.create_time == create_time
|
||||
assert stored_obj.update_time == update_time
|
||||
assert stored_obj.repository_id == repository.id
|
||||
assert stored_obj.changeset_revision == changeset_revision
|
||||
assert stored_obj.user_id == user.id
|
||||
assert stored_obj.approved == approved
|
||||
assert stored_obj.rating == rating
|
||||
assert stored_obj.deleted == deleted
|
||||
|
||||
def test_relationships(
|
||||
self, session, cls_, repository, user, repository_metadata_factory, component_review_factory
|
||||
):
|
||||
obj = cls_()
|
||||
changeset = "nonempty"
|
||||
obj.changeset_revision = changeset
|
||||
obj.repository = repository
|
||||
obj.user = user
|
||||
|
||||
metadata1 = repository_metadata_factory()
|
||||
metadata2 = repository_metadata_factory()
|
||||
metadata1.repository = repository
|
||||
metadata2.repository = repository
|
||||
metadata1.changeset_revision = changeset
|
||||
metadata2.changeset_revision = "something else"
|
||||
|
||||
component_review1 = component_review_factory()
|
||||
component_review1.repository_review = obj
|
||||
component_review1.deleted = False
|
||||
|
||||
component_review2 = component_review_factory()
|
||||
component_review2.repository_review = obj
|
||||
component_review2.deleted = False
|
||||
component_review2.private = True
|
||||
|
||||
session.add_all([metadata1, metadata2, component_review1, component_review2])
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.repository.id == repository.id
|
||||
assert stored_obj.user.id == user.id
|
||||
assert stored_obj.repository_metadata == metadata1
|
||||
assert collection_consists_of_objects(stored_obj.component_reviews, component_review1, component_review2)
|
||||
assert stored_obj.private_component_reviews == [component_review2]
|
||||
|
||||
delete_from_database(session, [component_review1, component_review2, metadata1, metadata2])
|
||||
|
||||
|
||||
class TestRepositoryRoleAssociation(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "repository_role_association"
|
||||
|
||||
def test_columns(self, session, cls_, repository, role):
|
||||
create_time = datetime.now()
|
||||
update_time = create_time + timedelta(hours=1)
|
||||
obj = cls_(repository, role)
|
||||
obj.create_time = create_time
|
||||
obj.update_time = update_time
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.id == obj_id
|
||||
assert stored_obj.repository_id == repository.id
|
||||
assert stored_obj.role_id == role.id
|
||||
assert stored_obj.create_time == create_time
|
||||
assert stored_obj.update_time == update_time
|
||||
|
||||
def test_relationships(self, session, cls_, repository, role):
|
||||
obj = cls_(repository, role)
|
||||
|
||||
with dbcleanup(session, obj) as obj_id:
|
||||
stored_obj = get_stored_obj(session, cls_, obj_id)
|
||||
assert stored_obj.repository.id == repository.id
|
||||
assert stored_obj.role.id == role.id
|
||||
|
||||
|
||||
class TestRole(BaseTest):
|
||||
def test_table(self, cls_):
|
||||
assert cls_.__tablename__ == "role"
|
||||
@@ -808,7 +598,6 @@ class TestUser(BaseTest):
|
||||
repository,
|
||||
galaxy_session,
|
||||
api_keys,
|
||||
repository_review,
|
||||
role,
|
||||
group,
|
||||
password_reset_token,
|
||||
@@ -825,7 +614,6 @@ class TestUser(BaseTest):
|
||||
obj.api_keys.append(api_keys)
|
||||
obj.reset_tokens.append(password_reset_token)
|
||||
obj.groups.append(user_group_association)
|
||||
obj.repository_reviews.append(repository_review)
|
||||
|
||||
_private_role = role_factory(name=obj.email)
|
||||
private_user_role = user_role_association_factory(obj, _private_role)
|
||||
@@ -842,7 +630,6 @@ class TestUser(BaseTest):
|
||||
assert stored_obj.api_keys == [api_keys]
|
||||
assert stored_obj.reset_tokens == [password_reset_token]
|
||||
assert stored_obj.groups == [user_group_association]
|
||||
assert stored_obj.repository_reviews == [repository_review]
|
||||
assert collection_consists_of_objects(stored_obj.roles, private_user_role, non_private_user_role)
|
||||
assert stored_obj.non_private_roles == [non_private_user_role]
|
||||
|
||||
@@ -948,12 +735,6 @@ def category(model, session):
|
||||
yield from dbcleanup_wrapper(session, instance)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def component(model, session):
|
||||
instance = model.Component()
|
||||
yield from dbcleanup_wrapper(session, instance)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def galaxy_session(model, session):
|
||||
instance = model.GalaxySession(session_key=get_unique_value())
|
||||
@@ -992,13 +773,6 @@ def repository_metadata(model, session):
|
||||
yield from dbcleanup_wrapper(session, instance)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repository_review(model, session, user):
|
||||
instance = model.RepositoryReview()
|
||||
instance.user = user
|
||||
yield from dbcleanup_wrapper(session, instance)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repository_category_association(model, session, repository, category):
|
||||
instance = model.RepositoryCategoryAssociation(repository, category)
|
||||
@@ -1044,14 +818,6 @@ def user_role_association(model, session, user, role):
|
||||
# Fixtures yielding factory functions.
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def component_review_factory(model):
|
||||
def make_instance(*args, **kwds):
|
||||
return model.ComponentReview(*args, **kwds)
|
||||
|
||||
return make_instance
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def group_role_association_factory(model):
|
||||
def make_instance(*args, **kwds):
|
||||
@@ -1068,14 +834,6 @@ def repository_metadata_factory(model):
|
||||
return make_instance
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def repository_review_factory(model):
|
||||
def make_instance(*args, **kwds):
|
||||
return model.RepositoryReview(*args, **kwds)
|
||||
|
||||
return make_instance
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def role_factory(model):
|
||||
def make_instance(*args, **kwds):
|
||||
|
||||
Reference in New Issue
Block a user