galaxy-commits
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2014
- 2 participants
- 245 discussions
7 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/2b6e21823ea7/
Changeset: 2b6e21823ea7
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: More ToolPanelManager unit testing.
Affected #: 1 file
diff -r 0587bc5413d66e85673d7b429bc04d34e47ad4c4 -r 2b6e21823ea70429b7913b913010f6501f10a601 test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
--- a/test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
+++ b/test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
@@ -101,6 +101,16 @@
assert "github.com/galaxyproect/example/test_tool/0.2" not in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
self._verify_tool_confs()
+ self._remove_guids( ["github.com/galaxyproect/example/test_tool/0.1"], uninstall=True )
+
+ # Now no versions of this tool are returned by toolbox.
+ all_versions = self.toolbox.get_tool( "test_tool", get_all_versions=True )
+ assert not all_versions
+
+ # Check that tool panel has reverted to old value...
+ section = self.toolbox.tool_panel["tid"]
+ assert len(section.elems) == 0
+
def _setup_two_versions_remove_one( self, section, uninstall ):
self._init_tool()
self._setup_two_versions_in_config( section=True )
https://bitbucket.org/galaxy/galaxy-central/commits/8ffb20fd4300/
Changeset: 8ffb20fd4300
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Eliminate repeated nested object access in ToolPanelManager.remove_guids.
Affected #: 1 file
diff -r 2b6e21823ea70429b7913b913010f6501f10a601 -r 8ffb20fd4300fbf3b4cc5ac21022e55cd2c1da68 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -445,10 +445,11 @@
self.remove_guids( guids_to_remove, shed_tool_conf, uninstall )
def remove_guids( self, guids_to_remove, shed_tool_conf, uninstall ):
+ toolbox = self.app.toolbox
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
- if guid_to_remove in self.app.toolbox.tools_by_id:
- del self.app.toolbox.tools_by_id[ guid_to_remove ]
+ if guid_to_remove in toolbox.tools_by_id:
+ del toolbox.tools_by_id[ guid_to_remove ]
index, shed_tool_conf_dict = self.get_shed_tool_conf_dict( shed_tool_conf )
if uninstall:
# Remove from the shed_tool_conf file on disk.
@@ -469,12 +470,12 @@
# Remove the tool sub-element from the section element.
config_elem.remove( tool_elem )
# Remove the tool from the section in the in-memory tool panel.
- if section_key in self.app.toolbox.tool_panel:
- tool_section = self.app.toolbox.tool_panel[ section_key ]
+ if section_key in toolbox.tool_panel:
+ tool_section = toolbox.tool_panel[ section_key ]
guid = tool_elem.get( 'guid' )
tool_key = 'tool_%s' % str( guid )
# Get the list of versions of this tool that are currently available in the toolbox.
- available_tool_versions = self.app.toolbox.get_loaded_tools_by_lineage( guid )
+ available_tool_versions = toolbox.get_loaded_tools_by_lineage( guid )
if tool_key in tool_section.elems:
if available_tool_versions:
available_tool_versions.reverse()
@@ -505,8 +506,8 @@
del tool_section.elems[ tool_key ]
if uninstall:
# Remove the tool from the section in the in-memory integrated tool panel.
- if section_key in self.app.toolbox.integrated_tool_panel:
- tool_section = self.app.toolbox.integrated_tool_panel[ section_key ]
+ if section_key in toolbox.integrated_tool_panel:
+ tool_section = toolbox.integrated_tool_panel[ section_key ]
tool_key = 'tool_%s' % str( tool_elem.get( 'guid' ) )
if tool_key in tool_section.elems:
del tool_section.elems[ tool_key ]
@@ -518,8 +519,8 @@
if guid in guids_to_remove:
tool_key = 'tool_%s' % str( config_elem.get( 'guid' ) )
# Get the list of versions of this tool that are currently available in the toolbox.
- available_tool_versions = self.app.toolbox.get_loaded_tools_by_lineage( guid )
- if tool_key in self.app.toolbox.tool_panel:
+ available_tool_versions = toolbox.get_loaded_tools_by_lineage( guid )
+ if tool_key in toolbox.tool_panel:
if available_tool_versions:
available_tool_versions.reverse()
replacement_tool_key = None
@@ -528,32 +529,32 @@
# the newest loaded version of the tool.
for available_tool_version in available_tool_versions:
available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
- if available_tool_version.id in self.app.toolbox.tool_panel.keys() or not available_tool_section_id:
+ if available_tool_version.id in toolbox.tool_panel.keys() or not available_tool_section_id:
replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
replacement_tool_version = available_tool_version
break
if replacement_tool_key and replacement_tool_version:
# Get the index of the tool_key in the tool_section.
- for tool_panel_index, key in enumerate( self.app.toolbox.tool_panel.keys() ):
+ for tool_panel_index, key in enumerate( toolbox.tool_panel.keys() ):
if key == tool_key:
break
# Remove the tool from the tool panel.
- del self.app.toolbox.tool_panel[ tool_key ]
+ del toolbox.tool_panel[ tool_key ]
# Add the replacement tool at the same location in the tool panel.
- self.app.toolbox.tool_panel.insert( tool_panel_index,
- replacement_tool_key,
- replacement_tool_version )
+ toolbox.tool_panel.insert( tool_panel_index,
+ replacement_tool_key,
+ replacement_tool_version )
else:
- del self.app.toolbox.tool_panel[ tool_key ]
+ del toolbox.tool_panel[ tool_key ]
else:
- del self.app.toolbox.tool_panel[ tool_key ]
+ del toolbox.tool_panel[ tool_key ]
if uninstall:
- if tool_key in self.app.toolbox.integrated_tool_panel:
- del self.app.toolbox.integrated_tool_panel[ tool_key ]
+ if tool_key in toolbox.integrated_tool_panel:
+ del toolbox.integrated_tool_panel[ tool_key ]
config_elems_to_remove.append( config_elem )
for config_elem in config_elems_to_remove:
# Remove the element from the in-memory list of elements.
config_elems.remove( config_elem )
# Update the config_elems of the in-memory shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
- self.app.toolbox.update_shed_config( index, shed_tool_conf_dict, integrated_panel_changes=uninstall )
+ toolbox.update_shed_config( index, shed_tool_conf_dict, integrated_panel_changes=uninstall )
https://bitbucket.org/galaxy/galaxy-central/commits/44dfa6fc2701/
Changeset: 44dfa6fc2701
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Reduce duplication/complexity in tool_panel_manager.py.
Big conditional in remove_guids switched on sectioned versus un-sectioned with very little difference in what was actually being done. This reduces the cyclomatic complexity of that method from 35 down to 26 (though it is still the most 'complex' method in that file by a wide margin).
Affected #: 1 file
diff -r 8ffb20fd4300fbf3b4cc5ac21022e55cd2c1da68 -r 44dfa6fc270161fb12a3f152d5f24f53d757cd29 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -446,6 +446,48 @@
def remove_guids( self, guids_to_remove, shed_tool_conf, uninstall ):
toolbox = self.app.toolbox
+
+ def remove_from_panel( tool_elem, has_elems, integrated_has_elems, section_key='' ):
+ # Hide tool from panel and promote next oldest version if
+ # available.
+ guid = tool_elem.get( 'guid' )
+ tool_key = 'tool_%s' % str( guid )
+ available_tool_versions = toolbox.get_loaded_tools_by_lineage( guid )
+ if tool_key in has_elems:
+ if available_tool_versions:
+ available_tool_versions.reverse()
+ replacement_tool_key = None
+ replacement_tool_version = None
+ # Since we are going to remove the tool from the section, replace it with
+ # the newest loaded version of the tool.
+ for available_tool_version in available_tool_versions:
+ available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
+ # I suspect "available_tool_version.id in has_elems.keys()" doesn't
+ # belong in the following line or at least I don't understand what
+ # purpose it might serve. -John
+ if available_tool_version.id in has_elems.keys() or (available_tool_section_id == section_key):
+ replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
+ replacement_tool_version = available_tool_version
+ break
+ if replacement_tool_key and replacement_tool_version:
+ # Get the index of the tool_key in the tool_section.
+ for tool_panel_index, key in enumerate( has_elems.keys() ):
+ if key == tool_key:
+ break
+ # Remove the tool from the tool panel.
+ del has_elems[ tool_key ]
+ # Add the replacement tool at the same location in the tool panel.
+ has_elems.insert( tool_panel_index,
+ replacement_tool_key,
+ replacement_tool_version )
+ else:
+ del has_elems[ tool_key ]
+ else:
+ del has_elems[ tool_key ]
+ if uninstall:
+ if tool_key in toolbox.integrated_tool_panel:
+ del toolbox.integrated_tool_panel[ tool_key ]
+
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
if guid_to_remove in toolbox.tools_by_id:
@@ -472,85 +514,15 @@
# Remove the tool from the section in the in-memory tool panel.
if section_key in toolbox.tool_panel:
tool_section = toolbox.tool_panel[ section_key ]
- guid = tool_elem.get( 'guid' )
- tool_key = 'tool_%s' % str( guid )
- # Get the list of versions of this tool that are currently available in the toolbox.
- available_tool_versions = toolbox.get_loaded_tools_by_lineage( guid )
- if tool_key in tool_section.elems:
- if available_tool_versions:
- available_tool_versions.reverse()
- replacement_tool_key = None
- replacement_tool_version = None
- # Since we are going to remove the tool from the section, replace it with the
- # newest loaded version of the tool.
- for available_tool_version in available_tool_versions:
- available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
- if available_tool_version.id in tool_section.elems.keys() or section_key == available_tool_section_id:
- replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
- replacement_tool_version = available_tool_version
- break
- if replacement_tool_key and replacement_tool_version:
- # Get the index of the tool_key in the tool_section.
- for tool_section_elems_index, key in enumerate( tool_section.elems.keys() ):
- if key == tool_key:
- break
- # Remove the tool from the tool section.
- del tool_section.elems[ tool_key ]
- # Add the replacement tool at the same location in the tool section.
- tool_section.elems.insert( tool_section_elems_index,
- replacement_tool_key,
- replacement_tool_version )
- else:
- del tool_section.elems[ tool_key ]
- else:
- del tool_section.elems[ tool_key ]
- if uninstall:
- # Remove the tool from the section in the in-memory integrated tool panel.
- if section_key in toolbox.integrated_tool_panel:
- tool_section = toolbox.integrated_tool_panel[ section_key ]
- tool_key = 'tool_%s' % str( tool_elem.get( 'guid' ) )
- if tool_key in tool_section.elems:
- del tool_section.elems[ tool_key ]
+ remove_from_panel( tool_elem, tool_section.elems, toolbox.integrated_tool_panel.get( section_key, {} ), section_key=section_key )
if len( config_elem ) < 1:
# Keep a list of all empty section elements so they can be removed.
config_elems_to_remove.append( config_elem )
elif config_elem.tag == 'tool':
guid = config_elem.get( 'guid' )
if guid in guids_to_remove:
- tool_key = 'tool_%s' % str( config_elem.get( 'guid' ) )
- # Get the list of versions of this tool that are currently available in the toolbox.
- available_tool_versions = toolbox.get_loaded_tools_by_lineage( guid )
- if tool_key in toolbox.tool_panel:
- if available_tool_versions:
- available_tool_versions.reverse()
- replacement_tool_key = None
- replacement_tool_version = None
- # Since we are going to remove the tool from the section, replace it with
- # the newest loaded version of the tool.
- for available_tool_version in available_tool_versions:
- available_tool_section_id, available_tool_section_name = available_tool_version.get_panel_section()
- if available_tool_version.id in toolbox.tool_panel.keys() or not available_tool_section_id:
- replacement_tool_key = 'tool_%s' % str( available_tool_version.id )
- replacement_tool_version = available_tool_version
- break
- if replacement_tool_key and replacement_tool_version:
- # Get the index of the tool_key in the tool_section.
- for tool_panel_index, key in enumerate( toolbox.tool_panel.keys() ):
- if key == tool_key:
- break
- # Remove the tool from the tool panel.
- del toolbox.tool_panel[ tool_key ]
- # Add the replacement tool at the same location in the tool panel.
- toolbox.tool_panel.insert( tool_panel_index,
- replacement_tool_key,
- replacement_tool_version )
- else:
- del toolbox.tool_panel[ tool_key ]
- else:
- del toolbox.tool_panel[ tool_key ]
- if uninstall:
- if tool_key in toolbox.integrated_tool_panel:
- del toolbox.integrated_tool_panel[ tool_key ]
+ # get_panel_section return '' for un-sectioned tools.
+ remove_from_panel( config_elem, toolbox.tool_panel, toolbox.integrated_tool_panel, section_key='' )
config_elems_to_remove.append( config_elem )
for config_elem in config_elems_to_remove:
# Remove the element from the in-memory list of elements.
https://bitbucket.org/galaxy/galaxy-central/commits/01293fc1f167/
Changeset: 01293fc1f167
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Abstract out ToolBox internals from tool_shed.util.tool_util.
Instead of reloading upload actions at this level and exposing tools_by_id - move this logic into the ToolBox in a new method called handle_datatypes_changed().
Affected #: 2 files
diff -r 44dfa6fc270161fb12a3f152d5f24f53d757cd29 -r 01293fc1f16715121524b987fcab031f3e149a02 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -34,6 +34,7 @@
from galaxy import exceptions
from galaxy.tools import watcher
from galaxy.tools.actions import DefaultToolAction
+from galaxy.tools.actions.upload import UploadToolAction
from galaxy.tools.actions.data_source import DataSourceToolAction
from galaxy.tools.actions.data_manager import DataManagerToolAction
from galaxy.tools.deps import build_dependency_manager
@@ -992,6 +993,13 @@
def init_dependency_manager( self ):
self.dependency_manager = build_dependency_manager( self.app.config )
+ def handle_datatypes_changed( self ):
+ """ Refresh upload tools when new datatypes are added. """
+ for tool_id in self.tools_by_id:
+ tool = self.tools_by_id[ tool_id ]
+ if isinstance( tool.tool_action, UploadToolAction ):
+ self.reload_tool_by_id( tool_id )
+
@property
def sa_session( self ):
"""
diff -r 44dfa6fc270161fb12a3f152d5f24f53d757cd29 -r 01293fc1f16715121524b987fcab031f3e149a02 lib/tool_shed/util/tool_util.py
--- a/lib/tool_shed/util/tool_util.py
+++ b/lib/tool_shed/util/tool_util.py
@@ -260,7 +260,4 @@
def reload_upload_tools( app ):
if hasattr( app, 'toolbox' ):
- for tool_id in app.toolbox.tools_by_id:
- tool = app.toolbox.tools_by_id[ tool_id ]
- if isinstance( tool.tool_action, UploadToolAction ):
- app.toolbox.reload_tool_by_id( tool_id )
+ app.toolbox.handle_datatypes_changed()
https://bitbucket.org/galaxy/galaxy-central/commits/7716c8fbb891/
Changeset: 7716c8fbb891
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Centralize abstraction for removing tools from toolbox.
Shield's toolbox.tools_by_id from lib/tool_shed/galaxy_install/tools/tool_panel_manager.py.
Affected #: 3 files
diff -r 01293fc1f16715121524b987fcab031f3e149a02 -r 7716c8fbb891eb18f81bc80fc5f85f735d025357 lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -529,8 +529,7 @@
converter.id = tool_dict[ 'guid' ]
break
if deactivate:
- if converter.id in toolbox.tools_by_id:
- del toolbox.tools_by_id[ converter.id ]
+ toolbox.remove_tool_by_id( converter.id, remove_from_panel=False )
if source_datatype in self.datatype_converters:
if target_datatype in self.datatype_converters[ source_datatype ]:
del self.datatype_converters[ source_datatype ][ target_datatype ]
diff -r 01293fc1f16715121524b987fcab031f3e149a02 -r 7716c8fbb891eb18f81bc80fc5f85f735d025357 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -952,9 +952,13 @@
status = 'done'
return message, status
- def remove_tool_by_id( self, tool_id ):
+ def remove_tool_by_id( self, tool_id, remove_from_panel=True ):
"""
- Attempt to remove the tool identified by 'tool_id'.
+ Attempt to remove the tool identified by 'tool_id'. Ignores
+ tool lineage - so to remove a tool with potentially multiple
+ versions send remove_from_panel=False and handle the logic of
+ promoting the next newest version of the tool into the panel
+ if needed.
"""
if tool_id not in self.tools_by_id:
message = "No tool with id %s" % escape( tool_id )
@@ -962,17 +966,18 @@
else:
tool = self.tools_by_id[ tool_id ]
del self.tools_by_id[ tool_id ]
- tool_key = 'tool_' + tool_id
- for key, val in self.tool_panel.items():
- if key == tool_key:
- del self.tool_panel[ key ]
- break
- elif key.startswith( 'section' ):
- if tool_key in val.elems:
- del self.tool_panel[ key ].elems[ tool_key ]
+ if remove_from_panel:
+ tool_key = 'tool_' + tool_id
+ for key, val in self.tool_panel.items():
+ if key == tool_key:
+ del self.tool_panel[ key ]
break
- if tool_id in self.data_manager_tools:
- del self.data_manager_tools[ tool_id ]
+ elif key.startswith( 'section' ):
+ if tool_key in val.elems:
+ del self.tool_panel[ key ].elems[ tool_key ]
+ break
+ if tool_id in self.data_manager_tools:
+ del self.data_manager_tools[ tool_id ]
#TODO: do we need to manually remove from the integrated panel here?
message = "Removed the tool:<br/>"
message += "<b>name:</b> %s<br/>" % tool.name
diff -r 01293fc1f16715121524b987fcab031f3e149a02 -r 7716c8fbb891eb18f81bc80fc5f85f735d025357 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -490,8 +490,8 @@
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
- if guid_to_remove in toolbox.tools_by_id:
- del toolbox.tools_by_id[ guid_to_remove ]
+ # remove_from_tool_panel to false, will handling that logic below.
+ toolbox.remove_tool_by_id( guid_to_remove, remove_from_panel=False )
index, shed_tool_conf_dict = self.get_shed_tool_conf_dict( shed_tool_conf )
if uninstall:
# Remove from the shed_tool_conf file on disk.
https://bitbucket.org/galaxy/galaxy-central/commits/75e5db40bd2e/
Changeset: 75e5db40bd2e
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Eliminate walking over tools_by_id externally from toolbox.
Affected #: 2 files
diff -r 7716c8fbb891eb18f81bc80fc5f85f735d025357 -r 75e5db40bd2e6bfb481b500081a3d8b066063541 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -535,6 +535,9 @@
.filter( self.app.install_model.ToolVersion.table.c.tool_id == tool_id ) \
.first()
+ def tools( self ):
+ return self.tools_by_id.iteritems()
+
def __get_tool_shed_repository( self, tool_shed, name, owner, installed_changeset_revision ):
# We store only the port, if one exists, in the database.
tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
diff -r 7716c8fbb891eb18f81bc80fc5f85f735d025357 -r 75e5db40bd2e6bfb481b500081a3d8b066063541 lib/galaxy/tools/search/__init__.py
--- a/lib/galaxy/tools/search/__init__.py
+++ b/lib/galaxy/tools/search/__init__.py
@@ -27,7 +27,7 @@
self.index = self.storage.create_index( schema )
writer = self.index.writer()
## TODO: would also be nice to search section headers.
- for id, tool in self.toolbox.tools_by_id.iteritems():
+ for id, tool in self.toolbox.tools():
add_doc_kwds = {
"id": id,
"title": to_unicode(tool.name),
https://bitbucket.org/galaxy/galaxy-central/commits/4844fa109944/
Changeset: 4844fa109944
User: jmchilton
Date: 2014-12-25 18:35:13+00:00
Summary: Abstractions for registering tools from outside toolbox.
Part of effort to further limit exposing tools_by_id directly outside Toolbox.
Affected #: 4 files
diff -r 75e5db40bd2e6bfb481b500081a3d8b066063541 -r 4844fa1099447fb8397159be710c99a82726821a lib/galaxy/datatypes/registry.py
--- a/lib/galaxy/datatypes/registry.py
+++ b/lib/galaxy/datatypes/registry.py
@@ -535,7 +535,7 @@
del self.datatype_converters[ source_datatype ][ target_datatype ]
self.log.debug( "Deactivated converter: %s", converter.id )
else:
- toolbox.tools_by_id[ converter.id ] = converter
+ toolbox.register_tool( converter )
if source_datatype not in self.datatype_converters:
self.datatype_converters[ source_datatype ] = odict()
self.datatype_converters[ source_datatype ][ target_datatype ] = converter
@@ -644,8 +644,7 @@
tmp_name = tempfile.NamedTemporaryFile()
tmp_name.write( tool_xml_text )
tmp_name.flush()
- set_meta_tool = toolbox.load_tool( tmp_name.name )
- toolbox.tools_by_id[ set_meta_tool.id ] = set_meta_tool
+ set_meta_tool = toolbox.load_hidden_tool( tmp_name.name )
self.set_external_metadata_tool = set_meta_tool
self.log.debug( "Loaded external metadata tool: %s", self.set_external_metadata_tool.id )
diff -r 75e5db40bd2e6bfb481b500081a3d8b066063541 -r 4844fa1099447fb8397159be710c99a82726821a lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -804,6 +804,17 @@
self.tool_watcher.watch_file( config_file, tool.id )
return tool
+ def load_hidden_tool( self, config_file, **kwds ):
+ """ Load a hidden tool (in this context meaning one that does not
+ appear in the tool panel) and register it in tools_by_id.
+ """
+ tool = self.load_tool( config_file, **kwds )
+ self.register_tool( tool )
+ return tool
+
+ def register_tool( self, tool ):
+ self.tools_by_id[ tool.id ] = tool
+
def package_tool( self, trans, tool_id ):
"""
Create a tarball with the tool's xml, help images, and test data.
diff -r 75e5db40bd2e6bfb481b500081a3d8b066063541 -r 4844fa1099447fb8397159be710c99a82726821a lib/galaxy/tools/data_manager/manager.py
--- a/lib/galaxy/tools/data_manager/manager.py
+++ b/lib/galaxy/tools/data_manager/manager.py
@@ -244,12 +244,12 @@
return self.guid or self.declared_id #if we have a guid, we will use that as the data_manager id
def load_tool( self, tool_filename, guid=None, data_manager_id=None, tool_shed_repository_id=None ):
- tool = self.data_managers.app.toolbox.load_tool( tool_filename,
- guid=guid,
- data_manager_id=data_manager_id,
- repository_id=tool_shed_repository_id )
+ toolbox = self.data_managers.app.toolbox
+ tool = toolbox.load_hidden_tool( tool_filename,
+ guid=guid,
+ data_manager_id=data_manager_id,
+ repository_id=tool_shed_repository_id )
self.data_managers.app.toolbox.data_manager_tools[ tool.id ] = tool
- self.data_managers.app.toolbox.tools_by_id[ tool.id ] = tool
self.tool = tool
return tool
diff -r 75e5db40bd2e6bfb481b500081a3d8b066063541 -r 4844fa1099447fb8397159be710c99a82726821a lib/galaxy/tools/imp_exp/__init__.py
--- a/lib/galaxy/tools/imp_exp/__init__.py
+++ b/lib/galaxy/tools/imp_exp/__init__.py
@@ -40,14 +40,12 @@
tmp_name = tempfile.NamedTemporaryFile()
tmp_name.write( tool_xml_text )
tmp_name.flush()
- history_exp_tool = toolbox.load_tool( tmp_name.name )
- toolbox.tools_by_id[ history_exp_tool.id ] = history_exp_tool
+ history_exp_tool = toolbox.load_hidden_tool( tmp_name.name )
log.debug( "Loaded history export tool: %s", history_exp_tool.id )
# Load import tool.
tool_xml = os.path.join( os.getcwd(), "lib/galaxy/tools/imp_exp/imp_history_from_archive.xml" )
- history_imp_tool = toolbox.load_tool( tool_xml )
- toolbox.tools_by_id[ history_imp_tool.id ] = history_imp_tool
+ history_imp_tool = toolbox.load_hidden_tool( tool_xml )
log.debug( "Loaded history import tool: %s", history_imp_tool.id )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
5 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/38c8222d9e79/
Changeset: 38c8222d9e79
User: jmchilton
Date: 2014-12-25 17:24:23+00:00
Summary: Bugfix: Allow passing key to GET /api/datatypes/mapping.
All anonymous API endpoints should also allow authenticated access and just ignore the key.
Affected #: 1 file
diff -r 179199007ec93cdfa45b200e9a27486035ff2477 -r 38c8222d9e79a237dea9179a63b486447aeb9999 lib/galaxy/webapps/galaxy/api/datatypes.py
--- a/lib/galaxy/webapps/galaxy/api/datatypes.py
+++ b/lib/galaxy/webapps/galaxy/api/datatypes.py
@@ -44,7 +44,7 @@
return { 'error': str( exception ) }
@web.expose_api_anonymous
- def mapping( self, trans ):
+ def mapping( self, trans, **kwd ):
'''
GET /api/datatypes/mapping
Return a dictionary of class to class mappings.
https://bitbucket.org/galaxy/galaxy-central/commits/cd529da77278/
Changeset: cd529da77278
User: jmchilton
Date: 2014-12-25 17:24:23+00:00
Summary: Suite of API tests for exist datatypes endpoint.
Affected #: 1 file
diff -r 38c8222d9e79a237dea9179a63b486447aeb9999 -r cd529da7727870e472d18a4ba9037aa554bb9e81 test/api/test_datatypes.py
--- /dev/null
+++ b/test/api/test_datatypes.py
@@ -0,0 +1,51 @@
+from base import api
+
+
+HIDDEN_DURING_UPLOAD_DATATYPE = "fli"
+
+
+class DatatypesApiTestCase( api.ApiTestCase ):
+
+ def test_index( self ):
+ datatypes = self._index_datatypes()
+ for common_type in ["tabular", "fasta"]:
+ assert common_type in datatypes, "%s not in %s" % (common_type, datatypes)
+
+ def test_index_upload_only( self ):
+ # fli is not displayed in upload - so only show it if upload_only
+ # is explicitly false.
+ datatypes = self._index_datatypes( data={ "upload_only": False } )
+ assert HIDDEN_DURING_UPLOAD_DATATYPE in datatypes
+
+ datatypes = self._index_datatypes( data={ "upload_only": True } )
+ assert HIDDEN_DURING_UPLOAD_DATATYPE not in datatypes
+
+ datatypes = self._index_datatypes( )
+ assert HIDDEN_DURING_UPLOAD_DATATYPE not in datatypes
+
+ def test_full_index( self ):
+ datatypes = self._index_datatypes( data={ "extension_only": False } )
+ for datatype in datatypes:
+ self._assert_has_keys( datatype, "extension", "description", "description_url" )
+ assert datatype["extension"] != HIDDEN_DURING_UPLOAD_DATATYPE
+
+ def test_mapping( self ):
+ response = self._get( "datatypes/mapping" )
+ self._assert_status_code_is( response, 200 )
+ mapping_dict = response.json()
+ self._assert_has_keys( mapping_dict, "ext_to_class_name", "class_to_classes" )
+
+ def test_sniffers( self ):
+ response = self._get( "datatypes/sniffers" )
+ self._assert_status_code_is( response, 200 )
+ sniffer_list = response.json()
+ owl_index = sniffer_list.index( "galaxy.datatypes.xml:Owl" )
+ xml_index = sniffer_list.index( "galaxy.datatypes.xml:GenericXml" )
+ assert owl_index < xml_index
+
+ def _index_datatypes( self, data={} ):
+ response = self._get( "datatypes", data=data )
+ self._assert_status_code_is( response, 200 )
+ datatypes = response.json()
+ assert isinstance( datatypes, list )
+ return datatypes
https://bitbucket.org/galaxy/galaxy-central/commits/afc01429c885/
Changeset: afc01429c885
User: jmchilton
Date: 2014-12-25 17:24:23+00:00
Summary: Update datatypes API to newer API decoarator/exception handling.
Affected #: 1 file
diff -r cd529da7727870e472d18a4ba9037aa554bb9e81 -r afc01429c88520099bbbb1715f8412d995d4b92c lib/galaxy/webapps/galaxy/api/datatypes.py
--- a/lib/galaxy/webapps/galaxy/api/datatypes.py
+++ b/lib/galaxy/webapps/galaxy/api/datatypes.py
@@ -2,7 +2,8 @@
API operations allowing clients to determine datatype supported by Galaxy.
"""
-from galaxy import web
+from galaxy.web import _future_expose_api_anonymous as expose_api_anonymous
+from galaxy import exceptions
from galaxy.web.base.controller import BaseAPIController
from galaxy.util import asbool
from galaxy.datatypes.data import Data
@@ -13,7 +14,7 @@
class DatatypesController( BaseAPIController ):
- @web.expose_api_anonymous
+ @expose_api_anonymous
def index( self, trans, **kwd ):
"""
GET /api/datatypes
@@ -38,12 +39,14 @@
dictionary[key] = elem.get(key)
rval.append(dictionary)
return rval
- except Exception, exception:
+ except Exception as exception:
log.error( 'could not get datatypes: %s', str( exception ), exc_info=True )
- trans.response.status = 500
- return { 'error': str( exception ) }
+ if not isinstance( exception, exceptions.MessageException ):
+ raise exceptions.InternalServerError( str( exception ) )
+ else:
+ raise
- @web.expose_api_anonymous
+ @expose_api_anonymous
def mapping( self, trans, **kwd ):
'''
GET /api/datatypes/mapping
@@ -69,12 +72,15 @@
visit_bases( types, c )
class_to_classes[ n ] = dict( ( t, True ) for t in types )
return dict( ext_to_class_name=ext_to_class_name, class_to_classes=class_to_classes )
- except Exception, exception:
+
+ except Exception as exception:
log.error( 'could not get datatype mapping: %s', str( exception ), exc_info=True )
- trans.response.status = 500
- return { 'error': str( exception ) }
+ if not isinstance( exception, exceptions.MessageException ):
+ raise exceptions.InternalServerError( str( exception ) )
+ else:
+ raise
- @web.expose_api_anonymous
+ @expose_api_anonymous
def sniffers( self, trans, **kwd ):
'''
GET /api/datatypes/sniffers
@@ -87,7 +93,9 @@
if datatype is not None:
rval.append( datatype )
return rval
- except Exception, exception:
+ except Exception as exception:
log.error( 'could not get datatypes: %s', str( exception ), exc_info=True )
- trans.response.status = 500
- return { 'error': str( exception ) }
+ if not isinstance( exception, exceptions.MessageException ):
+ raise exceptions.InternalServerError( str( exception ) )
+ else:
+ raise
https://bitbucket.org/galaxy/galaxy-central/commits/750775b64cb7/
Changeset: 750775b64cb7
User: jmchilton
Date: 2014-12-25 17:24:23+00:00
Summary: Reduce repeated nested object access in galaxy.api.datatypes.
Affected #: 1 file
diff -r afc01429c88520099bbbb1715f8412d995d4b92c -r 750775b64cb758876745af058550b97ae1c47105 lib/galaxy/webapps/galaxy/api/datatypes.py
--- a/lib/galaxy/webapps/galaxy/api/datatypes.py
+++ b/lib/galaxy/webapps/galaxy/api/datatypes.py
@@ -20,17 +20,18 @@
GET /api/datatypes
Return an object containing upload datatypes.
"""
+ datatypes_registry = self._datatypes_registry
extension_only = asbool( kwd.get( 'extension_only', True ) )
upload_only = asbool( kwd.get( 'upload_only', True ) )
try:
if extension_only:
if upload_only:
- return trans.app.datatypes_registry.upload_file_formats
+ return datatypes_registry.upload_file_formats
else:
- return [ ext for ext in trans.app.datatypes_registry.datatypes_by_extension ]
+ return [ ext for ext in datatypes_registry.datatypes_by_extension ]
else:
rval = []
- for elem in trans.app.datatypes_registry.datatype_elems:
+ for elem in datatypes_registry.datatype_elems:
if not asbool(elem.get('display_in_upload')) and upload_only:
continue
keys = ['extension', 'description', 'description_url']
@@ -55,7 +56,7 @@
try:
ext_to_class_name = dict()
classes = []
- for k, v in trans.app.datatypes_registry.datatypes_by_extension.iteritems():
+ for k, v in self._datatypes_registry.datatypes_by_extension.iteritems():
c = v.__class__
ext_to_class_name[k] = c.__module__ + "." + c.__name__
classes.append( c )
@@ -88,7 +89,7 @@
'''
try:
rval = []
- for sniffer_elem in trans.app.datatypes_registry.sniffer_elems:
+ for sniffer_elem in self._datatypes_registry.sniffer_elems:
datatype = sniffer_elem.get( 'type' )
if datatype is not None:
rval.append( datatype )
@@ -99,3 +100,7 @@
raise exceptions.InternalServerError( str( exception ) )
else:
raise
+
+ @property
+ def _datatypes_registry( self ):
+ return self.app.datatypes_registry
https://bitbucket.org/galaxy/galaxy-central/commits/0587bc5413d6/
Changeset: 0587bc5413d6
User: jmchilton
Date: 2014-12-25 17:24:23+00:00
Summary: Expose datatype converter information via datatype API.
With test case.
Affected #: 3 files
diff -r 750775b64cb758876745af058550b97ae1c47105 -r 0587bc5413d66e85673d7b429bc04d34e47ad4c4 lib/galaxy/webapps/galaxy/api/datatypes.py
--- a/lib/galaxy/webapps/galaxy/api/datatypes.py
+++ b/lib/galaxy/webapps/galaxy/api/datatypes.py
@@ -101,6 +101,19 @@
else:
raise
+ @expose_api_anonymous
+ def converters( self, trans, **kwd ):
+ converters = []
+ for (source_type, targets) in self._datatypes_registry.datatype_converters.iteritems():
+ for target_type in targets:
+ converters.append( {
+ 'source': source_type,
+ 'target': target_type,
+ 'tool_id': targets[ target_type ].id,
+ } )
+
+ return converters
+
@property
def _datatypes_registry( self ):
return self.app.datatypes_registry
diff -r 750775b64cb758876745af058550b97ae1c47105 -r 0587bc5413d66e85673d7b429bc04d34e47ad4c4 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -198,7 +198,7 @@
webapp.mapper.resource( 'datatype',
'datatypes',
path_prefix='/api',
- collection={ 'sniffers': 'GET', 'mapping' : 'GET' },
+ collection={ 'sniffers': 'GET', 'mapping' : 'GET', 'converters': 'GET' },
parent_resources=dict( member_name='datatype', collection_name='datatypes' ) )
#webapp.mapper.connect( 'run_workflow', '/api/workflow/{workflow_id}/library/{library_id}', controller='workflows', action='run', workflow_id=None, library_id=None, conditions=dict(method=["GET"]) )
webapp.mapper.resource( 'search', 'search', path_prefix='/api' )
diff -r 750775b64cb758876745af058550b97ae1c47105 -r 0587bc5413d66e85673d7b429bc04d34e47ad4c4 test/api/test_datatypes.py
--- a/test/api/test_datatypes.py
+++ b/test/api/test_datatypes.py
@@ -43,6 +43,19 @@
xml_index = sniffer_list.index( "galaxy.datatypes.xml:GenericXml" )
assert owl_index < xml_index
+ def test_converters( self ):
+ response = self._get( "datatypes/converters" )
+ self._assert_status_code_is( response, 200 )
+ converters_list = response.json()
+ found_fasta_to_tabular = False
+
+ for converter in converters_list:
+ self._assert_has_key( converter, "source", "target", "tool_id" )
+ if converter["source"] == "fasta" and converter["target"] == "tabular":
+ found_fasta_to_tabular = True
+
+ assert found_fasta_to_tabular
+
def _index_datatypes( self, data={} ):
response = self._get( "datatypes", data=data )
self._assert_status_code_is( response, 200 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/29ed5db57e42/
Changeset: 29ed5db57e42
User: jmchilton
Date: 2014-12-24 05:42:54+00:00
Summary: Breakup big remove method in tool_panel_manager.py to ease testing.
Separate out logic for dealing with toolbox from logic for dealing repository metadata in the database.
Affected #: 2 files
diff -r 17f4ab6dc1ff388f1e58e72b886cfa792e3b131c -r 29ed5db57e4247653a9530540180025de8e93f5d lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
--- a/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
+++ b/lib/galaxy/webapps/galaxy/controllers/admin_toolshed.py
@@ -249,9 +249,9 @@
if tool_shed_repository.includes_tools_for_display_in_tool_panel:
# Handle tool panel alterations.
tpm = tool_panel_manager.ToolPanelManager( trans.app )
- tpm.remove_from_tool_panel( tool_shed_repository,
- shed_tool_conf,
- uninstall=remove_from_disk_checked )
+ tpm.remove_repository_contents( tool_shed_repository,
+ shed_tool_conf,
+ uninstall=remove_from_disk_checked )
if tool_shed_repository.includes_data_managers:
dmh = data_manager.DataManagerHandler( trans.app )
dmh.remove_from_data_manager( tool_shed_repository )
diff -r 17f4ab6dc1ff388f1e58e72b886cfa792e3b131c -r 29ed5db57e4247653a9530540180025de8e93f5d lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -427,7 +427,7 @@
# Persist the altered in-memory version of the tool config.
self.config_elems_to_xml_file( config_elems, shed_tool_conf, tool_path )
- def remove_from_tool_panel( self, repository, shed_tool_conf, uninstall ):
+ def remove_repository_contents( self, repository, shed_tool_conf, uninstall ):
"""
A tool shed repository is being deactivated or uninstalled, so handle
tool panel alterations accordingly.
@@ -442,6 +442,9 @@
# Create a list of guids for all tools that will be removed from the in-memory tool panel
# and config file on disk.
guids_to_remove = [ k for k in tool_panel_dict.keys() ]
+ self.remove_guids( guids_to_remove, shed_tool_conf, uninstall )
+
+ def remove_guids( self, guids_to_remove, shed_tool_conf, uninstall ):
# Remove the tools from the toolbox's tools_by_id dictionary.
for guid_to_remove in guids_to_remove:
if guid_to_remove in self.app.toolbox.tools_by_id:
https://bitbucket.org/galaxy/galaxy-central/commits/179199007ec9/
Changeset: 179199007ec9
User: jmchilton
Date: 2014-12-24 05:42:54+00:00
Summary: Unit test coverage for removing stuff from the toolbox.
Covers cases for tools inside and outside of sections and both deactivation versus uninstallation.
Affected #: 2 files
diff -r 29ed5db57e4247653a9530540180025de8e93f5d -r 179199007ec93cdfa45b200e9a27486035ff2477 test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
--- a/test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
+++ b/test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
@@ -12,7 +12,7 @@
self._init_tool()
self._add_config( """<toolbox><section id="tid" name="test"><tool file="tool.xml" /></section></toolbox>""" )
toolbox = self.toolbox
- tpm = tool_panel_manager.ToolPanelManager( self.app )
+ tpm = self.tpm
# Test fetch existing section by id.
section_id, section = tpm.handle_tool_panel_section( toolbox, tool_panel_section_id="tid" )
assert section_id == "tid"
@@ -47,7 +47,7 @@
)
]
_, section = self.toolbox.get_or_create_section("tid1")
- tpm = tool_panel_manager.ToolPanelManager( self.app )
+ tpm = self.tpm
tool_panel_dict = tpm.generate_tool_panel_dict_for_new_install(
tool_dicts=new_tools,
tool_section=section,
@@ -61,6 +61,77 @@
shed_tool_conf="tool_conf.xml",
tool_panel_dict=tool_panel_dict,
)
+ self._verify_tool_confs()
+
+ def test_deactivate_in_section( self ):
+ self._setup_two_versions_remove_one( section=True, uninstall=False )
+ self._verify_version_2_removed_from_panel( )
+ # Still in tool conf since not uninstalled only deactivated...
+ assert "github.com/galaxyproect/example/test_tool/0.2" in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
+ self._verify_tool_confs()
+
+ self._remove_guids( ["github.com/galaxyproect/example/test_tool/0.1"], uninstall=False )
+
+ # Now no versions of this tool are returned by toolbox.
+ all_versions = self.toolbox.get_tool( "test_tool", get_all_versions=True )
+ assert not all_versions
+
+ # Check that tool panel has reverted to old value...
+ section = self.toolbox.tool_panel["tid"]
+ assert len(section.elems) == 0
+
+ def test_uninstall_in_section( self ):
+ self._setup_two_versions_remove_one( section=True, uninstall=True )
+ self._verify_version_2_removed_from_panel( )
+ # Not in tool conf because it was uninstalled.
+ assert "github.com/galaxyproect/example/test_tool/0.2" not in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
+ self._verify_tool_confs()
+
+ def test_deactivate_outside_section( self ):
+ self._setup_two_versions_remove_one( section=False, uninstall=False )
+ self._verify_version_2_removed_from_panel( section=False )
+ # Still in tool conf since not uninstalled only deactivated...
+ assert "github.com/galaxyproect/example/test_tool/0.2" in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
+ self._verify_tool_confs()
+
+ def test_uninstall_outside_section( self ):
+ self._setup_two_versions_remove_one( section=False, uninstall=True )
+ self._verify_version_2_removed_from_panel( section=False )
+ # Still in tool conf since not uninstalled only deactivated...
+ assert "github.com/galaxyproect/example/test_tool/0.2" not in open(os.path.join(self.test_directory, "tool_conf.xml"), "r").read()
+ self._verify_tool_confs()
+
+ def _setup_two_versions_remove_one( self, section, uninstall ):
+ self._init_tool()
+ self._setup_two_versions_in_config( section=True )
+ self._setup_two_versions()
+ self.toolbox
+ self._remove_guids( ["github.com/galaxyproect/example/test_tool/0.2"], uninstall=uninstall )
+
+ def _verify_version_2_removed_from_panel( self, section=True ):
+ # Check that test_tool now only has one version...
+ all_versions = self.toolbox.get_tool( "test_tool", get_all_versions=True )
+ assert len( all_versions ) == 1
+
+ # Check that tool panel has reverted to old value...
+ if section:
+ section = self.toolbox.tool_panel["tid"]
+ assert len(section.elems) == 1
+ assert section.elems.values()[0].id == "github.com/galaxyproect/example/test_tool/0.1"
+
+ assert "github.com/galaxyproect/example/test_tool/0.2" not in self.toolbox.integrated_tool_panel["tid"].elems
+ else:
+ self.toolbox.tool_panel.values()[0].id == "github.com/galaxyproect/example/test_tool/0.1"
+ assert "github.com/galaxyproect/example/test_tool/0.2" not in self.toolbox.integrated_tool_panel
+
+ def _remove_guids( self, guids, uninstall, shed_tool_conf="tool_conf.xml" ):
+ self.tpm.remove_guids(
+ guids_to_remove=guids,
+ shed_tool_conf=shed_tool_conf,
+ uninstall=uninstall,
+ )
+
+ def _verify_tool_confs( self ):
self._assert_valid_xml( self.integerated_tool_panel_path )
self._assert_valid_xml( os.path.join( self.test_directory, "tool_conf.xml" ) )
@@ -71,3 +142,7 @@
message_template = "file %s does not contain valid XML, content %s"
message = message_template % ( filename, open( filename, "r" ).read() )
raise AssertionError( message )
+
+ @property
+ def tpm( self ):
+ return tool_panel_manager.ToolPanelManager( self.app )
diff -r 29ed5db57e4247653a9530540180025de8e93f5d -r 179199007ec93cdfa45b200e9a27486035ff2477 test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -91,6 +91,27 @@
self.app.install_model.context.add( version_association )
self.app.install_model.context.flush( )
+ def _setup_two_versions_in_config( self, section=False ):
+ if section:
+ template = """<toolbox tool_path="%s">
+<section id="tid" name="TID" version="">
+ %s
+</section>
+<section id="tid" name="TID" version="">
+ %s
+</section>
+</toolbox>"""
+ else:
+ template = """<toolbox tool_path="%s">
+<section id="tid" name="TID" version="">
+ %s
+</section>
+<section id="tid" name="TID" version="">
+ %s
+</section>
+</toolbox>"""
+ self._add_config( template % (self.test_directory, CONFIG_TEST_TOOL_VERSION_1, CONFIG_TEST_TOOL_VERSION_2 ) )
+
def _add_config( self, xml, name="tool_conf.xml" ):
path = self._tool_conf_path( name=name )
with open( path, "w" ) as f:
@@ -133,14 +154,7 @@
def test_groups_tools_in_section( self ):
self._init_tool()
- self._add_config( """<toolbox tool_path="%s">
-<section id="tid" name="TID" version="">
- %s
-</section>
-<section id="tid" name="TID" version="">
- %s
-</section>
-</toolbox>""" % (self.test_directory, CONFIG_TEST_TOOL_VERSION_1, CONFIG_TEST_TOOL_VERSION_2 ) )
+ self._setup_two_versions_in_config( section=True )
self._setup_two_versions()
self.toolbox
self.__verify_two_test_tools( )
@@ -152,11 +166,7 @@
def test_group_tools_out_of_section( self ):
self._init_tool()
- self._add_config( """<toolbox tool_path="%s">
-%s
-%s
-</toolbox>""" % (self.test_directory, CONFIG_TEST_TOOL_VERSION_1, CONFIG_TEST_TOOL_VERSION_2 ) )
-
+ self._setup_two_versions_in_config( section=False )
self._setup_two_versions()
self.__verify_two_test_tools( )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Add tool lineage test for tools outside of sections.
by commits-noreply@bitbucket.org 24 Dec '14
by commits-noreply@bitbucket.org 24 Dec '14
24 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/17f4ab6dc1ff/
Changeset: 17f4ab6dc1ff
User: jmchilton
Date: 2014-12-24 03:17:55+00:00
Summary: Add tool lineage test for tools outside of sections.
Affected #: 1 file
diff -r 39e6037047070a5014c4250dc7f47775e78452b4 -r 17f4ab6dc1ff388f1e58e72b886cfa792e3b131c test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -1,4 +1,5 @@
import os
+import string
import unittest
from galaxy.tools import ToolBox
@@ -7,6 +8,21 @@
import tools_support
+CONFIG_TEST_TOOL_VERSION_TEMPLATE = string.Template(
+ """ <tool file="tool.xml" guid="github.com/galaxyproect/example/test_tool/0.${version}">
+ <tool_shed>github.com</tool_shed>
+ <repository_name>example</repository_name>
+ <repository_owner>galaxyproject</repository_owner>
+ <installed_changeset_revision>${version}</installed_changeset_revision>
+ <id>github.com/galaxyproect/example/test_tool/0.${version}</id>
+ <version>0.${version}</version>
+ </tool>
+ """
+)
+CONFIG_TEST_TOOL_VERSION_1 = CONFIG_TEST_TOOL_VERSION_TEMPLATE.safe_substitute( dict( version="1" ) )
+CONFIG_TEST_TOOL_VERSION_2 = CONFIG_TEST_TOOL_VERSION_TEMPLATE.safe_substitute( dict( version="2" ) )
+
+
class BaseToolBoxTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
@property
@@ -115,32 +131,52 @@
self.toolbox
self.assert_integerated_tool_panel(exists=True)
- def test_groups_tools( self ):
+ def test_groups_tools_in_section( self ):
self._init_tool()
self._add_config( """<toolbox tool_path="%s"><section id="tid" name="TID" version="">
- <tool file="tool.xml" guid="github.com/galaxyproect/example/test_tool/0.1">
- <tool_shed>github.com</tool_shed>
- <repository_name>example</repository_name>
- <repository_owner>galaxyproject</repository_owner>
- <installed_changeset_revision>2</installed_changeset_revision>
- <id>github.com/galaxyproect/example/test_tool/0.1</id>
- <version>0.1</version>
- </tool>
+ %s
</section><section id="tid" name="TID" version="">
- <tool file="tool.xml" guid="github.com/galaxyproect/example/test_tool/0.2">
- <tool_shed>github.com</tool_shed>
- <repository_name>example</repository_name>
- <repository_owner>galaxyproject</repository_owner>
- <installed_changeset_revision>2</installed_changeset_revision>
- <id>github.com/galaxyproect/example/test_tool/0.2</id>
- <version>0.2</version>
- </tool>
+ %s
</section>
-</toolbox>""" % self.test_directory )
+</toolbox>""" % (self.test_directory, CONFIG_TEST_TOOL_VERSION_1, CONFIG_TEST_TOOL_VERSION_2 ) )
self._setup_two_versions()
+ self.toolbox
+ self.__verify_two_test_tools( )
+ # Assert only newer version of the tool loaded into the panel.
+ section = self.toolbox.tool_panel["tid"]
+ assert len(section.elems) == 1
+ assert section.elems.values()[0].id == "github.com/galaxyproect/example/test_tool/0.2"
+
+ def test_group_tools_out_of_section( self ):
+ self._init_tool()
+ self._add_config( """<toolbox tool_path="%s">
+%s
+%s
+</toolbox>""" % (self.test_directory, CONFIG_TEST_TOOL_VERSION_1, CONFIG_TEST_TOOL_VERSION_2 ) )
+
+ self._setup_two_versions()
+ self.__verify_two_test_tools( )
+
+ # Assert tools merged in tool panel.
+ assert len( self.toolbox.tool_panel ) == 1
+
+ def test_update_shed_conf(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {} )
+ assert self.reindexed
+ self.assert_integerated_tool_panel(exists=True)
+
+ def test_update_shed_conf_deactivate_only(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {}, integrated_panel_changes=False )
+ assert self.reindexed
+ # No changes, should be regenerated
+ self.assert_integerated_tool_panel(exists=False)
+
+ def __verify_two_test_tools( self ):
# Assert tool versions of the tool with simple id 'test_tool'
all_versions = self.toolbox.get_tool( "test_tool", get_all_versions=True )
assert len( all_versions ) == 2
@@ -156,24 +192,6 @@
assert self.toolbox.get_tool( "test_tool", tool_version="0.1" ).guid == "github.com/galaxyproect/example/test_tool/0.1"
assert self.toolbox.get_tool( "test_tool", tool_version="0.2" ).guid == "github.com/galaxyproect/example/test_tool/0.2"
- # Assert only newer version of the tool loaded into the panel.
- section = self.toolbox.tool_panel["tid"]
- assert len(section.elems) == 1
- assert section.elems.values()[0].id == "github.com/galaxyproect/example/test_tool/0.2"
-
- def test_update_shed_conf(self):
- self.__setup_shed_tool_conf()
- self.toolbox.update_shed_config( 0, {} )
- assert self.reindexed
- self.assert_integerated_tool_panel(exists=True)
-
- def test_update_shed_conf_deactivate_only(self):
- self.__setup_shed_tool_conf()
- self.toolbox.update_shed_config( 0, {}, integrated_panel_changes=False )
- assert self.reindexed
- # No changes, should be regenerated
- self.assert_integerated_tool_panel(exists=False)
-
def __remove_itp( self ):
os.remove( os.path)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/97b801cca67e/
Changeset: 97b801cca67e
User: jmchilton
Date: 2014-12-24 02:42:37+00:00
Summary: More tool panel manager unit tests.
(Including adding file missing with previous commit 697b58f0.)
Affected #: 3 files
diff -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe -r 97b801cca67e566839e9c7fdaf5c558ff1eebab4 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -105,6 +105,8 @@
else:
tool_elem = XmlET.Element( 'tool' )
tool_elem.attrib[ 'file' ] = tool_file_path
+ if not tool.guid:
+ raise ValueError("tool has no guid")
tool_elem.attrib[ 'guid' ] = tool.guid
tool_shed_elem = XmlET.SubElement( tool_elem, 'tool_shed' )
tool_shed_elem.text = tool_shed
diff -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe -r 97b801cca67e566839e9c7fdaf5c558ff1eebab4 test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
--- /dev/null
+++ b/test/unit/tool_shed_unit_tests/test_tool_panel_manager.py
@@ -0,0 +1,73 @@
+import os
+
+from galaxy.util import parse_xml
+
+from tools.test_toolbox import BaseToolBoxTestCase
+from tool_shed.galaxy_install.tools import tool_panel_manager
+
+
+class ToolPanelManagerTestCase( BaseToolBoxTestCase ):
+
+ def test_handle_tool_panel_section( self ):
+ self._init_tool()
+ self._add_config( """<toolbox><section id="tid" name="test"><tool file="tool.xml" /></section></toolbox>""" )
+ toolbox = self.toolbox
+ tpm = tool_panel_manager.ToolPanelManager( self.app )
+ # Test fetch existing section by id.
+ section_id, section = tpm.handle_tool_panel_section( toolbox, tool_panel_section_id="tid" )
+ assert section_id == "tid"
+ assert len( section.elems ) == 1 # tool.xml
+ assert section.id == "tid"
+ assert len( toolbox.tool_panel ) == 1
+
+ section_id, section = tpm.handle_tool_panel_section( toolbox, new_tool_panel_section_label="tid2" )
+ assert section_id == "tid2"
+ assert len( section.elems ) == 0 # new section
+ assert section.id == "tid2"
+ assert len( toolbox.tool_panel ) == 2
+
+ # Test re-fetch new section by same id.
+ section_id, section = tpm.handle_tool_panel_section( toolbox, new_tool_panel_section_label="tid2" )
+ assert section_id == "tid2"
+ assert len( section.elems ) == 0 # new section
+ assert section.id == "tid2"
+ assert len( toolbox.tool_panel ) == 2
+
+ def test_add_tool_to_panel( self ):
+ self._init_tool()
+ self._add_config( """<toolbox tool_path="%s"></toolbox>""" % self.test_directory )
+ tool_path = os.path.join(self.test_directory, "tool.xml")
+ self.tool.guid = "123456"
+ new_tools = [{"guid": "123456", "tool_config": tool_path}]
+ repository_tools_tups = [
+ (
+ tool_path,
+ "123456",
+ self.tool,
+ )
+ ]
+ _, section = self.toolbox.get_or_create_section("tid1")
+ tpm = tool_panel_manager.ToolPanelManager( self.app )
+ tool_panel_dict = tpm.generate_tool_panel_dict_for_new_install(
+ tool_dicts=new_tools,
+ tool_section=section,
+ )
+ tpm.add_to_tool_panel(
+ repository_name="test_repo",
+ repository_clone_url="http://github.com/galaxyproject/example.git",
+ changeset_revision="0123456789abcde",
+ repository_tools_tups=repository_tools_tups,
+ owner="devteam",
+ shed_tool_conf="tool_conf.xml",
+ tool_panel_dict=tool_panel_dict,
+ )
+ self._assert_valid_xml( self.integerated_tool_panel_path )
+ self._assert_valid_xml( os.path.join( self.test_directory, "tool_conf.xml" ) )
+
+ def _assert_valid_xml( self, filename ):
+ try:
+ parse_xml( filename )
+ except Exception:
+ message_template = "file %s does not contain valid XML, content %s"
+ message = message_template % ( filename, open( filename, "r" ).read() )
+ raise AssertionError( message )
diff -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe -r 97b801cca67e566839e9c7fdaf5c558ff1eebab4 test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -23,6 +23,8 @@
def toolbox( self ):
if self.__toolbox is None:
self.__toolbox = SimplifiedToolBox( self )
+ # wire app with this new toolbox
+ self.app.toolbox = self.__toolbox
return self.__toolbox
def setUp( self ):
@@ -35,11 +37,15 @@
self.config_files = []
def _add_config( self, xml, name="tool_conf.xml" ):
- path = os.path.join( self.test_directory, "tool_conf.xml" )
+ path = self._tool_conf_path( name=name )
with open( path, "w" ) as f:
f.write( xml )
self.config_files.append( path )
+ def _tool_conf_path( self, name="tool_conf.xml" ):
+ path = os.path.join( self.test_directory, name )
+ return path
+
def __reindex( self ):
self.reindexed = True
https://bitbucket.org/galaxy/galaxy-central/commits/f1d8ecfadb85/
Changeset: f1d8ecfadb85
User: jmchilton
Date: 2014-12-24 02:42:37+00:00
Summary: PEP-8 and style tweaks to tool_panel_manager.py.
Affected #: 1 file
diff -r 97b801cca67e566839e9c7fdaf5c558ff1eebab4 -r f1d8ecfadb85df376846b5e4df0c0f30be569fc5 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -1,7 +1,6 @@
import logging
import threading
-import galaxy.tools
from xml.etree import ElementTree as XmlET
from tool_shed.util import basic_util
@@ -67,13 +66,14 @@
self.app.toolbox.integrated_tool_panel,
load_panel_dict=True )
elif config_elem.tag == 'tool':
- guid = config_elem.get( 'guid' )
- self.app.toolbox.load_tool_tag_set( config_elem,
- self.app.toolbox.tool_panel,
- self.app.toolbox.integrated_tool_panel,
- tool_path,
- load_panel_dict=True,
- guid=guid )
+ self.app.toolbox.load_tool_tag_set(
+ config_elem,
+ self.app.toolbox.tool_panel,
+ self.app.toolbox.integrated_tool_panel,
+ tool_path,
+ load_panel_dict=True,
+ guid=config_elem.get( 'guid' )
+ )
# Replace the old list of in-memory config_elems with the new list for this shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
self.app.toolbox.update_shed_config( index, shed_tool_conf_dict )
@@ -124,8 +124,9 @@
def generate_tool_panel_dict_for_new_install( self, tool_dicts, tool_section=None ):
"""
- When installing a repository that contains tools, all tools must currently be defined
- within the same tool section in the tool panel or outside of any sections.
+ When installing a repository that contains tools, all tools must
+ currently be defined within the same tool section in the tool panel or
+ outside of any sections.
"""
tool_panel_dict = {}
if tool_section:
@@ -168,11 +169,12 @@
def generate_tool_panel_dict_from_shed_tool_conf_entries( self, repository ):
"""
- Keep track of the section in the tool panel in which this repository's tools
- will be contained by parsing the shed_tool_conf in which the repository's tools
- are defined and storing the tool panel definition of each tool in the repository.
- This method is called only when the repository is being deactivated or un-installed
- and allows for activation or re-installation using the original layout.
+ Keep track of the section in the tool panel in which this repository's
+ tools will be contained by parsing the shed_tool_conf in which the
+ repository's tools are defined and storing the tool panel definition
+ of each tool in the repository. This method is called only when the
+ repository is being deactivated or un-installed and allows for
+ activation or re-installation using the original layout.
"""
tool_panel_dict = {}
shed_tool_conf, tool_path, relative_install_dir = \
@@ -351,8 +353,8 @@
def handle_tool_panel_selection( self, toolbox, metadata, no_changes_checked, tool_panel_section_id,
new_tool_panel_section_label ):
"""
- Handle the selected tool panel location for loading tools included in tool shed
- repositories when installing or reinstalling them.
+ Handle the selected tool panel location for loading tools included in
+ tool shed repositories when installing or reinstalling them.
"""
# Get the location in the tool panel in which each tool was originally loaded.
tool_section = None
@@ -390,10 +392,11 @@
def remove_from_shed_tool_config( self, shed_tool_conf_dict, guids_to_remove ):
"""
- A tool shed repository is being uninstalled so change the shed_tool_conf file.
- Parse the config file to generate the entire list of config_elems instead of
- using the in-memory list since it will be a subset of the entire list if one
- or more repositories have been deactivated.
+ A tool shed repository is being uninstalled so change the
+ shed_tool_conf file. Parse the config file to generate the entire list
+ of config_elems instead of using the in-memory list since it will be a
+ subset of the entire list if one or more repositories have been
+ deactivated.
"""
shed_tool_conf = shed_tool_conf_dict[ 'config_filename' ]
tool_path = shed_tool_conf_dict[ 'tool_path' ]
@@ -426,8 +429,8 @@
def remove_from_tool_panel( self, repository, shed_tool_conf, uninstall ):
"""
- A tool shed repository is being deactivated or uninstalled, so handle tool panel
- alterations accordingly.
+ A tool shed repository is being deactivated or uninstalled, so handle
+ tool panel alterations accordingly.
"""
# Determine where the tools are currently defined in the tool panel and store this
# information so the tools can be displayed in the same way when the repository is
https://bitbucket.org/galaxy/galaxy-central/commits/39e603704707/
Changeset: 39e603704707
User: jmchilton
Date: 2014-12-24 02:42:37+00:00
Summary: Unit test for tool panel merging tools by tool shed lineage.
Affected #: 1 file
diff -r f1d8ecfadb85df376846b5e4df0c0f30be569fc5 -r 39e6037047070a5014c4250dc7f47775e78452b4 test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -2,6 +2,7 @@
import unittest
from galaxy.tools import ToolBox
+from galaxy.model import tool_shed_install
from galaxy.model.tool_shed_install import mapping
import tools_support
@@ -30,12 +31,50 @@
def setUp( self ):
self.reindexed = False
self.setup_app( mock_model=False )
+ install_model = mapping.init( "sqlite:///:memory:", create_tables=True )
+ self.app.install_model = install_model
self.app.reindex_tool_search = self.__reindex
itp_config = os.path.join(self.test_directory, "integrated_tool_panel.xml")
self.app.config.integrated_tool_panel_config = itp_config
self.__toolbox = None
self.config_files = []
+ def _repo_install( self, changeset ):
+ repository = tool_shed_install.ToolShedRepository()
+ repository.tool_shed = "github.com"
+ repository.owner = "galaxyproject"
+ repository.name = "example"
+ repository.changeset_revision = changeset
+ repository.installed_changeset_revision = changeset
+ repository.deleted = False
+ repository.uninstalled = False
+ self.app.install_model.context.add( repository )
+ self.app.install_model.context.flush( )
+ return repository
+
+ def _setup_two_versions( self ):
+ repository1 = self._repo_install( changeset="1" )
+ version1 = tool_shed_install.ToolVersion()
+ version1.tool_id = "github.com/galaxyproect/example/test_tool/0.1"
+ version1.repository = repository1
+ self.app.install_model.context.add( version1 )
+ self.app.install_model.context.flush( )
+
+ repository2 = self._repo_install( changeset="2" )
+ version2 = tool_shed_install.ToolVersion()
+ version2.tool_id = "github.com/galaxyproect/example/test_tool/0.2"
+ version2.repository = repository2
+
+ self.app.install_model.context.add( version2 )
+ self.app.install_model.context.flush( )
+
+ version_association = tool_shed_install.ToolVersionAssociation()
+ version_association.parent_id = version1.id
+ version_association.tool_id = version2.id
+
+ self.app.install_model.context.add( version_association )
+ self.app.install_model.context.flush( )
+
def _add_config( self, xml, name="tool_conf.xml" ):
path = self._tool_conf_path( name=name )
with open( path, "w" ) as f:
@@ -78,7 +117,49 @@
def test_groups_tools( self ):
self._init_tool()
- self._add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+ self._add_config( """<toolbox tool_path="%s">
+<section id="tid" name="TID" version="">
+ <tool file="tool.xml" guid="github.com/galaxyproect/example/test_tool/0.1">
+ <tool_shed>github.com</tool_shed>
+ <repository_name>example</repository_name>
+ <repository_owner>galaxyproject</repository_owner>
+ <installed_changeset_revision>2</installed_changeset_revision>
+ <id>github.com/galaxyproect/example/test_tool/0.1</id>
+ <version>0.1</version>
+ </tool>
+</section>
+<section id="tid" name="TID" version="">
+ <tool file="tool.xml" guid="github.com/galaxyproect/example/test_tool/0.2">
+ <tool_shed>github.com</tool_shed>
+ <repository_name>example</repository_name>
+ <repository_owner>galaxyproject</repository_owner>
+ <installed_changeset_revision>2</installed_changeset_revision>
+ <id>github.com/galaxyproect/example/test_tool/0.2</id>
+ <version>0.2</version>
+ </tool>
+</section>
+</toolbox>""" % self.test_directory )
+ self._setup_two_versions()
+
+ # Assert tool versions of the tool with simple id 'test_tool'
+ all_versions = self.toolbox.get_tool( "test_tool", get_all_versions=True )
+ assert len( all_versions ) == 2
+
+ # Verify lineage_ids on both tools is correctly ordered.
+ for version in ["0.1", "0.2"]:
+ guid = "github.com/galaxyproect/example/test_tool/" + version
+ lineage_ids = self.toolbox.get_tool( guid ).lineage_ids
+ assert lineage_ids[ 0 ] == "github.com/galaxyproect/example/test_tool/0.1"
+ assert lineage_ids[ 1 ] == "github.com/galaxyproect/example/test_tool/0.2"
+
+ # Test tool_version attribute.
+ assert self.toolbox.get_tool( "test_tool", tool_version="0.1" ).guid == "github.com/galaxyproect/example/test_tool/0.1"
+ assert self.toolbox.get_tool( "test_tool", tool_version="0.2" ).guid == "github.com/galaxyproect/example/test_tool/0.2"
+
+ # Assert only newer version of the tool loaded into the panel.
+ section = self.toolbox.tool_panel["tid"]
+ assert len(section.elems) == 1
+ assert section.elems.values()[0].id == "github.com/galaxyproect/example/test_tool/0.2"
def test_update_shed_conf(self):
self.__setup_shed_tool_conf()
@@ -110,7 +191,6 @@
def __init__( self, test_case ):
app = test_case.app
# Handle app/config stuff needed by toolbox but not by tools.
- app.install_model = mapping.init( "sqlite:///:memory:", create_tables=True )
app.job_config.get_tool_resource_parameters = lambda tool_id: None
app.config.update_integrated_tool_panel = True
config_files = test_case.config_files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Move ToolPanelManager operation to create or get section into ToolBox.
by commits-noreply@bitbucket.org 23 Dec '14
by commits-noreply@bitbucket.org 23 Dec '14
23 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/697b58fa885a/
Changeset: 697b58fa885a
User: jmchilton
Date: 2014-12-23 19:22:08+00:00
Summary: Move ToolPanelManager operation to create or get section into ToolBox.
Now with unit test. Part of broader effort to make ToolBox interface more explicit, tested, and hide implementation details from other parts of code (such as ToolPanelManager).
Also reworked the code to now build up and re-parse XML structures - just use a dictionary - thanks to 34b3e1c.
Affected #: 3 files
diff -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -256,6 +256,27 @@
self.write_integrated_tool_panel_config_file()
app.reindex_tool_search()
+ def get_or_create_section( self, section_id, new_label=None ):
+ tool_panel_section_key = str( section_id )
+ if tool_panel_section_key in self.tool_panel:
+ # Appending a tool to an existing section in toolbox.tool_panel
+ tool_section = self.tool_panel[ tool_panel_section_key ]
+ log.debug( "Appending to tool panel section: %s" % str( tool_section.name ) )
+ else:
+ # Appending a new section to toolbox.tool_panel
+ if new_label is None:
+ # This might add an ugly section label to the tool panel, but, oh well...
+ new_label = section_id
+ section_dict = {
+ 'name': new_label,
+ 'id': section_id,
+ 'version': '',
+ }
+ tool_section = ToolSection( section_dict )
+ self.tool_panel[ tool_panel_section_key ] = tool_section
+ log.debug( "Loading new tool panel section: %s" % str( tool_section.name ) )
+ return tool_panel_section_key, tool_section
+
def __resolve_tool_path(self, tool_path, config_filename):
if not tool_path:
# Default to backward compatible config setting.
diff -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -312,24 +312,7 @@
return tool_section
def get_or_create_tool_section( self, toolbox, tool_panel_section_id, new_tool_panel_section_label=None ):
- tool_panel_section_key = str( tool_panel_section_id )
- if tool_panel_section_key in toolbox.tool_panel:
- # Appending a tool to an existing section in toolbox.tool_panel
- tool_section = toolbox.tool_panel[ tool_panel_section_key ]
- log.debug( "Appending to tool panel section: %s" % str( tool_section.name ) )
- else:
- # Appending a new section to toolbox.tool_panel
- if new_tool_panel_section_label is None:
- # This might add an ugly section label to the tool panel, but, oh well...
- new_tool_panel_section_label = tool_panel_section_id
- elem = XmlET.Element( 'section' )
- elem.attrib[ 'name' ] = new_tool_panel_section_label
- elem.attrib[ 'id' ] = tool_panel_section_id
- elem.attrib[ 'version' ] = ''
- tool_section = galaxy.tools.ToolSection( elem )
- toolbox.tool_panel[ tool_panel_section_key ] = tool_section
- log.debug( "Loading new tool panel section: %s" % str( tool_section.name ) )
- return tool_panel_section_key, tool_section
+ return toolbox.get_or_create_section( section_id=tool_panel_section_id, new_label=new_tool_panel_section_label )
def get_shed_tool_conf_dict( self, shed_tool_conf ):
"""
diff -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b -r 697b58fa885a215bbcd33aa6e09c8f98e2c8b7fe test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -6,63 +6,7 @@
import tools_support
-class ToolBoxTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
-
- def test_load_file( self ):
- self._init_tool()
- self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
-
- toolbox = self.toolbox
- assert toolbox.get_tool( "test_tool" ) is not None
- assert toolbox.get_tool( "not_a_test_tool" ) is None
-
- def test_load_file_in_section( self ):
- self._init_tool()
- self.__add_config( """<toolbox><section id="t" name="test"><tool file="tool.xml" /></section></toolbox>""" )
-
- toolbox = self.toolbox
- assert toolbox.get_tool( "test_tool" ) is not None
- assert toolbox.get_tool( "not_a_test_tool" ) is None
-
- def test_writes_integrate_tool_panel( self ):
- self._init_tool()
- self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
-
- self.assert_integerated_tool_panel(exists=False)
- self.toolbox
- self.assert_integerated_tool_panel(exists=True)
-
- def test_groups_tools( self ):
- self._init_tool()
- self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
-
- def test_update_shed_conf(self):
- self.__setup_shed_tool_conf()
- self.toolbox.update_shed_config( 0, {} )
- assert self.reindexed
- self.assert_integerated_tool_panel(exists=True)
-
- def test_update_shed_conf_deactivate_only(self):
- self.__setup_shed_tool_conf()
- self.toolbox.update_shed_config( 0, {}, integrated_panel_changes=False )
- assert self.reindexed
- # No changes, should be regenerated
- self.assert_integerated_tool_panel(exists=False)
-
- def setUp( self ):
- self.reindexed = False
- self.setup_app( mock_model=False )
- self.app.reindex_tool_search = self.__reindex
- itp_config = os.path.join(self.test_directory, "integrated_tool_panel.xml")
- self.app.config.integrated_tool_panel_config = itp_config
- self.__toolbox = None
- self.config_files = []
-
- def __reindex( self ):
- self.reindexed = True
-
- def __remove_itp( self ):
- os.remove( os.path)
+class BaseToolBoxTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
@property
def integerated_tool_panel_path( self ):
@@ -81,14 +25,73 @@
self.__toolbox = SimplifiedToolBox( self )
return self.__toolbox
- def __add_config( self, xml, name="tool_conf.xml" ):
+ def setUp( self ):
+ self.reindexed = False
+ self.setup_app( mock_model=False )
+ self.app.reindex_tool_search = self.__reindex
+ itp_config = os.path.join(self.test_directory, "integrated_tool_panel.xml")
+ self.app.config.integrated_tool_panel_config = itp_config
+ self.__toolbox = None
+ self.config_files = []
+
+ def _add_config( self, xml, name="tool_conf.xml" ):
path = os.path.join( self.test_directory, "tool_conf.xml" )
with open( path, "w" ) as f:
f.write( xml )
self.config_files.append( path )
+ def __reindex( self ):
+ self.reindexed = True
+
+
+class ToolBoxTestCase( BaseToolBoxTestCase ):
+
+ def test_load_file( self ):
+ self._init_tool()
+ self._add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ toolbox = self.toolbox
+ assert toolbox.get_tool( "test_tool" ) is not None
+ assert toolbox.get_tool( "not_a_test_tool" ) is None
+
+ def test_load_file_in_section( self ):
+ self._init_tool()
+ self._add_config( """<toolbox><section id="t" name="test"><tool file="tool.xml" /></section></toolbox>""" )
+
+ toolbox = self.toolbox
+ assert toolbox.get_tool( "test_tool" ) is not None
+ assert toolbox.get_tool( "not_a_test_tool" ) is None
+
+ def test_writes_integrate_tool_panel( self ):
+ self._init_tool()
+ self._add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ self.assert_integerated_tool_panel(exists=False)
+ self.toolbox
+ self.assert_integerated_tool_panel(exists=True)
+
+ def test_groups_tools( self ):
+ self._init_tool()
+ self._add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ def test_update_shed_conf(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {} )
+ assert self.reindexed
+ self.assert_integerated_tool_panel(exists=True)
+
+ def test_update_shed_conf_deactivate_only(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {}, integrated_panel_changes=False )
+ assert self.reindexed
+ # No changes, should be regenerated
+ self.assert_integerated_tool_panel(exists=False)
+
+ def __remove_itp( self ):
+ os.remove( os.path)
+
def __setup_shed_tool_conf( self ):
- self.__add_config( """<toolbox tool_path="."></toolbox>""" )
+ self._add_config( """<toolbox tool_path="."></toolbox>""" )
self.toolbox # create toolbox
assert not self.reindexed
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
7 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d3298df33143/
Changeset: d3298df33143
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Make tool filters properties optional attributes of config.
This way the tool shed doesn't need to pointlessly add them to its config object.
Affected #: 2 files
diff -r 3131a76ddd932911a80838d83aaf71baf26a3d6f -r d3298df33143d829bc9e9ed5d1cae0e1c39b60b1 lib/galaxy/tools/filters/__init__.py
--- a/lib/galaxy/tools/filters/__init__.py
+++ b/lib/galaxy/tools/filters/__init__.py
@@ -20,9 +20,9 @@
self.default_filters = dict( tool=[ _not_hidden, _handle_requires_login ], section=[], label=[] )
# Add dynamic filters to these default filters.
config = toolbox.app.config
- self.__init_filters( "tool", config.tool_filters, self.default_filters )
- self.__init_filters( "section", config.tool_section_filters, self.default_filters )
- self.__init_filters( "label", config.tool_label_filters, self.default_filters )
+ self.__init_filters( "tool", getattr( config, "tool_filters", "" ), self.default_filters )
+ self.__init_filters( "section", getattr( config, "tool_section_filters", "" ), self.default_filters )
+ self.__init_filters( "label", getattr( config, "tool_label_filters", "" ), self.default_filters )
def build_filters( self, trans, **kwds ):
"""
diff -r 3131a76ddd932911a80838d83aaf71baf26a3d6f -r d3298df33143d829bc9e9ed5d1cae0e1c39b60b1 lib/galaxy/webapps/tool_shed/config.py
--- a/lib/galaxy/webapps/tool_shed/config.py
+++ b/lib/galaxy/webapps/tool_shed/config.py
@@ -50,9 +50,6 @@
self.test_conf = resolve_path( kwargs.get( "test_conf", "" ), self.root )
self.id_secret = kwargs.get( "id_secret", "USING THE DEFAULT IS NOT SECURE!" )
# Tool stuff
- self.tool_filters = listify( kwargs.get( "tool_filters", [] ) )
- self.tool_label_filters = listify( kwargs.get( "tool_label_filters", [] ) )
- self.tool_section_filters = listify( kwargs.get( "tool_section_filters", [] ) )
self.tool_path = resolve_path( kwargs.get( "tool_path", "tools" ), self.root )
self.tool_secret = kwargs.get( "tool_secret", "" )
self.tool_data_path = resolve_path( kwargs.get( "tool_data_path", "shed-tool-data" ), os.getcwd() )
https://bitbucket.org/galaxy/galaxy-central/commits/175345aa482e/
Changeset: 175345aa482e
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Make use_tool_dependencies an optional attribute of config.
This way the tool shed doesn't need to pointlessly configure this property to create a toolbox.
Affected #: 2 files
diff -r d3298df33143d829bc9e9ed5d1cae0e1c39b60b1 -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 lib/galaxy/tools/deps/__init__.py
--- a/lib/galaxy/tools/deps/__init__.py
+++ b/lib/galaxy/tools/deps/__init__.py
@@ -14,7 +14,7 @@
def build_dependency_manager( config ):
- if config.use_tool_dependencies:
+ if getattr( config, "use_tool_dependencies", False ):
dependency_manager_kwds = {
'default_base_path': config.tool_dependency_dir,
'conf_file': config.dependency_resolvers_config_file,
diff -r d3298df33143d829bc9e9ed5d1cae0e1c39b60b1 -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 lib/galaxy/webapps/tool_shed/config.py
--- a/lib/galaxy/webapps/tool_shed/config.py
+++ b/lib/galaxy/webapps/tool_shed/config.py
@@ -59,13 +59,6 @@
self.ftp_upload_dir = kwargs.get( 'ftp_upload_dir', None )
# Install and test framework for testing tools contained in repositories.
self.num_tool_test_results_saved = kwargs.get( 'num_tool_test_results_saved', 5 )
- # Location for dependencies
- if 'tool_dependency_dir' in kwargs:
- self.tool_dependency_dir = resolve_path( kwargs.get( "tool_dependency_dir" ), self.root )
- self.use_tool_dependencies = True
- else:
- self.tool_dependency_dir = None
- self.use_tool_dependencies = False
self.update_integrated_tool_panel = False
# Galaxy flavor Docker Image
self.enable_galaxy_flavor_docker_image = string_as_bool( kwargs.get( "enable_galaxy_flavor_docker_image", "False" ) )
https://bitbucket.org/galaxy/galaxy-central/commits/50150dc1e84a/
Changeset: 50150dc1e84a
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Update XML library use during tool parsing to elimiante FutureWarnings.
Affected #: 5 files
diff -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -742,13 +742,13 @@
root = getattr( tool_source, "root", None )
# TODO: mucking with the XML directly like this is terrible,
# modify inputs directly post load if possible.
- if root and hasattr( self.app, "job_config" ): # toolshed may not have job_config?
- tool_id = root.get( 'id' ) if root else None
+ if root is not None and hasattr( self.app, "job_config" ): # toolshed may not have job_config?
+ tool_id = root.get( 'id' )
parameters = self.app.job_config.get_tool_resource_parameters( tool_id )
if parameters:
inputs = root.find('inputs')
# If tool has not inputs, create some so we can insert conditional
- if not inputs:
+ if inputs is None:
inputs = ElementTree.fromstring( "<inputs></inputs>")
root.append( inputs )
# Insert a conditional allowing user to specify resource parameters.
@@ -1563,7 +1563,7 @@
root = tool_source.root
conf_parent_elem = root.find("configfiles")
- if conf_parent_elem:
+ if conf_parent_elem is not None:
for conf_elem in conf_parent_elem.findall( "configfile" ):
name = conf_elem.get( "name" )
filename = conf_elem.get( "filename", None )
@@ -1697,7 +1697,7 @@
root = tool_source.root
citations = []
citations_elem = root.find("citations")
- if not citations_elem:
+ if citations_elem is None:
return citations
for citation_elem in citations_elem:
diff -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -49,7 +49,7 @@
self.label = input_source.parse_label()
self.help = input_source.parse_help()
sanitizer_elem = input_source.parse_sanitizer_elem()
- if sanitizer_elem:
+ if sanitizer_elem is not None:
self.sanitizer = ToolParameterSanitizer.from_element( sanitizer_elem )
else:
self.sanitizer = None
diff -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 lib/galaxy/tools/parameters/input_translation.py
--- a/lib/galaxy/tools/parameters/input_translation.py
+++ b/lib/galaxy/tools/parameters/input_translation.py
@@ -59,7 +59,7 @@
append_param = None
value_trans_elem = req_param.find( 'value_translation' )
- if value_trans_elem:
+ if value_trans_elem is not None:
for value_elem in value_trans_elem.findall( 'value' ):
remote_value = value_elem.get( "remote_value" )
galaxy_value = value_elem.get( "galaxy_value" )
@@ -67,7 +67,7 @@
value_trans[ remote_value ] = galaxy_value
append_param_elem = req_param.find( "append_param" )
- if append_param_elem:
+ if append_param_elem is not None:
separator = append_param_elem.get( 'separator', ',' )
first_separator = append_param_elem.get( 'first_separator', None )
join_str = append_param_elem.get( 'join', '=' )
diff -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 lib/galaxy/tools/parameters/output.py
--- a/lib/galaxy/tools/parameters/output.py
+++ b/lib/galaxy/tools/parameters/output.py
@@ -15,7 +15,7 @@
def __init__( self, parent, config_elem ):
self.parent = parent
self.actions = []
- if config_elem:
+ if config_elem is not None:
for elem in config_elem:
if elem.tag == "conditional":
self.actions.append( ToolOutputActionConditional( self, elem ) )
diff -r 175345aa482e4ef394e639b1a3688ee38ac84fc4 -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 lib/galaxy/tools/parser/xml.py
--- a/lib/galaxy/tools/parser/xml.py
+++ b/lib/galaxy/tools/parser/xml.py
@@ -604,7 +604,7 @@
def __init__(self, root):
self.input_elem = root.find("inputs")
page_sources = []
- if self.input_elem:
+ if self.input_elem is not None:
pages_elem = self.input_elem.findall( "page" )
for page in ( pages_elem or [ self.input_elem ] ):
page_sources.append(XmlPageSource(page))
https://bitbucket.org/galaxy/galaxy-central/commits/cf6352cc45a4/
Changeset: cf6352cc45a4
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Start work on unit tests for galaxy.tools.ToolBox.
Affected #: 2 files
diff -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 -r cf6352cc45a45ffa3430d24944bd4ace50ba9c6a test/unit/tools/test_toolbox.py
--- /dev/null
+++ b/test/unit/tools/test_toolbox.py
@@ -0,0 +1,75 @@
+import os
+import unittest
+
+from galaxy.tools import ToolBox
+from galaxy.model.tool_shed_install import mapping
+import tools_support
+
+
+class ToolBoxTestCase( unittest.TestCase, tools_support.UsesApp, tools_support.UsesTools ):
+
+ def test_load_file( self ):
+ self._init_tool()
+ self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ toolbox = self.toolbox
+ assert toolbox.get_tool( "test_tool" ) is not None
+ assert toolbox.get_tool( "not_a_test_tool" ) is None
+
+ def test_load_file_in_section( self ):
+ self._init_tool()
+ self.__add_config( """<toolbox><section id="t" name="test"><tool file="tool.xml" /></section></toolbox>""" )
+
+ toolbox = self.toolbox
+ assert toolbox.get_tool( "test_tool" ) is not None
+ assert toolbox.get_tool( "not_a_test_tool" ) is None
+
+ def test_writes_integrate_tool_panel( self ):
+ self._init_tool()
+ self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ itp = os.path.join(self.test_directory, "integrated_tool_panel.xml")
+
+ assert not os.path.exists( itp )
+ self.toolbox
+ assert os.path.exists( itp )
+
+ def test_groups_tools( self ):
+ self._init_tool()
+ self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+
+ def setUp( self ):
+ self.setup_app( mock_model=False )
+ itp_config = os.path.join(self.test_directory, "integrated_tool_panel.xml")
+ self.app.config.integrated_tool_panel_config = itp_config
+ self.__toolbox = None
+ self.config_files = []
+
+ @property
+ def toolbox( self ):
+ if self.__toolbox is None:
+ self.__toolbox = SimplifiedToolBox( self )
+ return self.__toolbox
+
+ def __add_config( self, xml, name="tool_conf.xml" ):
+ path = os.path.join( self.test_directory, "tool_conf.xml" )
+ with open( path, "w" ) as f:
+ f.write( xml )
+ self.config_files.append( path )
+
+
+class SimplifiedToolBox( ToolBox ):
+
+ def __init__( self, test_case ):
+ app = test_case.app
+ # Handle app/config stuff needed by toolbox but not by tools.
+ app.install_model = mapping.init( "sqlite:///:memory:", create_tables=True )
+ app.job_config.get_tool_resource_parameters = lambda tool_id: None
+ app.config.update_integrated_tool_panel = True
+ config_files = test_case.config_files
+ tool_root_dir = test_case.test_directory
+ super( SimplifiedToolBox, self ).__init__(
+ config_files,
+ tool_root_dir,
+ app,
+ )
diff -r 50150dc1e84a33a2a5c9d73dd7e66c5b8fdc6eb8 -r cf6352cc45a45ffa3430d24944bd4ace50ba9c6a test/unit/tools_support.py
--- a/test/unit/tools_support.py
+++ b/test/unit/tools_support.py
@@ -131,6 +131,7 @@
self.tool_data_tables = {}
self.dataset_collections_service = None
self.container_finder = NullContainerFinder()
+ self.name = "galaxy"
class MockContext(object):
https://bitbucket.org/galaxy/galaxy-central/commits/22151bb4fbca/
Changeset: 22151bb4fbca
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: PEP-8 fixes to tool_shed.galaxy_install.tools.tool_panel_manager.
Affected #: 1 file
diff -r cf6352cc45a45ffa3430d24944bd4ace50ba9c6a -r 22151bb4fbca2519a7f97d71253b8890f5e9a472 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -1,5 +1,4 @@
import logging
-import os
import threading
import galaxy.tools
@@ -355,7 +354,7 @@
# If tool_panel_section_id is received, the section exists in the tool panel. In this
# case, the value of the received tool_panel_section_id must be the id retrieved from a
# tool panel config (e.g., tool_conf.xml, which may have getext). If new_tool_panel_section_label
- # is received, a new section will be added to the tool panel.
+ # is received, a new section will be added to the tool panel.
if new_tool_panel_section_label:
section_id = str( new_tool_panel_section_label.lower().replace( ' ', '_' ) )
tool_panel_section_key, tool_section = \
@@ -396,7 +395,6 @@
tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ]
tool_section_dict = tool_section_dicts[ 0 ]
original_section_id = tool_section_dict[ 'id' ]
- original_section_name = tool_section_dict[ 'name' ]
if original_section_id:
tool_panel_section_key, tool_section = \
self.get_or_create_tool_section( toolbox,
https://bitbucket.org/galaxy/galaxy-central/commits/c161028f01af/
Changeset: c161028f01af
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Introduce abstraction for reindexing tool search.
Fixes re-indexing after tool shed modifications for 5c44ac1 and reduces duplication.
Affected #: 2 files
diff -r 22151bb4fbca2519a7f97d71253b8890f5e9a472 -r c161028f01afc5a2aa3d5f701447fc84d1a9b578 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -706,10 +706,7 @@
from galaxy import tools
self.toolbox = tools.ToolBox( tool_configs, self.config.tool_path, self )
- # Search support for tools
- import galaxy.tools.search
- index_help = getattr( self.config, "index_tool_help", True )
- self.toolbox_search = galaxy.tools.search.ToolBoxSearch( self.toolbox, index_help )
+ self.reindex_tool_search()
from galaxy.tools.deps import containers
galaxy_root_dir = os.path.abspath(self.config.root)
@@ -720,7 +717,13 @@
outputs_to_working_directory=self.config.outputs_to_working_directory,
container_image_cache_path=self.config.container_image_cache_path,
)
- self.container_finder = galaxy.tools.deps.containers.ContainerFinder(app_info)
+ self.container_finder = containers.ContainerFinder(app_info)
+
+ def reindex_tool_search( self ):
+ # Call this when tools are added or removed.
+ import galaxy.tools.search
+ index_help = getattr( self.config, "index_tool_help", True )
+ self.toolbox_search = galaxy.tools.search.ToolBoxSearch( self.toolbox, index_help )
def _configure_tool_data_tables( self, from_shed_config ):
from galaxy.tools.data import ToolDataTableManager
diff -r 22151bb4fbca2519a7f97d71253b8890f5e9a472 -r c161028f01afc5a2aa3d5f701447fc84d1a9b578 lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -2,7 +2,6 @@
import threading
import galaxy.tools
-from galaxy.tools.search import ToolBoxSearch
from xml.etree import ElementTree as XmlET
from tool_shed.util import basic_util
@@ -81,7 +80,7 @@
if self.app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
self.app.toolbox.write_integrated_tool_panel_config_file()
- self.app.toolbox_search = ToolBoxSearch( self.app.toolbox )
+ self.app.reindex_tool_search()
def config_elems_to_xml_file( self, config_elems, config_filename, tool_path ):
"""
@@ -571,7 +570,7 @@
# Update the config_elems of the in-memory shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
self.app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
- self.app.toolbox_search = ToolBoxSearch( self.app.toolbox )
+ self.app.reindex_tool_search()
if uninstall and self.app.config.update_integrated_tool_panel:
# Write the current in-memory version of the integrated_tool_panel.xml file to disk.
self.app.toolbox.write_integrated_tool_panel_config_file()
https://bitbucket.org/galaxy/galaxy-central/commits/5328806e31ac/
Changeset: 5328806e31ac
User: jmchilton
Date: 2014-12-23 18:52:39+00:00
Summary: Introduce abstraction for updating ToolBox's shed configs.
Hides some details of writing out integrated tool panel, reindexing, etc... from tool shed install code and reduces duplicatation in tool shed's tool_panel_manager.
Add unit tests.
Affected #: 3 files
diff -r c161028f01afc5a2aa3d5f701447fc84d1a9b578 -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -244,6 +244,18 @@
return shed_config_dict
return default
+ def update_shed_config( self, shed_conf_index, shed_conf, integrated_panel_changes=True ):
+ """ Update the in-memory descriptions of tools and write out the changes
+ to integrated tool panel unless we are just deactivating a tool (since
+ that doesn't affect that file).
+ """
+ app = self.app
+ self.shed_tool_confs[ shed_conf_index ] = shed_conf
+ if integrated_panel_changes and app.config.update_integrated_tool_panel:
+ # Write the current in-memory version of the integrated_tool_panel.xml file to disk.
+ self.write_integrated_tool_panel_config_file()
+ app.reindex_tool_search()
+
def __resolve_tool_path(self, tool_path, config_filename):
if not tool_path:
# Default to backward compatible config setting.
diff -r c161028f01afc5a2aa3d5f701447fc84d1a9b578 -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
--- a/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
+++ b/lib/tool_shed/galaxy_install/tools/tool_panel_manager.py
@@ -76,11 +76,7 @@
guid=guid )
# Replace the old list of in-memory config_elems with the new list for this shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
- self.app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
- if self.app.config.update_integrated_tool_panel:
- # Write the current in-memory version of the integrated_tool_panel.xml file to disk.
- self.app.toolbox.write_integrated_tool_panel_config_file()
- self.app.reindex_tool_search()
+ self.app.toolbox.update_shed_config( index, shed_tool_conf_dict )
def config_elems_to_xml_file( self, config_elems, config_filename, tool_path ):
"""
@@ -569,8 +565,4 @@
config_elems.remove( config_elem )
# Update the config_elems of the in-memory shed_tool_conf_dict.
shed_tool_conf_dict[ 'config_elems' ] = config_elems
- self.app.toolbox.shed_tool_confs[ index ] = shed_tool_conf_dict
- self.app.reindex_tool_search()
- if uninstall and self.app.config.update_integrated_tool_panel:
- # Write the current in-memory version of the integrated_tool_panel.xml file to disk.
- self.app.toolbox.write_integrated_tool_panel_config_file()
+ self.app.toolbox.update_shed_config( index, shed_tool_conf_dict, integrated_panel_changes=uninstall )
diff -r c161028f01afc5a2aa3d5f701447fc84d1a9b578 -r 5328806e31ac52e01f89b89d4d7873c38d9ae07b test/unit/tools/test_toolbox.py
--- a/test/unit/tools/test_toolbox.py
+++ b/test/unit/tools/test_toolbox.py
@@ -28,23 +28,53 @@
self._init_tool()
self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
- itp = os.path.join(self.test_directory, "integrated_tool_panel.xml")
-
- assert not os.path.exists( itp )
+ self.assert_integerated_tool_panel(exists=False)
self.toolbox
- assert os.path.exists( itp )
+ self.assert_integerated_tool_panel(exists=True)
def test_groups_tools( self ):
self._init_tool()
self.__add_config( """<toolbox><tool file="tool.xml" /></toolbox>""" )
+ def test_update_shed_conf(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {} )
+ assert self.reindexed
+ self.assert_integerated_tool_panel(exists=True)
+
+ def test_update_shed_conf_deactivate_only(self):
+ self.__setup_shed_tool_conf()
+ self.toolbox.update_shed_config( 0, {}, integrated_panel_changes=False )
+ assert self.reindexed
+ # No changes, should be regenerated
+ self.assert_integerated_tool_panel(exists=False)
+
def setUp( self ):
+ self.reindexed = False
self.setup_app( mock_model=False )
+ self.app.reindex_tool_search = self.__reindex
itp_config = os.path.join(self.test_directory, "integrated_tool_panel.xml")
self.app.config.integrated_tool_panel_config = itp_config
self.__toolbox = None
self.config_files = []
+ def __reindex( self ):
+ self.reindexed = True
+
+ def __remove_itp( self ):
+ os.remove( os.path)
+
+ @property
+ def integerated_tool_panel_path( self ):
+ return os.path.join(self.test_directory, "integrated_tool_panel.xml")
+
+ def assert_integerated_tool_panel( self, exists=True ):
+ does_exist = os.path.exists( self.integerated_tool_panel_path )
+ if exists:
+ assert does_exist
+ else:
+ assert not does_exist
+
@property
def toolbox( self ):
if self.__toolbox is None:
@@ -57,6 +87,14 @@
f.write( xml )
self.config_files.append( path )
+ def __setup_shed_tool_conf( self ):
+ self.__add_config( """<toolbox tool_path="."></toolbox>""" )
+
+ self.toolbox # create toolbox
+ assert not self.reindexed
+
+ os.remove( self.integerated_tool_panel_path )
+
class SimplifiedToolBox( ToolBox ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3131a76ddd93/
Changeset: 3131a76ddd93
User: carlfeberhard
Date: 2014-12-22 19:58:44+00:00
Summary: merge
Affected #: 29 files
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -254,6 +254,11 @@
"""
Get a History from the database by id, verifying ownership.
"""
+ if trans.user is None and trans.history:
+ if id == trans.security.encode_id( trans.history.id ):
+ return trans.history
+ raise ItemOwnershipException( "Must be logged in to manage Galaxy items", type='error' )
+
history = self.get_object( trans, id, 'History',
check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted )
history = self.security_check( trans, history, check_ownership, check_accessible )
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f test/casperjs/anon-history-tests.js
--- a/test/casperjs/anon-history-tests.js
+++ b/test/casperjs/anon-history-tests.js
@@ -7,127 +7,110 @@
spaceghost.test.begin( 'Testing histories for anonymous users', 0, function suite( test ){
spaceghost.start();
-// ===================================================================
+ // ===================================================================
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ spaceghost.info( 'Will use fixtureData.testUser: ' + email );
+ }
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
- spaceghost.info( 'Will use fixtureData.testUser: ' + email );
-}
+ var editableTextClass = spaceghost.data.selectors.editableText,
+ editableTextInput = spaceghost.data.selectors.editableTextInput,
-var tooltipSelector = spaceghost.data.selectors.tooltipBalloon,
- editableTextClass = spaceghost.data.selectors.editableText,
- editableTextInput = spaceghost.data.selectors.editableTextInput,
+ unnamedName = spaceghost.historypanel.data.text.history.newName,
+ nameSelector = spaceghost.historypanel.data.selectors.history.name,
+ sizeSelector = spaceghost.historypanel.data.selectors.history.size,
+ initialSizeStr = spaceghost.historypanel.data.text.history.newSize,
+ tagIconSelector = spaceghost.historypanel.data.selectors.history.tagIcon,
+ annoIconSelector = spaceghost.historypanel.data.selectors.history.annoIcon,
+ emptyMsgSelector = spaceghost.historypanel.data.selectors.history.emptyMsg,
+ emptyMsgStr = spaceghost.historypanel.data.text.history.emptyMsg;
- unnamedName = spaceghost.historypanel.data.text.history.newName,
- nameSelector = spaceghost.historypanel.data.selectors.history.name,
- sizeSelector = spaceghost.historypanel.data.selectors.history.size,
- initialSizeStr = spaceghost.historypanel.data.text.history.newSize,
- tagIconSelector = spaceghost.historypanel.data.selectors.history.tagIcon,
- annoIconSelector = spaceghost.historypanel.data.selectors.history.annoIcon,
- emptyMsgSelector = spaceghost.historypanel.data.selectors.history.emptyMsg,
- emptyMsgStr = spaceghost.historypanel.data.text.history.emptyMsg,
- anonNameTooltip = spaceghost.historypanel.data.text.anonymous.tooltips.name;
+ var filenameToUpload = '1.txt',
+ filepathToUpload = '../../test-data/' + filenameToUpload;
-var historyFrameInfo = {},
- filenameToUpload = '1.txt',
- filepathToUpload = '../../test-data/' + filenameToUpload,
- testUploadedId = null,
- testUploadInfo = {};
+ // ------------------------------------------------------------------- check the anonymous new, history for form
+ spaceghost.openHomePage().historypanel.waitForHdas( function testPanelStructure(){
+ this.test.comment( 'history panel for anonymous user, new history' );
+ this.test.comment( "history name should exist, be visible, and have text " + unnamedName );
+ this.test.assertExists( nameSelector, nameSelector + ' exists' );
+ this.test.assertVisible( nameSelector, 'History name is visible' );
+ this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
-// =================================================================== TESTS
-// ------------------------------------------------------------------- check the anonymous new, history for form
-spaceghost.openHomePage().historypanel.waitForHdas( function testPanelStructure(){
- this.test.comment( 'history panel for anonymous user, new history' );
+ this.test.comment( "history should display size and size should be 0 bytes" );
+ this.test.assertExists( sizeSelector, 'Found ' + sizeSelector );
+ this.test.assertVisible( sizeSelector, 'History size is visible' );
+ this.test.assertSelectorHasText( sizeSelector, initialSizeStr,
+ 'History size has "' + initialSizeStr + '"' );
- this.test.comment( "history name should exist, be visible, and have text " + unnamedName );
- this.test.assertExists( nameSelector, nameSelector + ' exists' );
- this.test.assertVisible( nameSelector, 'History name is visible' );
- this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
+ this.test.comment( "NO tags or annotations icons should be available for an anonymous user" );
+ this.test.assertDoesntExist( tagIconSelector, 'Tag icon button not found' );
+ this.test.assertDoesntExist( annoIconSelector, 'Annotation icon button not found' );
- this.test.comment( "history should display size and size should be 0 bytes" );
- this.test.assertExists( sizeSelector, 'Found ' + sizeSelector );
- this.test.assertVisible( sizeSelector, 'History size is visible' );
- this.test.assertSelectorHasText( sizeSelector, initialSizeStr,
- 'History size has "' + initialSizeStr + '"' );
-
- this.test.comment( "NO tags or annotations icons should be available for an anonymous user" );
- this.test.assertDoesntExist( tagIconSelector, 'Tag icon button not found' );
- this.test.assertDoesntExist( annoIconSelector, 'Annotation icon button not found' );
-
- this.test.assertExists( emptyMsgSelector, emptyMsgSelector + ' exists' );
- this.test.comment( "A message about the current history being empty should be displayed" );
- this.test.assertVisible( emptyMsgSelector, 'Empty history message is visible' );
- this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
- 'Message contains "' + emptyMsgStr + '"' );
-
- this.test.comment( 'name should NOT be editable when clicked by anon-user' );
- this.assertDoesntHaveClass( nameSelector, editableTextClass, "Name field is not classed as editable text" );
- this.click( nameSelector );
- this.test.assertDoesntExist( editableTextInput, "Clicking on name does not create an input" );
-});
-
-// ------------------------------------------------------------------- anon user can upload file
-spaceghost.then( function testAnonUpload(){
- this.test.comment( 'anon-user should be able to upload files' );
-
- var currHistory = spaceghost.api.histories.index()[0];
- spaceghost.api.tools.thenUpload( currHistory.id, {
- filepath: filepathToUpload
- }, function uploadCallback( uploadedId ){
- testUploadedId = uploadedId;
- });
-});
-spaceghost.openHomePage().historypanel.waitForHdas( function testAnonUpload(){
- this.test.comment( 'uploaded files should be well formed in the panel' );
-
- var hdaElement = spaceghost.getElementInfo( '#dataset-' + testUploadedId );
- this.debug( 'uploaded HDA info: ' + this.jsonStr( this.quickInfo( hdaElement ) ) );
-
- var hasHda = hdaElement,
- hasClass = hdaElement.attributes[ 'class' ],
- hasOkClass = hdaElement.attributes[ 'class' ].indexOf( 'state-ok' ) !== -1;
- this.test.assert( ( hasHda && hasClass && hasOkClass ), "Uploaded file: " + hdaElement.text );
- testUploadInfo = hdaElement;
-});
-spaceghost.then( function testAnonUpload(){
- this.test.comment( "empty should be NO LONGER be displayed" );
- this.test.assertNotVisible( emptyMsgSelector, 'Empty history message is not visible' );
-});
-
-// ------------------------------------------------------------------- anon user can run tool on file
-
-// ------------------------------------------------------------------- anon user registers/logs in -> same history
-spaceghost.user.loginOrRegisterUser( email, password ).openHomePage( function(){
- this.test.comment( 'anon-user should login and be associated with previous history' );
-
- var loggedInAs = spaceghost.user.loggedInAs();
- this.test.assert( loggedInAs === email, 'loggedInAs() matches email: "' + loggedInAs + '"' );
-
- this.historypanel.waitForHdas( function(){
- var hdaInfo = this.historypanel.hdaElementInfoByTitle( filenameToUpload );
- this.test.assert( hdaInfo !== null, "After logging in - found a matching hda by name and hid" );
- if( hdaInfo ){
- this.test.assert( testUploadInfo.attributes.id === hdaInfo.attributes.id,
- "After logging in - found a matching hda by hda view id: " + hdaInfo.attributes.id );
- }
- });
-});
-
-// ------------------------------------------------------------------- logs out -> new history
-spaceghost.user.logout().openHomePage( function(){
- this.test.comment( 'logging out should create a new, anonymous history' );
-
- this.historypanel.waitForHdas( function(){
- this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
+ this.test.assertExists( emptyMsgSelector, emptyMsgSelector + ' exists' );
+ this.test.comment( "A message about the current history being empty should be displayed" );
+ this.test.assertVisible( emptyMsgSelector, 'Empty history message is visible' );
this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
'Message contains "' + emptyMsgStr + '"' );
+
+ this.test.comment( 'name should NOT be editable when clicked by anon-user' );
+ this.assertDoesntHaveClass( nameSelector, editableTextClass, "Name field is not classed as editable text" );
+ this.click( nameSelector );
+ this.test.assertDoesntExist( editableTextInput, "Clicking on name does not create an input" );
});
-});
-// ===================================================================
+ // ------------------------------------------------------------------- anon user can upload file
+ var uploadedId = null;
+ spaceghost.api.tools.thenUploadToCurrent({ filepath: filepathToUpload }, function( id, json ){
+ uploadedId = id;
+ });
+ spaceghost.openHomePage().historypanel.waitForHdas( function testAnonUpload(){
+ this.test.comment( 'anon-user should be able to upload files' );
+ this.test.assertExists( '#dataset-' + uploadedId, "found hda" );
+ var hdaElement = this.elementInfoOrNull( '#dataset-' + uploadedId );
+ this.debug( 'hdaElement: ' + hdaElement );
+ if( hdaElement ){
+ this.test.assert( hdaElement.attributes[ 'class' ].indexOf( 'state-ok' ) !== -1,
+ "Uploaded file: " + hdaElement.text );
+ }
+
+ this.test.comment( "empty should be NO LONGER be displayed" );
+ this.test.assertNotVisible( emptyMsgSelector, 'Empty history message is not visible' );
+ });
+
+ // ------------------------------------------------------------------- anon user can run tool on file
+
+ // ------------------------------------------------------------------- anon user registers/logs in -> same history
+ spaceghost.user.loginOrRegisterUser( email, password ).openHomePage( function(){
+ this.test.comment( 'anon-user should login and be associated with previous history' );
+
+ var loggedInAs = spaceghost.user.loggedInAs();
+ this.test.assert( loggedInAs === email, 'loggedInAs() matches email: "' + loggedInAs + '"' );
+
+ this.historypanel.waitForHdas( function(){
+ var hdaInfo = this.historypanel.hdaElementInfoByTitle( filenameToUpload );
+ this.test.assert( hdaInfo !== null, "After logging in - found a matching hda by name and hid" );
+ if( hdaInfo ){
+ this.test.assert( 'dataset-' + uploadedId === hdaInfo.attributes.id,
+ "After logging in - found a matching hda by hda view id: " + hdaInfo.attributes.id );
+ }
+ });
+ });
+
+ // ------------------------------------------------------------------- logs out -> new history
+ spaceghost.user.logout().openHomePage( function(){
+ this.test.comment( 'logging out should create a new, anonymous history' );
+
+ this.historypanel.waitForHdas( function(){
+ this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
+ this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
+ 'Message contains "' + emptyMsgStr + '"' );
+ });
+ });
+
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f test/casperjs/api-anon-history-permission-tests.js
--- a/test/casperjs/api-anon-history-permission-tests.js
+++ b/test/casperjs/api-anon-history-permission-tests.js
@@ -8,195 +8,194 @@
+ 'with anonymous users over the API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-var inaccessibleHistory, accessibleHistory, publishedHistory,
- inaccessibleHdas, accessibleHdas, publishedHdas,
- accessibleLink;
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ var inaccessibleHistory, accessibleHistory, publishedHistory,
+ inaccessibleHdas, accessibleHdas, publishedHdas;
-//// ------------------------------------------------------------------------------------------- create 3 histories
-spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- // create three histories: make the 2nd importable (via the API), and the third published
+ //// ------------------------------------------------------------------------------------------- create 3 histories
+ spaceghost.user.loginOrRegisterUser( email, password );
+ spaceghost.openHomePage().then( function(){
+ // create three histories: make the 2nd importable (via the API), and the third published
- // make the current the inaccessible one
- inaccessibleHistory = this.api.histories.index()[0];
- this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
- inaccessibleHistory = this.api.histories.index()[0];
+ // make the current the inaccessible one
+ inaccessibleHistory = this.api.histories.index()[0];
+ this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
+ inaccessibleHistory = this.api.histories.index()[0];
- accessibleHistory = this.api.histories.create({ name: 'accessible' });
- var returned = this.api.histories.update( accessibleHistory.id, {
- importable : true
+ accessibleHistory = this.api.histories.create({ name: 'accessible' });
+ var returned = this.api.histories.update( accessibleHistory.id, {
+ importable : true
+ });
+ //this.debug( this.jsonStr( returned ) );
+ accessibleHistory = this.api.histories.show( accessibleHistory.id );
+
+ publishedHistory = this.api.histories.create({ name: 'published' });
+ returned = this.api.histories.update( publishedHistory.id, {
+ published : true
+ });
+ //this.debug( this.jsonStr( returned ) );
+ publishedHistory = this.api.histories.show( publishedHistory.id );
+
});
- //this.debug( this.jsonStr( returned ) );
- accessibleHistory = this.api.histories.show( accessibleHistory.id );
- publishedHistory = this.api.histories.create({ name: 'published' });
- returned = this.api.histories.update( publishedHistory.id, {
- published : true
+ //// ------------------------------------------------------------------------------------------- upload some files
+ spaceghost.then( function(){
+ this.api.tools.thenUpload( inaccessibleHistory.id, { filepath: '../../test-data/1.bed' });
+ this.api.tools.thenUpload( accessibleHistory.id, { filepath: '../../test-data/1.bed' });
+ this.api.tools.thenUpload( publishedHistory.id, { filepath: '../../test-data/1.bed' });
});
- //this.debug( this.jsonStr( returned ) );
- publishedHistory = this.api.histories.show( publishedHistory.id );
+ spaceghost.then( function(){
+ // check that they're there
+ inaccessibleHdas = this.api.hdas.index( inaccessibleHistory.id ),
+ accessibleHdas = this.api.hdas.index( accessibleHistory.id ),
+ publishedHdas = this.api.hdas.index( publishedHistory.id );
+ });
+ spaceghost.user.logout();
-});
+ // =================================================================== TESTS
+ //// ------------------------------------------------------------------------------------------- anon user
+ function testAnonReadFunctionsOnAccessible( history, hdas ){
+ this.test.comment( '---- testing read/accessibility functions for ACCESSIBLE history: ' + history.name );
-//// ------------------------------------------------------------------------------------------- upload some files
-spaceghost.then( function(){
- this.api.tools.thenUpload( inaccessibleHistory.id, { filepath: '../../test-data/1.bed' });
- this.api.tools.thenUpload( accessibleHistory.id, { filepath: '../../test-data/1.bed' });
- this.api.tools.thenUpload( publishedHistory.id, { filepath: '../../test-data/1.bed' });
-});
-spaceghost.then( function(){
- // check that they're there
- inaccessibleHdas = this.api.hdas.index( inaccessibleHistory.id ),
- accessibleHdas = this.api.hdas.index( accessibleHistory.id ),
- publishedHdas = this.api.hdas.index( publishedHistory.id );
-});
-spaceghost.user.logout();
+ // read functions for history
+ this.test.comment( 'show should work for history: ' + history.name );
+ this.test.assert( this.api.histories.show( history.id ).id === history.id,
+ 'show worked' );
+ this.test.comment( 'copying should fail for history (multiple histories not allowed): ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ history_id : history.id });
+ }, 403, 'API authentication required for this request', 'update authentication required' );
-// =================================================================== TESTS
-//// ------------------------------------------------------------------------------------------- anon user
-function testAnonReadFunctionsOnAccessible( history, hdas ){
- this.test.comment( '---- testing read/accessibility functions for ACCESSIBLE history: ' + history.name );
+ // read functions for history contents
+ this.test.comment( 'index of history contents should work for history: ' + history.name );
+ this.test.assert( this.api.hdas.index( history.id ).length === 1,
+ 'hda index worked' );
+ this.test.comment( 'showing of history contents should work for history: ' + history.name );
+ this.test.assert( this.api.hdas.show( history.id, hdas[0].id ).id === hdas[0].id,
+ 'hda show worked' );
- // read functions for history
- this.test.comment( 'show should work for history: ' + history.name );
- this.test.assert( this.api.histories.show( history.id ).id === history.id,
- 'show worked' );
- this.test.comment( 'copying should fail for history (multiple histories not allowed): ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.create({ history_id : history.id });
- }, 403, 'API authentication required for this request', 'update authentication required' );
-
- // read functions for history contents
- this.test.comment( 'index of history contents should work for history: ' + history.name );
- this.test.assert( this.api.hdas.index( history.id ).length === 1,
- 'hda index worked' );
- this.test.comment( 'showing of history contents should work for history: ' + history.name );
- this.test.assert( this.api.hdas.show( history.id, hdas[0].id ).id === hdas[0].id,
- 'hda show worked' );
-
- this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
- + ' should work from accessible history: ' + history.name );
- this.api.hdas.create( this.api.histories.index()[0].id, {
- source : 'hda',
- content : hdas[0].id
- });
-}
-
-function testAnonReadFunctionsOnInaccessible( history, hdas ){
- this.test.comment( '---- testing read/accessibility functions for INACCESSIBLE history: ' + history.name );
-
- // read functions for history
- this.test.comment( 'show should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.show( history.id );
- }, 403, 'History is not accessible to the current user', 'show failed with error' );
- this.test.comment( 'copying should fail for history (implicit multiple histories): ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.create({ history_id : history.id });
- }, 403, 'API authentication required for this request', 'copy failed with error' );
-
- // read functions for history contents
- this.test.comment( 'index and show of history contents should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.index( history.id );
- }, 403, 'History is not accessible to the current user', 'hda index failed with error' );
- this.api.assertRaises( function(){
- this.api.hdas.show( history.id, hdas[0].id );
- }, 403, 'History is not accessible to the current user', 'hda show failed with error' );
-
- this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
- + ' from an inaccessible history should fail for: ' + history.name );
- this.api.assertRaises( function(){
- var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
+ this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ + ' should work from accessible history: ' + history.name );
+ this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
- this.debug( this.jsonStr( returned ) );
- }, 403, 'History is not accessible to the current user', 'hda copy from failed with error' );
+ }
-}
+ function testAnonReadFunctionsOnInaccessible( history, hdas ){
+ this.test.comment( '---- testing read/accessibility functions for INACCESSIBLE history: ' + history.name );
-function testAnonWriteFunctions( history, hdas ){
- this.test.comment( '---- testing write/ownership functions for history: ' + history.name );
+ // read functions for history
+ this.test.comment( 'show should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.show( history.id );
+ }, 403, 'History is not accessible to the current user', 'show failed with error' );
+ this.test.comment( 'copying should fail for history (implicit multiple histories): ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ history_id : history.id });
+ }, 403, 'API authentication required for this request', 'copy failed with error' );
- this.test.comment( 'update should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.update( history.id, { deleted: true });
- }, 403, 'API authentication required for this request', 'update authentication required' );
- this.test.comment( 'delete should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.delete_( history.id );
- }, 403, 'API authentication required for this request', 'delete authentication required' );
+ // read functions for history contents
+ this.test.comment( 'index and show of history contents should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.index( history.id );
+ }, 403, 'History is not accessible to the current user', 'hda index failed with error' );
+ this.api.assertRaises( function(){
+ this.api.hdas.show( history.id, hdas[0].id );
+ }, 403, 'History is not accessible to the current user', 'hda show failed with error' );
- this.test.comment( 'hda updating should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.update( history.id, hdas[0].id, { deleted: true });
- // anon hda update fails w/ this msg if trying to update non-current history hda
- }, 403, 'You must be logged in to update this history', 'hda update failed with error' );
- this.test.comment( 'hda deletion should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( history.id, hdas[0].id );
- }, 403, 'API authentication required for this request', 'hda delete failed with error' );
+ this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ + ' from an inaccessible history should fail for: ' + history.name );
+ this.api.assertRaises( function(){
+ var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
+ source : 'hda',
+ content : hdas[0].id
+ });
+ this.debug( this.jsonStr( returned ) );
+ }, 403, 'History is not accessible to the current user', 'hda copy from failed with error' );
- this.test.comment( 'copying hda into history should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.create( history.id, {
- source : 'hda',
- // should error before it checks the id
- content : 'bler'
+ }
+
+ function testAnonWriteFunctions( history, hdas ){
+ this.test.comment( '---- testing write/ownership functions for history: ' + history.name );
+
+ this.test.comment( 'update should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.update( history.id, { deleted: true });
+ }, 403, 'API authentication required for this request', 'update authentication required' );
+ this.test.comment( 'delete should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.delete_( history.id );
+ }, 403, 'API authentication required for this request', 'delete authentication required' );
+
+ this.test.comment( 'hda updating should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.update( history.id, hdas[0].id, { deleted: true });
+ // anon hda update fails w/ this msg if trying to update non-current history hda
+ }, 403, 'You must be logged in to update this history', 'hda update failed with error' );
+ this.test.comment( 'hda deletion should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( history.id, hdas[0].id );
+ }, 403, 'API authentication required for this request', 'hda delete failed with error' );
+
+ this.test.comment( 'copying hda into history should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.create( history.id, {
+ source : 'hda',
+ // should error before it checks the id
+ content : 'bler'
+ });
+ }, 403, 'Must be logged in to manage Galaxy histories', 'hda copy to failed' );
+ }
+
+ function testAnonInaccessible( history, hdas ){
+ testAnonReadFunctionsOnInaccessible.call( this, history, hdas );
+ testAnonWriteFunctions.call( this, history, hdas );
+ }
+
+ function testAnonAccessible( history, hdas ){
+ testAnonReadFunctionsOnAccessible.call( this, history, hdas );
+ testAnonWriteFunctions.call( this, history, hdas );
+ }
+
+ spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
+ testAnonInaccessible.call( spaceghost, inaccessibleHistory, inaccessibleHdas );
+ testAnonAccessible.call( spaceghost, accessibleHistory, accessibleHdas );
+ testAnonAccessible.call( spaceghost, publishedHistory, publishedHdas );
+ });
+
+
+ // ------------------------------------------------------------------------------------------- user1 revoke perms
+ spaceghost.user.loginOrRegisterUser( email, password );
+ spaceghost.openHomePage().then( function(){
+ this.test.comment( 'revoking perms should prevent access' );
+ this.api.histories.update( accessibleHistory.id, {
+ importable : false
});
- }, 403, 'Must be logged in to manage Galaxy histories', 'hda copy to failed' );
-}
+ var returned = this.api.histories.show( accessibleHistory.id );
-function testAnonInaccessible( history, hdas ){
- testAnonReadFunctionsOnInaccessible.call( this, history, hdas );
- testAnonWriteFunctions.call( this, history, hdas );
-}
+ this.api.histories.update( publishedHistory.id, {
+ importable : false,
+ published : false
+ });
+ returned = this.api.histories.show( publishedHistory.id );
+ });
+ spaceghost.user.logout();
-function testAnonAccessible( history, hdas ){
- testAnonReadFunctionsOnAccessible.call( this, history, hdas );
- testAnonWriteFunctions.call( this, history, hdas );
-}
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- testAnonInaccessible.call( spaceghost, inaccessibleHistory, inaccessibleHdas );
- testAnonAccessible.call( spaceghost, accessibleHistory, accessibleHdas );
- testAnonAccessible.call( spaceghost, publishedHistory, publishedHdas );
-});
+ // ------------------------------------------------------------------------------------------- anon retry perms
+ spaceghost.openHomePage().then( function(){
+ testAnonInaccessible.call( spaceghost, accessibleHistory, accessibleHdas );
+ testAnonInaccessible.call( spaceghost, publishedHistory, publishedHdas );
+ });
-// ------------------------------------------------------------------------------------------- user1 revoke perms
-spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- this.test.comment( 'revoking perms should prevent access' );
- this.api.histories.update( accessibleHistory.id, {
- importable : false
- });
- var returned = this.api.histories.show( accessibleHistory.id );
-
- this.api.histories.update( publishedHistory.id, {
- importable : false,
- published : false
- });
- returned = this.api.histories.show( publishedHistory.id );
-});
-spaceghost.user.logout();
-
-
-// ------------------------------------------------------------------------------------------- anon retry perms
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- testAnonInaccessible.call( spaceghost, accessibleHistory, accessibleHdas );
- testAnonInaccessible.call( spaceghost, publishedHistory, publishedHdas );
-});
-
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f test/casperjs/api-anon-history-tests.js
--- a/test/casperjs/api-anon-history-tests.js
+++ b/test/casperjs/api-anon-history-tests.js
@@ -7,125 +7,116 @@
spaceghost.test.begin( 'Test API functions for histories with an anonymous user', 0, function suite( test ){
spaceghost.start();
-// =================================================================== TESTS
-spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
-spaceghost.then( function(){
+ // =================================================================== TESTS
+ spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
+ spaceghost.then( function(){
- // ------------------------------------------------------------------------------------------- anon allowed
- this.test.comment( 'index should get a list of histories' );
- var index = this.api.histories.index();
- this.test.assert( utils.isArray( index ), "index returned an array: length " + index.length );
- this.test.assert( index.length === 1, 'Has at least one history' );
+ // ------------------------------------------------------------------------------------------- anon allowed
+ this.test.comment( 'index should get a list of histories' );
+ var index = this.api.histories.index();
+ this.test.assert( utils.isArray( index ), "index returned an array: length " + index.length );
+ this.test.assert( index.length === 1, 'Has at least one history' );
- this.test.comment( 'show should get a history details object' );
- var historyShow = this.api.histories.show( index[0].id );
- //this.debug( this.jsonStr( historyShow ) );
- this.test.assert( historyShow.id === index[0].id, 'Is the first history' );
- this.test.assert( this.hasKeys( historyShow, [ 'id', 'name', 'user_id' ] ) );
+ this.test.comment( 'show should get a history details object' );
+ var historyShow = this.api.histories.show( index[0].id );
+ //this.debug( this.jsonStr( historyShow ) );
+ this.test.assert( historyShow.id === index[0].id, 'Is the first history' );
+ this.test.assert( this.hasKeys( historyShow, [ 'id', 'name', 'user_id' ] ) );
- // ------------------------------------------------------------------------------------------- anon forbidden
- //TODO: why not return the current history?
- this.test.comment( 'calling show with "most_recently_used" should return None for an anon user' );
- var recent = this.api.histories.show( 'most_recently_used' );
- this.test.assert( recent === null, 'most_recently_used returned None' );
+ // ------------------------------------------------------------------------------------------- anon forbidden
+ //TODO: why not return the current history?
+ this.test.comment( 'calling show with "most_recently_used" should return None for an anon user' );
+ var recent = this.api.histories.show( 'most_recently_used' );
+ this.test.assert( recent === null, 'most_recently_used returned None' );
- this.test.comment( 'Calling create should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.create({ name: 'new' });
- }, 403, 'API authentication required for this request', 'create failed with error' );
+ this.test.comment( 'Calling create should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ name: 'new' });
+ }, 403, 'API authentication required for this request', 'create failed with error' );
- this.test.comment( 'Calling delete should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.delete_( historyShow.id );
- }, 403, 'API authentication required for this request', 'create failed with error' );
+ this.test.comment( 'Calling delete should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.delete_( historyShow.id );
+ }, 403, 'API authentication required for this request', 'create failed with error' );
- this.test.comment( 'Calling update should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.update( historyShow.id, {} );
- }, 403, 'API authentication required for this request', 'update failed with error' );
+ this.test.comment( 'Calling update should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.update( historyShow.id, {} );
+ }, 403, 'API authentication required for this request', 'update failed with error' );
- //TODO: need these two in api.js
- //this.test.comment( 'Calling archive_import should fail for an anonymous user' );
- //this.api.assertRaises( function(){
- // this.api.histories.archive_import( historyShow.id, {} );
- //}, 403, 'API authentication required for this request', 'archive_import failed with error' );
+ //TODO: need these two in api.js
+ //this.test.comment( 'Calling archive_import should fail for an anonymous user' );
+ //this.api.assertRaises( function(){
+ // this.api.histories.archive_import( historyShow.id, {} );
+ //}, 403, 'API authentication required for this request', 'archive_import failed with error' );
- //this.test.comment( 'Calling archive_download should fail for an anonymous user' );
- //this.api.assertRaises( function(){
- // this.api.histories.archive_download( historyShow.id, {} );
- //}, 403, 'API authentication required for this request', 'archive_download failed with error' );
+ //this.test.comment( 'Calling archive_download should fail for an anonymous user' );
+ //this.api.assertRaises( function(){
+ // this.api.histories.archive_download( historyShow.id, {} );
+ //}, 403, 'API authentication required for this request', 'archive_download failed with error' );
- // test server bad id protection
- spaceghost.test.comment( 'A bad id should throw an error' );
- this.api.assertRaises( function(){
- this.api.histories.show( '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
+ // test server bad id protection
+ spaceghost.test.comment( 'A bad id should throw an error' );
+ this.api.assertRaises( function(){
+ this.api.histories.show( '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
-});
+ });
-// ------------------------------------------------------------------------------------------- hdas
-spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
-spaceghost.then( function(){
- var currHistory = spaceghost.api.histories.index()[0];
- spaceghost.api.tools.thenUpload( currHistory.id, {
- filepath: '../../test-data/1.sam'
- }, function( uploadedId ){
- var hda = spaceghost.api.hdas.show( currHistory.id, uploadedId );
- this.test.assert( hda.state === 'ok', "Convenience function produced hda in ok state" );
- });
-});
+ // ------------------------------------------------------------------------------------------- hdas
+ spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
+ spaceghost.api.tools.thenUploadToCurrent({ filepath: '../../test-data/1.sam' });
+ spaceghost.then( function(){
+ var current = this.api.histories.index()[0];
-spaceghost.then( function(){
- var current = this.api.histories.index()[0];
+ // ------------------------------------------------------------------------------------------- anon allowed
+ this.test.comment( 'anonymous users can index hdas in their current history' );
+ var hdaIndex = this.api.hdas.index( current.id );
+ this.test.assert( hdaIndex.length === 1, 'indexed hdas' );
- // ------------------------------------------------------------------------------------------- anon allowed
- this.test.comment( 'anonymous users can index hdas in their current history' );
- var hdaIndex = this.api.hdas.index( current.id );
- this.test.assert( hdaIndex.length === 1, 'indexed hdas' );
+ this.test.comment( 'anonymous users can show hdas in their current history' );
+ var hda = this.api.hdas.show( current.id, hdaIndex[0].id );
+ this.test.assert( this.hasKeys( hda, [ 'id', 'name' ] ), 'showed hda: ' + hda.name );
- this.test.comment( 'anonymous users can show hdas in their current history' );
- var hda = this.api.hdas.show( current.id, hdaIndex[0].id );
- this.test.assert( this.hasKeys( hda, [ 'id', 'name' ] ), 'showed hda: ' + hda.name );
+ this.test.comment( 'anonymous users can hide hdas in their current history' );
+ var changed = this.api.hdas.update( current.id, hda.id, { visible: false });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.visible === false, 'successfully hidden' );
- this.test.comment( 'anonymous users can hide hdas in their current history' );
- var changed = this.api.hdas.update( current.id, hda.id, { visible: false });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.visible === false, 'successfully hidden' );
+ this.test.comment( 'anonymous users can mark their hdas as deleted in their current history' );
+ changed = this.api.hdas.update( current.id, hda.id, { deleted: true });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.deleted, 'successfully deleted' );
- this.test.comment( 'anonymous users can mark their hdas as deleted in their current history' );
- changed = this.api.hdas.update( current.id, hda.id, { deleted: true });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.deleted, 'successfully deleted' );
+ // ------------------------------------------------------------------------------------------- anon forbidden
+ this.test.comment( 'Creating an hda should work for an anonymous user' );
+ var returned = this.api.hdas.create( current.id, { source: 'hda', content: hda.id });
+ //this.debug( this.jsonStr( returned ) );
+ this.test.assert( returned.name === hda.name, 'name matches: ' + returned.name );
+ this.test.assert( returned.id !== hda.id, 'new id: ' + returned.id );
- // ------------------------------------------------------------------------------------------- anon forbidden
- this.test.comment( 'Creating an hda should work for an anonymous user' );
- var returned = this.api.hdas.create( current.id, { source: 'hda', content: hda.id });
- //this.debug( this.jsonStr( returned ) );
- this.test.assert( returned.name === hda.name, 'name matches: ' + returned.name );
- this.test.assert( returned.id !== hda.id, 'new id: ' + returned.id );
+ //TODO: should be allowed
+ this.test.comment( 'Calling hda delete should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( current.id, hda.id );
+ }, 403, 'API authentication required for this request', 'delete failed with error' );
- //TODO: should be allowed
- this.test.comment( 'Calling hda delete should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( current.id, hda.id );
- }, 403, 'API authentication required for this request', 'delete failed with error' );
+ //TODO: only sharing, tags, annotations should be blocked/prevented
+ this.test.comment( 'Calling update with keys other than "visible" or "deleted" should fail silently' );
+ this.test.comment( 'Calling update on tags should fail silently' );
+ changed = this.api.hdas.update( current.id, hda.id, { tags: [ 'one' ] });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.tags.length === 0, 'tags were not set: ' + this.jsonStr( hda.tags ) );
- //TODO: only sharing, tags, annotations should be blocked/prevented
- this.test.comment( 'Calling update with keys other than "visible" or "deleted" should fail silently' );
- this.test.comment( 'Calling update on tags should fail silently' );
- changed = this.api.hdas.update( current.id, hda.id, { tags: [ 'one' ] });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.tags.length === 0, 'tags were not set: ' + this.jsonStr( hda.tags ) );
+ this.test.comment( 'Calling update on annotation should fail silently' );
+ changed = this.api.hdas.update( current.id, hda.id, { annotation: 'yup yup yup' });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( !hda.annotation, 'annotation was not set: ' + hda.annotation );
- this.test.comment( 'Calling update on annotation should fail silently' );
- changed = this.api.hdas.update( current.id, hda.id, { annotation: 'yup yup yup' });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( !hda.annotation, 'annotation was not set: ' + hda.annotation );
+ });
-});
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f test/casperjs/api-configuration-tests.js
--- a/test/casperjs/api-configuration-tests.js
+++ b/test/casperjs/api-configuration-tests.js
@@ -7,57 +7,55 @@
spaceghost.test.begin( 'Test the Galaxy configuration API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-spaceghost.user.loginOrRegisterUser( email, password );
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ spaceghost.user.loginOrRegisterUser( email, password );
-// =================================================================== TESTS
-var normKeys = [
- 'enable_unique_workflow_defaults',
- 'ftp_upload_site',
- 'ftp_upload_dir',
- 'wiki_url',
- 'support_url',
- 'logo_url',
- 'terms_url',
- 'allow_user_dataset_purge'
- ],
- adminKeys = normKeys.concat([
- 'library_import_dir',
- 'user_library_import_dir',
- 'allow_library_path_paste',
- 'allow_user_creation',
- 'allow_user_deletion'
- ]);
+ // =================================================================== TESTS
+ var normKeys = [
+ 'enable_unique_workflow_defaults',
+ 'ftp_upload_site',
+ 'ftp_upload_dir',
+ 'wiki_url',
+ 'support_url',
+ 'logo_url',
+ 'terms_url',
+ 'allow_user_dataset_purge'
+ ],
+ adminKeys = normKeys.concat([
+ 'library_import_dir',
+ 'user_library_import_dir',
+ 'allow_library_path_paste',
+ 'allow_user_creation',
+ 'allow_user_deletion'
+ ]);
+ // ------------------------------------------------------------------------------------------- INDEX
+ spaceghost.openHomePage().then( function(){
+ this.test.comment( 'index should get a (shortened) list of configuration settings '
+ + 'when requested by a normal user' );
-// ------------------------------------------------------------------------------------------- INDEX
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
+ var configIndex = this.api.configuration.index();
+ this.debug( this.jsonStr( configIndex ) );
+ this.test.assert( utils.isObject( configIndex ), "index returned an object" );
+ this.test.assert( this.hasKeys( configIndex, normKeys ), 'Has the proper keys' );
- this.test.comment( 'index should get a (shortened) list of configuration settings '
- + 'when requested by a normal user' );
- var configIndex = this.api.configuration.index();
- this.debug( this.jsonStr( configIndex ) );
- this.test.assert( utils.isObject( configIndex ), "index returned an object" );
- this.test.assert( this.hasKeys( configIndex, normKeys ), 'Has the proper keys' );
+ });
+ spaceghost.user.logout();
-});
-spaceghost.user.logout();
+ // ------------------------------------------------------------------------------------------- INDEX (admin)
+ spaceghost.tryStepsCatch( function tryAdminLogin(){
+ spaceghost.user.loginAdmin();
+ }, function(){} );
-// ------------------------------------------------------------------------------------------- INDEX (admin)
-spaceghost.tryStepsCatch( function tryAdminLogin(){
- spaceghost.user.loginAdmin();
-}, function(){} );
-
-//}, function failedLoginRegister(){
-// this.info( 'Admin level configuration API tests not run: no admin account available' );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- spaceghost.waitForMasthead( function() {
+ //}, function failedLoginRegister(){
+ // this.info( 'Admin level configuration API tests not run: no admin account available' );
+ spaceghost.openHomePage().waitForMasthead( function(){
if( spaceghost.user.userIsAdmin() ){
this.test.comment( 'index should get a (full) list of configuration settings '
+ 'when requested by an admin user' );
@@ -70,9 +68,8 @@
this.info( 'Admin level configuration API tests not run: no admin account available' );
}
});
-});
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f -r 3131a76ddd932911a80838d83aaf71baf26a3d6f test/casperjs/api-hda-tests.js
--- a/test/casperjs/api-hda-tests.js
+++ b/test/casperjs/api-hda-tests.js
@@ -7,363 +7,359 @@
spaceghost.test.begin( 'Test the HDA API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-spaceghost.user.loginOrRegisterUser( email, password );
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl, function(){
- this.test.comment( '(logged in as ' + this.user.loggedInAs() + ')' );
- this.api.tools.thenUpload( spaceghost.api.histories.index()[0].id, {
+ spaceghost.openHomePage().api.tools.thenUploadToCurrent({
filepath: '../../test-data/1.sam'
});
-});
-// =================================================================== TESTS
-var summaryKeys = [ 'id', 'name', 'history_id', 'state', 'deleted', 'purged', 'visible', 'url', 'type' ],
- detailKeys = [
- // the following are always present regardless of datatype
- 'id', 'name', 'api_type', 'model_class',
- 'history_id', 'hid',
- 'accessible', 'deleted', 'visible', 'purged',
- 'state', 'data_type', 'file_ext', 'file_size',
- 'misc_info', 'misc_blurb',
- 'download_url', 'visualizations', 'display_apps', 'display_types',
- 'genome_build',
- // the following are NOT always present DEPENDING ON datatype
- 'metadata_dbkey',
- 'metadata_column_names', 'metadata_column_types', 'metadata_columns',
- 'metadata_comment_lines', 'metadata_data_lines'
- ];
+ // =================================================================== TESTS
+ var summaryKeys = [ 'id', 'name', 'history_id', 'state', 'deleted', 'purged', 'visible', 'url', 'type' ],
+ detailKeys = [
+ // the following are always present regardless of datatype
+ 'id', 'name', 'api_type', 'model_class',
+ 'history_id', 'hid',
+ 'accessible', 'deleted', 'visible', 'purged',
+ 'state', 'data_type', 'file_ext', 'file_size',
+ 'misc_info', 'misc_blurb',
+ 'download_url', 'visualizations', 'display_apps', 'display_types',
+ 'genome_build',
+ // the following are NOT always present DEPENDING ON datatype
+ 'metadata_dbkey',
+ 'metadata_column_names', 'metadata_column_types', 'metadata_columns',
+ 'metadata_comment_lines', 'metadata_data_lines'
+ ];
-// ------------------------------------------------------------------------------------------- logged in user
-spaceghost.then( function(){
-
- // ------------------------------------------------------------------------------------------- INDEX
- this.test.comment( 'index should return a list of summary data for each hda' );
- var histories = this.api.histories.index(),
- lastHistory = histories[0],
- hdaIndex = this.api.hdas.index( lastHistory.id );
- //this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
+ // ------------------------------------------------------------------------------------------- logged in user
+ spaceghost.then( function(){
+ // ------------------------------------------------------------------------------------------- INDEX
+ this.test.comment( 'index should return a list of summary data for each hda' );
+ var histories = this.api.histories.index(),
+ lastHistory = histories[0],
+ hdaIndex = this.api.hdas.index( lastHistory.id );
+ //this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
- this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
- this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
+ this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
+ this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
- var firstHda = hdaIndex[0];
- this.test.assert( this.hasKeys( firstHda, summaryKeys ), 'Has the proper keys' );
+ var firstHda = hdaIndex[0];
+ this.test.assert( this.hasKeys( firstHda, summaryKeys ), 'Has the proper keys' );
- this.test.assert( this.api.isEncodedId( firstHda.id ), 'Id appears well-formed: ' + firstHda.id );
- this.test.assert( firstHda.name === '1.sam', 'Title matches: ' + firstHda.name );
+ this.test.assert( this.api.isEncodedId( firstHda.id ), 'Id appears well-formed: ' + firstHda.id );
+ this.test.assert( firstHda.name === '1.sam', 'Title matches: ' + firstHda.name );
- // ------------------------------------------------------------------------------------------- SHOW
- this.test.comment( 'show should get an HDA details object' );
- var hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- //this.debug( this.jsonStr( hdaShow ) );
- this.test.assert( this.hasKeys( hdaShow, detailKeys ), 'Has the proper keys' );
+ // ------------------------------------------------------------------------------------------- SHOW
+ this.test.comment( 'show should get an HDA details object' );
+ var hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ //this.debug( this.jsonStr( hdaShow ) );
+ this.test.assert( this.hasKeys( hdaShow, detailKeys ), 'Has the proper keys' );
- //TODO: validate data in each hdaShow attribute...
+ //TODO: validate data in each hdaShow attribute...
- // ------------------------------------------------------------------------------------------- INDEX (detailed)
- this.test.comment( 'index should return a list of detailed data for each hda in "ids" when passed' );
- hdaIndex = this.api.hdas.index( lastHistory.id, [ firstHda.id ] );
- this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
+ // ------------------------------------------------------------------------------------------- INDEX (detailed)
+ this.test.comment( 'index should return a list of detailed data for each hda in "ids" when passed' );
+ hdaIndex = this.api.hdas.index( lastHistory.id, [ firstHda.id ] );
+ this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
- this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
- this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
+ this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
+ this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
- firstHda = hdaIndex[0];
- this.test.assert( this.hasKeys( firstHda, detailKeys ), 'Has the proper keys' );
+ firstHda = hdaIndex[0];
+ this.test.assert( this.hasKeys( firstHda, detailKeys ), 'Has the proper keys' );
- //TODO??: validate data in firstHda attribute? we ASSUME it's from a common method as show...
+ //TODO??: validate data in firstHda attribute? we ASSUME it's from a common method as show...
- // ------------------------------------------------------------------------------------------- CREATE
- //TODO: create from_ld_id
- this.test.comment( 'create should allow copying an accessible hda' );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- var returned = this.api.hdas.create( lastHistory.id, {
- source : 'hda',
- content : hdaShow.id
+ // ------------------------------------------------------------------------------------------- CREATE
+ //TODO: create from_ld_id
+ this.test.comment( 'create should allow copying an accessible hda' );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ var returned = this.api.hdas.create( lastHistory.id, {
+ source : 'hda',
+ content : hdaShow.id
+ });
+ //this.debug( 'returned:' + this.jsonStr( returned ) );
+ this.test.assert( this.hasKeys( returned, detailKeys ), 'Has the proper keys' );
+ this.test.assert( typeof returned.id !== 'number' && isNaN( Number( returned.id ) ),
+ 'id seems to be encoded: ' + returned.id );
+ this.test.assert( typeof returned.history_id !== 'number' && isNaN( Number( returned.history_id ) ),
+ 'history_id seems to be encoded: ' + returned.history_id );
+
+
+ // ------------------------------------------------------------------------------------------- UPDATE
+ // ........................................................................................... idiot proofing
+ this.test.comment( 'updating to the current value should return no value (no change)' );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ var returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : hdaShow.name
+ });
+ this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
+
+ this.test.comment( 'updating using a nonsense key should NOT fail with an error' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ konamiCode : 'uuddlrlrba'
+ });
+ this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
+
+ this.test.comment( 'updating by attempting to change type should cause an error' );
+ this.api.assertRaises( function(){
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ //name : false
+ deleted : 'sure why not'
+ });
+ }, 400, 'deleted must be a boolean', 'changing deleted type failed' );
+
+ // ........................................................................................... name
+ this.test.comment( 'update should allow changing the name' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : 'New name'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === 'New name', "Name successfully set via update: " + hdaShow.name );
+
+ this.test.comment( 'update should sanitize any new name' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : 'New name<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === 'New name', "Update sanitized name: " + hdaShow.name );
+
+ this.test.comment( 'update should allow unicode in names' );
+ var unicodeName = 'Ржевский сапоги';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : unicodeName
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === unicodeName, "Update accepted unicode name: " + hdaShow.name );
+
+ this.test.comment( 'update should allow escaped quotations in names' );
+ var quotedName = '"Bler"';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : quotedName
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === quotedName,
+ "Update accepted escaped quotations in name: " + hdaShow.name );
+
+
+ // ........................................................................................... deleted
+ this.test.comment( 'update should allow changing the deleted flag' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ deleted: true
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id, true );
+ this.test.assert( hdaShow.deleted === true, "Update set the deleted flag: " + hdaShow.deleted );
+
+ this.test.comment( 'update should allow changing the deleted flag back' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ deleted: false
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.deleted === false, "Update set the deleted flag: " + hdaShow.deleted );
+
+
+ // ........................................................................................... visible/hidden
+ this.test.comment( 'update should allow changing the visible flag' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ visible: false
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.visible === false, "Update set the visible flag: " + hdaShow.visible );
+
+
+ // ........................................................................................... genome/dbkey
+ this.test.comment( 'update should allow changing the genome_build' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : 'hg18'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ //this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
+ this.test.assert( hdaShow.genome_build === 'hg18',
+ "genome_build successfully set via update: " + hdaShow.genome_build );
+ this.test.assert( hdaShow.metadata_dbkey === 'hg18',
+ "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
+ this.test.comment( 'update should sanitize any genome_build' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : 'hg18<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.genome_build === 'hg18',
+ "Update sanitized genome_build: " + hdaShow.genome_build );
+ this.test.assert( hdaShow.metadata_dbkey === 'hg18',
+ "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
+
+ this.test.comment( 'update should allow unicode in genome builds' );
+ var unicodeBuild = 'Ржевский18';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : unicodeBuild
+ });
+ this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
+ this.test.assert( hdaShow.genome_build === unicodeBuild,
+ "Update accepted unicode genome_build: " + hdaShow.genome_build );
+
+ // ........................................................................................... misc_info/info
+ this.test.comment( 'update should allow changing the misc_info' );
+ var newInfo = 'I\'ve made a huge mistake.';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : newInfo
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === newInfo,
+ "misc_info successfully set via update: " + hdaShow.misc_info );
+
+ this.test.comment( 'update should sanitize any misc_info' );
+ var newInfo = 'You\'re going to get hop-ons.';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : newInfo + '<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === newInfo,
+ "Update sanitized misc_info: " + hdaShow.misc_info );
+
+ this.test.comment( 'update should allow unicode in misc_info' );
+ var unicodeInfo = '여보!';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : unicodeInfo
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === unicodeInfo,
+ "Update accepted unicode misc_info: " + hdaShow.misc_info );
+
+ // ........................................................................................... annotation
+ // currently fails because no annotation is returned in details
+ this.test.comment( 'update should allow changing the annotation' );
+ var newAnnotation = 'Found this sample on a movie theatre floor';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : newAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === newAnnotation,
+ "Annotation successfully set via update: " + hdaShow.annotation );
+
+ this.test.comment( 'update should sanitize any new annotation' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : 'New annotation<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === 'New annotation',
+ "Update sanitized annotation: " + hdaShow.annotation );
+
+ this.test.comment( 'update should allow unicode in annotations' );
+ var unicodeAnnotation = 'お願いは、それが落下させない';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : unicodeAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === unicodeAnnotation,
+ "Update accepted unicode annotation: " + hdaShow.annotation );
+
+ this.test.comment( 'update should allow escaped quotations in annotations' );
+ var quotedAnnotation = '"Bler"';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : quotedAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === quotedAnnotation,
+ "Update accepted escaped quotations in annotation: " + hdaShow.annotation );
+
+ // ------------------------------------------------------------------------------------------- ERRORS
+ this.test.comment( 'create should error with "Please define the source" when the param "from_ld_id" is not used' );
+ this.api.assertRaises( function(){
+ this.api.hdas.create( lastHistory.id, { bler: 'bler' } );
+ }, 400, "must be either 'library' or 'hda'", 'create with no source failed' );
+
+ this.test.comment( 'updating using a nonsense key should fail silently' );
+ returned = this.api.hdas.update( lastHistory.id, hdaShow.id, {
+ konamiCode : 'uuddlrlrba'
+ });
+ this.test.assert( returned.konamiCode === undefined, 'key was not set: ' + returned.konamiCode );
+
+ spaceghost.test.comment( 'A bad id should throw an error when using show' );
+ this.api.assertRaises( function(){
+ this.api.hdas.show( lastHistory.id, '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
+ spaceghost.test.comment( 'A bad id should throw an error when using update' );
+ this.api.assertRaises( function(){
+ this.api.hdas.update( lastHistory.id, '1234123412341234', {} );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: update' );
+ spaceghost.test.comment( 'A bad id should throw an error when using delete' );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( lastHistory.id, '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: delete' );
+ spaceghost.test.comment( 'A bad id should throw an error when using undelete' );
+
+ this.test.comment( 'updating by attempting to change type should cause an error' );
+ [ 'name', 'annotation', 'genome_build', 'misc_info' ].forEach( function( key ){
+ var updatedAttrs = {};
+ updatedAttrs[ key ] = false;
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
+ }, 400, key + ' must be a string or unicode', 'type validation error' );
+ });
+ [ 'deleted', 'visible' ].forEach( function( key ){
+ var updatedAttrs = {};
+ updatedAttrs[ key ] = 'straaang';
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
+ }, 400, key + ' must be a boolean', 'type validation error' );
+ });
+ [ 'you\'re it', [ true ] ].forEach( function( badVal ){
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, { tags: badVal });
+ }, 400, 'tags must be a list', 'type validation error' );
+ });
+
+ // ------------------------------------------------------------------------------------------- DELETE
+ this.test.comment( 'calling delete on an hda should mark it as deleted but not change the history size' );
+ lastHistory = this.api.histories.show( lastHistory.id );
+ var sizeBeforeDelete = lastHistory.nice_size;
+
+ returned = this.api.hdas.delete_( lastHistory.id, firstHda.id );
+ //this.debug( this.jsonStr( returned ) );
+
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.deleted, 'hda is marked deleted' );
+ lastHistory = this.api.histories.show( lastHistory.id );
+ this.test.assert( lastHistory.nice_size === sizeBeforeDelete, 'history size has not changed' );
+
+ // by default, purging fails bc uni.ini:allow_user_dataset_purge=False
+ this.api.assertRaises( function(){
+ returned = this.api.hdas.delete_( lastHistory.id, firstHda.id, { purge : true });
+ }, 403, 'This instance does not allow user dataset purging', 'Purge failed' );
+ /*
+ */
});
- //this.debug( 'returned:' + this.jsonStr( returned ) );
- this.test.assert( this.hasKeys( returned, detailKeys ), 'Has the proper keys' );
- this.test.assert( typeof returned.id !== 'number' && isNaN( Number( returned.id ) ),
- 'id seems to be encoded: ' + returned.id );
- this.test.assert( typeof returned.history_id !== 'number' && isNaN( Number( returned.history_id ) ),
- 'history_id seems to be encoded: ' + returned.history_id );
+ //spaceghost.user.logout();
- // ------------------------------------------------------------------------------------------- UPDATE
- // ........................................................................................... idiot proofing
- this.test.comment( 'updating to the current value should return no value (no change)' );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- var returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : hdaShow.name
- });
- this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
-
- this.test.comment( 'updating using a nonsense key should NOT fail with an error' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- konamiCode : 'uuddlrlrba'
- });
- this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
-
- this.test.comment( 'updating by attempting to change type should cause an error' );
- this.api.assertRaises( function(){
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- //name : false
- deleted : 'sure why not'
- });
- }, 400, 'deleted must be a boolean', 'changing deleted type failed' );
-
- // ........................................................................................... name
- this.test.comment( 'update should allow changing the name' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : 'New name'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === 'New name', "Name successfully set via update: " + hdaShow.name );
-
- this.test.comment( 'update should sanitize any new name' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : 'New name<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === 'New name', "Update sanitized name: " + hdaShow.name );
-
- this.test.comment( 'update should allow unicode in names' );
- var unicodeName = 'Ржевский сапоги';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : unicodeName
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === unicodeName, "Update accepted unicode name: " + hdaShow.name );
-
- this.test.comment( 'update should allow escaped quotations in names' );
- var quotedName = '"Bler"';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : quotedName
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === quotedName,
- "Update accepted escaped quotations in name: " + hdaShow.name );
-
-
- // ........................................................................................... deleted
- this.test.comment( 'update should allow changing the deleted flag' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- deleted: true
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id, true );
- this.test.assert( hdaShow.deleted === true, "Update set the deleted flag: " + hdaShow.deleted );
-
- this.test.comment( 'update should allow changing the deleted flag back' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- deleted: false
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.deleted === false, "Update set the deleted flag: " + hdaShow.deleted );
-
-
- // ........................................................................................... visible/hidden
- this.test.comment( 'update should allow changing the visible flag' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- visible: false
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.visible === false, "Update set the visible flag: " + hdaShow.visible );
-
-
- // ........................................................................................... genome_build/dbkey
- this.test.comment( 'update should allow changing the genome_build' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : 'hg18'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- //this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
- this.test.assert( hdaShow.genome_build === 'hg18',
- "genome_build successfully set via update: " + hdaShow.genome_build );
- this.test.assert( hdaShow.metadata_dbkey === 'hg18',
- "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
- this.test.comment( 'update should sanitize any genome_build' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : 'hg18<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.genome_build === 'hg18',
- "Update sanitized genome_build: " + hdaShow.genome_build );
- this.test.assert( hdaShow.metadata_dbkey === 'hg18',
- "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
-
- this.test.comment( 'update should allow unicode in genome builds' );
- var unicodeBuild = 'Ржевский18';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : unicodeBuild
- });
- this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
- this.test.assert( hdaShow.genome_build === unicodeBuild,
- "Update accepted unicode genome_build: " + hdaShow.genome_build );
-
- // ........................................................................................... misc_info/info
- this.test.comment( 'update should allow changing the misc_info' );
- var newInfo = 'I\'ve made a huge mistake.';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : newInfo
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === newInfo,
- "misc_info successfully set via update: " + hdaShow.misc_info );
-
- this.test.comment( 'update should sanitize any misc_info' );
- var newInfo = 'You\'re going to get hop-ons.';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : newInfo + '<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === newInfo,
- "Update sanitized misc_info: " + hdaShow.misc_info );
-
- this.test.comment( 'update should allow unicode in misc_info' );
- var unicodeInfo = '여보!';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : unicodeInfo
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === unicodeInfo,
- "Update accepted unicode misc_info: " + hdaShow.misc_info );
-
- // ........................................................................................... annotation
- // currently fails because no annotation is returned in details
- this.test.comment( 'update should allow changing the annotation' );
- var newAnnotation = 'Found this sample on a movie theatre floor';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : newAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === newAnnotation,
- "Annotation successfully set via update: " + hdaShow.annotation );
-
- this.test.comment( 'update should sanitize any new annotation' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : 'New annotation<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === 'New annotation',
- "Update sanitized annotation: " + hdaShow.annotation );
-
- this.test.comment( 'update should allow unicode in annotations' );
- var unicodeAnnotation = 'お願いは、それが落下させない';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : unicodeAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === unicodeAnnotation,
- "Update accepted unicode annotation: " + hdaShow.annotation );
-
- this.test.comment( 'update should allow escaped quotations in annotations' );
- var quotedAnnotation = '"Bler"';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : quotedAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === quotedAnnotation,
- "Update accepted escaped quotations in annotation: " + hdaShow.annotation );
-
- // ------------------------------------------------------------------------------------------- ERRORS
- this.test.comment( 'create should error with "Please define the source" when the param "from_ld_id" is not used' );
- this.api.assertRaises( function(){
- this.api.hdas.create( lastHistory.id, { bler: 'bler' } );
- }, 400, "must be either 'library' or 'hda'", 'create with no source failed' );
-
- this.test.comment( 'updating using a nonsense key should fail silently' );
- returned = this.api.hdas.update( lastHistory.id, hdaShow.id, {
- konamiCode : 'uuddlrlrba'
- });
- this.test.assert( returned.konamiCode === undefined, 'key was not set: ' + returned.konamiCode );
-
- spaceghost.test.comment( 'A bad id should throw an error when using show' );
- this.api.assertRaises( function(){
- this.api.hdas.show( lastHistory.id, '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
- spaceghost.test.comment( 'A bad id should throw an error when using update' );
- this.api.assertRaises( function(){
- this.api.hdas.update( lastHistory.id, '1234123412341234', {} );
- }, 400, 'unable to decode', 'Bad Request with invalid id: update' );
- spaceghost.test.comment( 'A bad id should throw an error when using delete' );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( lastHistory.id, '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: delete' );
- spaceghost.test.comment( 'A bad id should throw an error when using undelete' );
-
- this.test.comment( 'updating by attempting to change type should cause an error' );
- [ 'name', 'annotation', 'genome_build', 'misc_info' ].forEach( function( key ){
- var updatedAttrs = {};
- updatedAttrs[ key ] = false;
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
- }, 400, key + ' must be a string or unicode', 'type validation error' );
- });
- [ 'deleted', 'visible' ].forEach( function( key ){
- var updatedAttrs = {};
- updatedAttrs[ key ] = 'straaang';
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
- }, 400, key + ' must be a boolean', 'type validation error' );
- });
- [ 'you\'re it', [ true ] ].forEach( function( badVal ){
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, { tags: badVal });
- }, 400, 'tags must be a list', 'type validation error' );
- });
-
- // ------------------------------------------------------------------------------------------- DELETE
- this.test.comment( 'calling delete on an hda should mark it as deleted but not change the history size' );
- lastHistory = this.api.histories.show( lastHistory.id );
- var sizeBeforeDelete = lastHistory.nice_size;
-
- returned = this.api.hdas.delete_( lastHistory.id, firstHda.id );
- //this.debug( this.jsonStr( returned ) );
-
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.deleted, 'hda is marked deleted' );
- lastHistory = this.api.histories.show( lastHistory.id );
- this.test.assert( lastHistory.nice_size === sizeBeforeDelete, 'history size has not changed' );
-
- // by default, purging fails bc uni.ini:allow_user_dataset_purge=False
- this.api.assertRaises( function(){
- returned = this.api.hdas.delete_( lastHistory.id, firstHda.id, { purge : true });
- }, 403, 'This instance does not allow user dataset purging', 'Purge failed' );
-/*
-*/
-});
-//spaceghost.user.logout();
-
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: carlfeberhard: UsesHistoryMixin, get_history: allow anon users to get their current history; update browser tests; remove unused selenium tests
by commits-noreply@bitbucket.org 22 Dec '14
by commits-noreply@bitbucket.org 22 Dec '14
22 Dec '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/501f510ff101/
Changeset: 501f510ff101
Branch: next-stable
User: carlfeberhard
Date: 2014-12-22 19:35:08+00:00
Summary: UsesHistoryMixin, get_history: allow anon users to get their current history; update browser tests; remove unused selenium tests
Affected #: 28 files
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -255,6 +255,11 @@
"""
Get a History from the database by id, verifying ownership.
"""
+ if trans.user is None and trans.history:
+ if id == trans.security.encode_id( trans.history.id ):
+ return trans.history
+ raise ItemOwnershipException( "Must be logged in to manage Galaxy items", type='error' )
+
history = self.get_object( trans, id, 'History',
check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted )
history = self.security_check( trans, history, check_ownership, check_accessible )
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b test/casperjs/anon-history-tests.js
--- a/test/casperjs/anon-history-tests.js
+++ b/test/casperjs/anon-history-tests.js
@@ -7,117 +7,111 @@
spaceghost.test.begin( 'Testing histories for anonymous users', 0, function suite( test ){
spaceghost.start();
-// ===================================================================
+ // ===================================================================
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ spaceghost.info( 'Will use fixtureData.testUser: ' + email );
+ }
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
- spaceghost.info( 'Will use fixtureData.testUser: ' + email );
-}
+ var editableTextClass = spaceghost.data.selectors.editableText,
+ editableTextInput = spaceghost.data.selectors.editableTextInput,
-var tooltipSelector = spaceghost.data.selectors.tooltipBalloon,
- editableTextClass = spaceghost.data.selectors.editableText,
- editableTextInput = spaceghost.data.selectors.editableTextInput,
+ unnamedName = spaceghost.historypanel.data.text.history.newName,
+ nameSelector = spaceghost.historypanel.data.selectors.history.name,
+ sizeSelector = spaceghost.historypanel.data.selectors.history.size,
+ initialSizeStr = spaceghost.historypanel.data.text.history.newSize,
+ tagIconSelector = spaceghost.historypanel.data.selectors.history.tagIcon,
+ annoIconSelector = spaceghost.historypanel.data.selectors.history.annoIcon,
+ emptyMsgSelector = spaceghost.historypanel.data.selectors.history.emptyMsg,
+ emptyMsgStr = spaceghost.historypanel.data.text.history.emptyMsg;
- unnamedName = spaceghost.historypanel.data.text.history.newName,
- nameSelector = spaceghost.historypanel.data.selectors.history.name,
- sizeSelector = spaceghost.historypanel.data.selectors.history.size,
- initialSizeStr = spaceghost.historypanel.data.text.history.newSize,
- tagIconSelector = spaceghost.historypanel.data.selectors.history.tagIcon,
- annoIconSelector = spaceghost.historypanel.data.selectors.history.annoIcon,
- emptyMsgSelector = spaceghost.historypanel.data.selectors.history.emptyMsg,
- emptyMsgStr = spaceghost.historypanel.data.text.history.emptyMsg,
- anonNameTooltip = spaceghost.historypanel.data.text.anonymous.tooltips.name;
+ var filenameToUpload = '1.txt',
+ filepathToUpload = '../../test-data/' + filenameToUpload;
-var historyFrameInfo = {},
- filenameToUpload = '1.txt',
- filepathToUpload = '../../test-data/' + filenameToUpload,
- testUploadInfo = {};
+ // ------------------------------------------------------------------- check the anonymous new, history for form
+ spaceghost.openHomePage().historypanel.waitForHdas( function testPanelStructure(){
+ this.test.comment( 'history panel for anonymous user, new history' );
-// =================================================================== TESTS
-// ------------------------------------------------------------------- check the anonymous new, history for form
-spaceghost.openHomePage().historypanel.waitForHdas( function testPanelStructure(){
- this.test.comment( 'history panel for anonymous user, new history' );
+ this.test.comment( "history name should exist, be visible, and have text " + unnamedName );
+ this.test.assertExists( nameSelector, nameSelector + ' exists' );
+ this.test.assertVisible( nameSelector, 'History name is visible' );
+ this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
- this.test.comment( "history name should exist, be visible, and have text " + unnamedName );
- this.test.assertExists( nameSelector, nameSelector + ' exists' );
- this.test.assertVisible( nameSelector, 'History name is visible' );
- this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
+ this.test.comment( "history should display size and size should be 0 bytes" );
+ this.test.assertExists( sizeSelector, 'Found ' + sizeSelector );
+ this.test.assertVisible( sizeSelector, 'History size is visible' );
+ this.test.assertSelectorHasText( sizeSelector, initialSizeStr,
+ 'History size has "' + initialSizeStr + '"' );
- this.test.comment( "history should display size and size should be 0 bytes" );
- this.test.assertExists( sizeSelector, 'Found ' + sizeSelector );
- this.test.assertVisible( sizeSelector, 'History size is visible' );
- this.test.assertSelectorHasText( sizeSelector, initialSizeStr,
- 'History size has "' + initialSizeStr + '"' );
+ this.test.comment( "NO tags or annotations icons should be available for an anonymous user" );
+ this.test.assertDoesntExist( tagIconSelector, 'Tag icon button not found' );
+ this.test.assertDoesntExist( annoIconSelector, 'Annotation icon button not found' );
- this.test.comment( "NO tags or annotations icons should be available for an anonymous user" );
- this.test.assertDoesntExist( tagIconSelector, 'Tag icon button not found' );
- this.test.assertDoesntExist( annoIconSelector, 'Annotation icon button not found' );
+ this.test.assertExists( emptyMsgSelector, emptyMsgSelector + ' exists' );
+ this.test.comment( "A message about the current history being empty should be displayed" );
+ this.test.assertVisible( emptyMsgSelector, 'Empty history message is visible' );
+ this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
+ 'Message contains "' + emptyMsgStr + '"' );
- this.test.assertExists( emptyMsgSelector, emptyMsgSelector + ' exists' );
- this.test.comment( "A message about the current history being empty should be displayed" );
- this.test.assertVisible( emptyMsgSelector, 'Empty history message is visible' );
- this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
- 'Message contains "' + emptyMsgStr + '"' );
-
- this.test.comment( 'name should NOT be editable when clicked by anon-user' );
- this.assertDoesntHaveClass( nameSelector, editableTextClass, "Name field is not classed as editable text" );
- this.click( nameSelector );
- this.test.assertDoesntExist( editableTextInput, "Clicking on name does not create an input" );
-});
-
-// ------------------------------------------------------------------- anon user can upload file
-spaceghost.then( function testAnonUpload(){
- this.test.comment( 'anon-user should be able to upload files' );
-
- spaceghost.tools.uploadFile( filepathToUpload, function uploadCallback( _uploadInfo ){
- this.debug( 'uploaded HDA info: ' + this.jsonStr( this.quickInfo( _uploadInfo.hdaElement ) ) );
- var hasHda = _uploadInfo.hdaElement,
- hasClass = _uploadInfo.hdaElement.attributes[ 'class' ],
- hasOkClass = _uploadInfo.hdaElement.attributes[ 'class' ].indexOf( 'state-ok' ) !== -1;
- this.test.assert( ( hasHda && hasClass && hasOkClass ), "Uploaded file: " + _uploadInfo.hdaElement.text );
- testUploadInfo = _uploadInfo;
+ this.test.comment( 'name should NOT be editable when clicked by anon-user' );
+ this.assertDoesntHaveClass( nameSelector, editableTextClass, "Name field is not classed as editable text" );
+ this.click( nameSelector );
+ this.test.assertDoesntExist( editableTextInput, "Clicking on name does not create an input" );
});
-});
-spaceghost.then( function testAnonUpload(){
- this.test.comment( "empty should be NO LONGER be displayed" );
- this.test.assertNotVisible( emptyMsgSelector, 'Empty history message is not visible' );
-});
+ // ------------------------------------------------------------------- anon user can upload file
+ var uploadedId = null;
+ spaceghost.api.tools.thenUploadToCurrent({ filepath: filepathToUpload }, function( id, json ){
+ uploadedId = id;
+ });
+ spaceghost.openHomePage().historypanel.waitForHdas( function testAnonUpload(){
+ this.test.comment( 'anon-user should be able to upload files' );
+ this.test.assertExists( '#dataset-' + uploadedId, "found hda" );
+ var hdaElement = this.elementInfoOrNull( '#dataset-' + uploadedId );
+ this.debug( 'hdaElement: ' + hdaElement );
+ if( hdaElement ){
+ this.test.assert( hdaElement.attributes[ 'class' ].indexOf( 'state-ok' ) !== -1,
+ "Uploaded file: " + hdaElement.text );
+ }
-// ------------------------------------------------------------------- anon user can run tool on file
+ this.test.comment( "empty should be NO LONGER be displayed" );
+ this.test.assertNotVisible( emptyMsgSelector, 'Empty history message is not visible' );
+ });
-// ------------------------------------------------------------------- anon user registers/logs in -> same history
-spaceghost.user.loginOrRegisterUser( email, password ).openHomePage( function(){
- this.test.comment( 'anon-user should login and be associated with previous history' );
+ // ------------------------------------------------------------------- anon user can run tool on file
- var loggedInAs = spaceghost.user.loggedInAs();
- this.test.assert( loggedInAs === email, 'loggedInAs() matches email: "' + loggedInAs + '"' );
+ // ------------------------------------------------------------------- anon user registers/logs in -> same history
+ spaceghost.user.loginOrRegisterUser( email, password ).openHomePage( function(){
+ this.test.comment( 'anon-user should login and be associated with previous history' );
- this.historypanel.waitForHdas( function(){
- var hdaInfo = this.historypanel.hdaElementInfoByTitle( filenameToUpload );
- this.test.assert( hdaInfo !== null, "After logging in - found a matching hda by name and hid" );
- if( hdaInfo ){
- this.test.assert( testUploadInfo.hdaElement.attributes.id === hdaInfo.attributes.id,
- "After logging in - found a matching hda by hda view id: " + hdaInfo.attributes.id );
- }
+ var loggedInAs = spaceghost.user.loggedInAs();
+ this.test.assert( loggedInAs === email, 'loggedInAs() matches email: "' + loggedInAs + '"' );
+
+ this.historypanel.waitForHdas( function(){
+ var hdaInfo = this.historypanel.hdaElementInfoByTitle( filenameToUpload );
+ this.test.assert( hdaInfo !== null, "After logging in - found a matching hda by name and hid" );
+ if( hdaInfo ){
+ this.test.assert( 'dataset-' + uploadedId === hdaInfo.attributes.id,
+ "After logging in - found a matching hda by hda view id: " + hdaInfo.attributes.id );
+ }
+ });
});
-});
-// ------------------------------------------------------------------- logs out -> new history
-spaceghost.user.logout().openHomePage( function(){
- this.test.comment( 'logging out should create a new, anonymous history' );
+ // ------------------------------------------------------------------- logs out -> new history
+ spaceghost.user.logout().openHomePage( function(){
+ this.test.comment( 'logging out should create a new, anonymous history' );
- this.historypanel.waitForHdas( function(){
- this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
- this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
- 'Message contains "' + emptyMsgStr + '"' );
+ this.historypanel.waitForHdas( function(){
+ this.test.assertSelectorHasText( nameSelector, unnamedName, 'History name is ' + unnamedName );
+ this.test.assertSelectorHasText( emptyMsgSelector, emptyMsgStr,
+ 'Message contains "' + emptyMsgStr + '"' );
+ });
});
-});
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b test/casperjs/api-anon-history-permission-tests.js
--- a/test/casperjs/api-anon-history-permission-tests.js
+++ b/test/casperjs/api-anon-history-permission-tests.js
@@ -8,195 +8,194 @@
+ 'with anonymous users over the API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-var inaccessibleHistory, accessibleHistory, publishedHistory,
- inaccessibleHdas, accessibleHdas, publishedHdas,
- accessibleLink;
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ var inaccessibleHistory, accessibleHistory, publishedHistory,
+ inaccessibleHdas, accessibleHdas, publishedHdas;
-//// ------------------------------------------------------------------------------------------- create 3 histories
-spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- // create three histories: make the 2nd importable (via the API), and the third published
+ //// ------------------------------------------------------------------------------------------- create 3 histories
+ spaceghost.user.loginOrRegisterUser( email, password );
+ spaceghost.openHomePage().then( function(){
+ // create three histories: make the 2nd importable (via the API), and the third published
- // make the current the inaccessible one
- inaccessibleHistory = this.api.histories.index()[0];
- this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
- inaccessibleHistory = this.api.histories.index()[0];
+ // make the current the inaccessible one
+ inaccessibleHistory = this.api.histories.index()[0];
+ this.api.histories.update( inaccessibleHistory.id, { name: 'inaccessible' });
+ inaccessibleHistory = this.api.histories.index()[0];
- accessibleHistory = this.api.histories.create({ name: 'accessible' });
- var returned = this.api.histories.update( accessibleHistory.id, {
- importable : true
+ accessibleHistory = this.api.histories.create({ name: 'accessible' });
+ var returned = this.api.histories.update( accessibleHistory.id, {
+ importable : true
+ });
+ //this.debug( this.jsonStr( returned ) );
+ accessibleHistory = this.api.histories.show( accessibleHistory.id );
+
+ publishedHistory = this.api.histories.create({ name: 'published' });
+ returned = this.api.histories.update( publishedHistory.id, {
+ published : true
+ });
+ //this.debug( this.jsonStr( returned ) );
+ publishedHistory = this.api.histories.show( publishedHistory.id );
+
});
- //this.debug( this.jsonStr( returned ) );
- accessibleHistory = this.api.histories.show( accessibleHistory.id );
- publishedHistory = this.api.histories.create({ name: 'published' });
- returned = this.api.histories.update( publishedHistory.id, {
- published : true
+ //// ------------------------------------------------------------------------------------------- upload some files
+ spaceghost.then( function(){
+ this.api.tools.thenUpload( inaccessibleHistory.id, { filepath: '../../test-data/1.bed' });
+ this.api.tools.thenUpload( accessibleHistory.id, { filepath: '../../test-data/1.bed' });
+ this.api.tools.thenUpload( publishedHistory.id, { filepath: '../../test-data/1.bed' });
});
- //this.debug( this.jsonStr( returned ) );
- publishedHistory = this.api.histories.show( publishedHistory.id );
+ spaceghost.then( function(){
+ // check that they're there
+ inaccessibleHdas = this.api.hdas.index( inaccessibleHistory.id ),
+ accessibleHdas = this.api.hdas.index( accessibleHistory.id ),
+ publishedHdas = this.api.hdas.index( publishedHistory.id );
+ });
+ spaceghost.user.logout();
-});
+ // =================================================================== TESTS
+ //// ------------------------------------------------------------------------------------------- anon user
+ function testAnonReadFunctionsOnAccessible( history, hdas ){
+ this.test.comment( '---- testing read/accessibility functions for ACCESSIBLE history: ' + history.name );
-//// ------------------------------------------------------------------------------------------- upload some files
-spaceghost.then( function(){
- this.api.tools.thenUpload( inaccessibleHistory.id, { filepath: '../../test-data/1.bed' });
- this.api.tools.thenUpload( accessibleHistory.id, { filepath: '../../test-data/1.bed' });
- this.api.tools.thenUpload( publishedHistory.id, { filepath: '../../test-data/1.bed' });
-});
-spaceghost.then( function(){
- // check that they're there
- inaccessibleHdas = this.api.hdas.index( inaccessibleHistory.id ),
- accessibleHdas = this.api.hdas.index( accessibleHistory.id ),
- publishedHdas = this.api.hdas.index( publishedHistory.id );
-});
-spaceghost.user.logout();
+ // read functions for history
+ this.test.comment( 'show should work for history: ' + history.name );
+ this.test.assert( this.api.histories.show( history.id ).id === history.id,
+ 'show worked' );
+ this.test.comment( 'copying should fail for history (multiple histories not allowed): ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ history_id : history.id });
+ }, 403, 'API authentication required for this request', 'update authentication required' );
-// =================================================================== TESTS
-//// ------------------------------------------------------------------------------------------- anon user
-function testAnonReadFunctionsOnAccessible( history, hdas ){
- this.test.comment( '---- testing read/accessibility functions for ACCESSIBLE history: ' + history.name );
+ // read functions for history contents
+ this.test.comment( 'index of history contents should work for history: ' + history.name );
+ this.test.assert( this.api.hdas.index( history.id ).length === 1,
+ 'hda index worked' );
+ this.test.comment( 'showing of history contents should work for history: ' + history.name );
+ this.test.assert( this.api.hdas.show( history.id, hdas[0].id ).id === hdas[0].id,
+ 'hda show worked' );
- // read functions for history
- this.test.comment( 'show should work for history: ' + history.name );
- this.test.assert( this.api.histories.show( history.id ).id === history.id,
- 'show worked' );
- this.test.comment( 'copying should fail for history (multiple histories not allowed): ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.create({ history_id : history.id });
- }, 403, 'API authentication required for this request', 'update authentication required' );
-
- // read functions for history contents
- this.test.comment( 'index of history contents should work for history: ' + history.name );
- this.test.assert( this.api.hdas.index( history.id ).length === 1,
- 'hda index worked' );
- this.test.comment( 'showing of history contents should work for history: ' + history.name );
- this.test.assert( this.api.hdas.show( history.id, hdas[0].id ).id === hdas[0].id,
- 'hda show worked' );
-
- this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
- + ' should work from accessible history: ' + history.name );
- this.api.hdas.create( this.api.histories.index()[0].id, {
- source : 'hda',
- content : hdas[0].id
- });
-}
-
-function testAnonReadFunctionsOnInaccessible( history, hdas ){
- this.test.comment( '---- testing read/accessibility functions for INACCESSIBLE history: ' + history.name );
-
- // read functions for history
- this.test.comment( 'show should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.show( history.id );
- }, 403, 'History is not accessible to the current user', 'show failed with error' );
- this.test.comment( 'copying should fail for history (implicit multiple histories): ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.create({ history_id : history.id });
- }, 403, 'API authentication required for this request', 'copy failed with error' );
-
- // read functions for history contents
- this.test.comment( 'index and show of history contents should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.index( history.id );
- }, 403, 'History is not accessible to the current user', 'hda index failed with error' );
- this.api.assertRaises( function(){
- this.api.hdas.show( history.id, hdas[0].id );
- }, 403, 'History is not accessible to the current user', 'hda show failed with error' );
-
- this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
- + ' from an inaccessible history should fail for: ' + history.name );
- this.api.assertRaises( function(){
- var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
+ this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ + ' should work from accessible history: ' + history.name );
+ this.api.hdas.create( this.api.histories.index()[0].id, {
source : 'hda',
content : hdas[0].id
});
- this.debug( this.jsonStr( returned ) );
- }, 403, 'History is not accessible to the current user', 'hda copy from failed with error' );
+ }
-}
+ function testAnonReadFunctionsOnInaccessible( history, hdas ){
+ this.test.comment( '---- testing read/accessibility functions for INACCESSIBLE history: ' + history.name );
-function testAnonWriteFunctions( history, hdas ){
- this.test.comment( '---- testing write/ownership functions for history: ' + history.name );
+ // read functions for history
+ this.test.comment( 'show should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.show( history.id );
+ }, 403, 'History is not accessible to the current user', 'show failed with error' );
+ this.test.comment( 'copying should fail for history (implicit multiple histories): ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ history_id : history.id });
+ }, 403, 'API authentication required for this request', 'copy failed with error' );
- this.test.comment( 'update should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.update( history.id, { deleted: true });
- }, 403, 'API authentication required for this request', 'update authentication required' );
- this.test.comment( 'delete should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.histories.delete_( history.id );
- }, 403, 'API authentication required for this request', 'delete authentication required' );
+ // read functions for history contents
+ this.test.comment( 'index and show of history contents should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.index( history.id );
+ }, 403, 'History is not accessible to the current user', 'hda index failed with error' );
+ this.api.assertRaises( function(){
+ this.api.hdas.show( history.id, hdas[0].id );
+ }, 403, 'History is not accessible to the current user', 'hda show failed with error' );
- this.test.comment( 'hda updating should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.update( history.id, hdas[0].id, { deleted: true });
- // anon hda update fails w/ this msg if trying to update non-current history hda
- }, 403, 'You must be logged in to update this history', 'hda update failed with error' );
- this.test.comment( 'hda deletion should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( history.id, hdas[0].id );
- }, 403, 'API authentication required for this request', 'hda delete failed with error' );
+ this.test.comment( 'Attempting to copy an accessible hda (default is accessible)'
+ + ' from an inaccessible history should fail for: ' + history.name );
+ this.api.assertRaises( function(){
+ var returned = this.api.hdas.create( this.api.histories.index()[0].id, {
+ source : 'hda',
+ content : hdas[0].id
+ });
+ this.debug( this.jsonStr( returned ) );
+ }, 403, 'History is not accessible to the current user', 'hda copy from failed with error' );
- this.test.comment( 'copying hda into history should fail for history: ' + history.name );
- this.api.assertRaises( function(){
- this.api.hdas.create( history.id, {
- source : 'hda',
- // should error before it checks the id
- content : 'bler'
+ }
+
+ function testAnonWriteFunctions( history, hdas ){
+ this.test.comment( '---- testing write/ownership functions for history: ' + history.name );
+
+ this.test.comment( 'update should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.update( history.id, { deleted: true });
+ }, 403, 'API authentication required for this request', 'update authentication required' );
+ this.test.comment( 'delete should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.histories.delete_( history.id );
+ }, 403, 'API authentication required for this request', 'delete authentication required' );
+
+ this.test.comment( 'hda updating should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.update( history.id, hdas[0].id, { deleted: true });
+ // anon hda update fails w/ this msg if trying to update non-current history hda
+ }, 403, 'You must be logged in to update this history', 'hda update failed with error' );
+ this.test.comment( 'hda deletion should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( history.id, hdas[0].id );
+ }, 403, 'API authentication required for this request', 'hda delete failed with error' );
+
+ this.test.comment( 'copying hda into history should fail for history: ' + history.name );
+ this.api.assertRaises( function(){
+ this.api.hdas.create( history.id, {
+ source : 'hda',
+ // should error before it checks the id
+ content : 'bler'
+ });
+ }, 403, 'Must be logged in to manage Galaxy histories', 'hda copy to failed' );
+ }
+
+ function testAnonInaccessible( history, hdas ){
+ testAnonReadFunctionsOnInaccessible.call( this, history, hdas );
+ testAnonWriteFunctions.call( this, history, hdas );
+ }
+
+ function testAnonAccessible( history, hdas ){
+ testAnonReadFunctionsOnAccessible.call( this, history, hdas );
+ testAnonWriteFunctions.call( this, history, hdas );
+ }
+
+ spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
+ testAnonInaccessible.call( spaceghost, inaccessibleHistory, inaccessibleHdas );
+ testAnonAccessible.call( spaceghost, accessibleHistory, accessibleHdas );
+ testAnonAccessible.call( spaceghost, publishedHistory, publishedHdas );
+ });
+
+
+ // ------------------------------------------------------------------------------------------- user1 revoke perms
+ spaceghost.user.loginOrRegisterUser( email, password );
+ spaceghost.openHomePage().then( function(){
+ this.test.comment( 'revoking perms should prevent access' );
+ this.api.histories.update( accessibleHistory.id, {
+ importable : false
});
- }, 403, 'Must be logged in to manage Galaxy histories', 'hda copy to failed' );
-}
+ var returned = this.api.histories.show( accessibleHistory.id );
-function testAnonInaccessible( history, hdas ){
- testAnonReadFunctionsOnInaccessible.call( this, history, hdas );
- testAnonWriteFunctions.call( this, history, hdas );
-}
+ this.api.histories.update( publishedHistory.id, {
+ importable : false,
+ published : false
+ });
+ returned = this.api.histories.show( publishedHistory.id );
+ });
+ spaceghost.user.logout();
-function testAnonAccessible( history, hdas ){
- testAnonReadFunctionsOnAccessible.call( this, history, hdas );
- testAnonWriteFunctions.call( this, history, hdas );
-}
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- testAnonInaccessible.call( spaceghost, inaccessibleHistory, inaccessibleHdas );
- testAnonAccessible.call( spaceghost, accessibleHistory, accessibleHdas );
- testAnonAccessible.call( spaceghost, publishedHistory, publishedHdas );
-});
+ // ------------------------------------------------------------------------------------------- anon retry perms
+ spaceghost.openHomePage().then( function(){
+ testAnonInaccessible.call( spaceghost, accessibleHistory, accessibleHdas );
+ testAnonInaccessible.call( spaceghost, publishedHistory, publishedHdas );
+ });
-// ------------------------------------------------------------------------------------------- user1 revoke perms
-spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- this.test.comment( 'revoking perms should prevent access' );
- this.api.histories.update( accessibleHistory.id, {
- importable : false
- });
- var returned = this.api.histories.show( accessibleHistory.id );
-
- this.api.histories.update( publishedHistory.id, {
- importable : false,
- published : false
- });
- returned = this.api.histories.show( publishedHistory.id );
-});
-spaceghost.user.logout();
-
-
-// ------------------------------------------------------------------------------------------- anon retry perms
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- testAnonInaccessible.call( spaceghost, accessibleHistory, accessibleHdas );
- testAnonInaccessible.call( spaceghost, publishedHistory, publishedHdas );
-});
-
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b test/casperjs/api-anon-history-tests.js
--- a/test/casperjs/api-anon-history-tests.js
+++ b/test/casperjs/api-anon-history-tests.js
@@ -7,123 +7,116 @@
spaceghost.test.begin( 'Test API functions for histories with an anonymous user', 0, function suite( test ){
spaceghost.start();
-// =================================================================== TESTS
-spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
-spaceghost.then( function(){
+ // =================================================================== TESTS
+ spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
+ spaceghost.then( function(){
- // ------------------------------------------------------------------------------------------- anon allowed
- this.test.comment( 'index should get a list of histories' );
- var index = this.api.histories.index();
- this.test.assert( utils.isArray( index ), "index returned an array: length " + index.length );
- this.test.assert( index.length === 1, 'Has at least one history' );
+ // ------------------------------------------------------------------------------------------- anon allowed
+ this.test.comment( 'index should get a list of histories' );
+ var index = this.api.histories.index();
+ this.test.assert( utils.isArray( index ), "index returned an array: length " + index.length );
+ this.test.assert( index.length === 1, 'Has at least one history' );
- this.test.comment( 'show should get a history details object' );
- var historyShow = this.api.histories.show( index[0].id );
- //this.debug( this.jsonStr( historyShow ) );
- this.test.assert( historyShow.id === index[0].id, 'Is the first history' );
- this.test.assert( this.hasKeys( historyShow, [ 'id', 'name', 'user_id' ] ) );
+ this.test.comment( 'show should get a history details object' );
+ var historyShow = this.api.histories.show( index[0].id );
+ //this.debug( this.jsonStr( historyShow ) );
+ this.test.assert( historyShow.id === index[0].id, 'Is the first history' );
+ this.test.assert( this.hasKeys( historyShow, [ 'id', 'name', 'user_id' ] ) );
- // ------------------------------------------------------------------------------------------- anon forbidden
- //TODO: why not return the current history?
- this.test.comment( 'calling show with "most_recently_used" should return None for an anon user' );
- var recent = this.api.histories.show( 'most_recently_used' );
- this.test.assert( recent === null, 'most_recently_used returned None' );
+ // ------------------------------------------------------------------------------------------- anon forbidden
+ //TODO: why not return the current history?
+ this.test.comment( 'calling show with "most_recently_used" should return None for an anon user' );
+ var recent = this.api.histories.show( 'most_recently_used' );
+ this.test.assert( recent === null, 'most_recently_used returned None' );
- this.test.comment( 'Calling create should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.create({ name: 'new' });
- }, 403, 'API authentication required for this request', 'create failed with error' );
+ this.test.comment( 'Calling create should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.create({ name: 'new' });
+ }, 403, 'API authentication required for this request', 'create failed with error' );
- this.test.comment( 'Calling delete should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.delete_( historyShow.id );
- }, 403, 'API authentication required for this request', 'create failed with error' );
+ this.test.comment( 'Calling delete should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.delete_( historyShow.id );
+ }, 403, 'API authentication required for this request', 'create failed with error' );
- this.test.comment( 'Calling update should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.histories.update( historyShow.id, {} );
- }, 403, 'API authentication required for this request', 'update failed with error' );
+ this.test.comment( 'Calling update should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.histories.update( historyShow.id, {} );
+ }, 403, 'API authentication required for this request', 'update failed with error' );
- //TODO: need these two in api.js
- //this.test.comment( 'Calling archive_import should fail for an anonymous user' );
- //this.api.assertRaises( function(){
- // this.api.histories.archive_import( historyShow.id, {} );
- //}, 403, 'API authentication required for this request', 'archive_import failed with error' );
+ //TODO: need these two in api.js
+ //this.test.comment( 'Calling archive_import should fail for an anonymous user' );
+ //this.api.assertRaises( function(){
+ // this.api.histories.archive_import( historyShow.id, {} );
+ //}, 403, 'API authentication required for this request', 'archive_import failed with error' );
- //this.test.comment( 'Calling archive_download should fail for an anonymous user' );
- //this.api.assertRaises( function(){
- // this.api.histories.archive_download( historyShow.id, {} );
- //}, 403, 'API authentication required for this request', 'archive_download failed with error' );
+ //this.test.comment( 'Calling archive_download should fail for an anonymous user' );
+ //this.api.assertRaises( function(){
+ // this.api.histories.archive_download( historyShow.id, {} );
+ //}, 403, 'API authentication required for this request', 'archive_download failed with error' );
- // test server bad id protection
- spaceghost.test.comment( 'A bad id should throw an error' );
- this.api.assertRaises( function(){
- this.api.histories.show( '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
+ // test server bad id protection
+ spaceghost.test.comment( 'A bad id should throw an error' );
+ this.api.assertRaises( function(){
+ this.api.histories.show( '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
-});
+ });
-// ------------------------------------------------------------------------------------------- hdas
-spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
-spaceghost.then( function(){
- spaceghost.tools.uploadFile( '../../test-data/1.sam', function( uploadInfo ){
- this.test.assert( uploadInfo.hdaElement !== null, "Convenience function produced hda" );
- var state = this.historypanel.getHdaState( '#' + uploadInfo.hdaElement.attributes.id );
- this.test.assert( state === 'ok', "Convenience function produced hda in ok state" );
+ // ------------------------------------------------------------------------------------------- hdas
+ spaceghost.thenOpen( spaceghost.baseUrl ).waitForSelector( spaceghost.historypanel.data.selectors.history.name );
+ spaceghost.api.tools.thenUploadToCurrent({ filepath: '../../test-data/1.sam' });
+ spaceghost.then( function(){
+ var current = this.api.histories.index()[0];
+
+ // ------------------------------------------------------------------------------------------- anon allowed
+ this.test.comment( 'anonymous users can index hdas in their current history' );
+ var hdaIndex = this.api.hdas.index( current.id );
+ this.test.assert( hdaIndex.length === 1, 'indexed hdas' );
+
+ this.test.comment( 'anonymous users can show hdas in their current history' );
+ var hda = this.api.hdas.show( current.id, hdaIndex[0].id );
+ this.test.assert( this.hasKeys( hda, [ 'id', 'name' ] ), 'showed hda: ' + hda.name );
+
+ this.test.comment( 'anonymous users can hide hdas in their current history' );
+ var changed = this.api.hdas.update( current.id, hda.id, { visible: false });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.visible === false, 'successfully hidden' );
+
+ this.test.comment( 'anonymous users can mark their hdas as deleted in their current history' );
+ changed = this.api.hdas.update( current.id, hda.id, { deleted: true });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.deleted, 'successfully deleted' );
+
+ // ------------------------------------------------------------------------------------------- anon forbidden
+ this.test.comment( 'Creating an hda should work for an anonymous user' );
+ var returned = this.api.hdas.create( current.id, { source: 'hda', content: hda.id });
+ //this.debug( this.jsonStr( returned ) );
+ this.test.assert( returned.name === hda.name, 'name matches: ' + returned.name );
+ this.test.assert( returned.id !== hda.id, 'new id: ' + returned.id );
+
+ //TODO: should be allowed
+ this.test.comment( 'Calling hda delete should fail for an anonymous user' );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( current.id, hda.id );
+ }, 403, 'API authentication required for this request', 'delete failed with error' );
+
+ //TODO: only sharing, tags, annotations should be blocked/prevented
+ this.test.comment( 'Calling update with keys other than "visible" or "deleted" should fail silently' );
+ this.test.comment( 'Calling update on tags should fail silently' );
+ changed = this.api.hdas.update( current.id, hda.id, { tags: [ 'one' ] });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( hda.tags.length === 0, 'tags were not set: ' + this.jsonStr( hda.tags ) );
+
+ this.test.comment( 'Calling update on annotation should fail silently' );
+ changed = this.api.hdas.update( current.id, hda.id, { annotation: 'yup yup yup' });
+ hda = this.api.hdas.show( current.id, hda.id );
+ this.test.assert( !hda.annotation, 'annotation was not set: ' + hda.annotation );
+
});
-});
-spaceghost.then( function(){
- var current = this.api.histories.index()[0];
-
- // ------------------------------------------------------------------------------------------- anon allowed
- this.test.comment( 'anonymous users can index hdas in their current history' );
- var hdaIndex = this.api.hdas.index( current.id );
- this.test.assert( hdaIndex.length === 1, 'indexed hdas' );
-
- this.test.comment( 'anonymous users can show hdas in their current history' );
- var hda = this.api.hdas.show( current.id, hdaIndex[0].id );
- this.test.assert( this.hasKeys( hda, [ 'id', 'name' ] ), 'showed hda: ' + hda.name );
-
- this.test.comment( 'anonymous users can hide hdas in their current history' );
- var changed = this.api.hdas.update( current.id, hda.id, { visible: false });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.visible === false, 'successfully hidden' );
-
- this.test.comment( 'anonymous users can mark their hdas as deleted in their current history' );
- changed = this.api.hdas.update( current.id, hda.id, { deleted: true });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.deleted, 'successfully deleted' );
-
- // ------------------------------------------------------------------------------------------- anon forbidden
- this.test.comment( 'Creating an hda should work for an anonymous user' );
- var returned = this.api.hdas.create( current.id, { source: 'hda', content: hda.id });
- //this.debug( this.jsonStr( returned ) );
- this.test.assert( returned.name === hda.name, 'name matches: ' + returned.name );
- this.test.assert( returned.id !== hda.id, 'new id: ' + returned.id );
-
- //TODO: should be allowed
- this.test.comment( 'Calling hda delete should fail for an anonymous user' );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( current.id, hda.id );
- }, 403, 'API authentication required for this request', 'delete failed with error' );
-
- //TODO: only sharing, tags, annotations should be blocked/prevented
- this.test.comment( 'Calling update with keys other than "visible" or "deleted" should fail silently' );
- this.test.comment( 'Calling update on tags should fail silently' );
- changed = this.api.hdas.update( current.id, hda.id, { tags: [ 'one' ] });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( hda.tags.length === 0, 'tags were not set: ' + this.jsonStr( hda.tags ) );
-
- this.test.comment( 'Calling update on annotation should fail silently' );
- changed = this.api.hdas.update( current.id, hda.id, { annotation: 'yup yup yup' });
- hda = this.api.hdas.show( current.id, hda.id );
- this.test.assert( !hda.annotation, 'annotation was not set: ' + hda.annotation );
-
-});
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b test/casperjs/api-configuration-tests.js
--- a/test/casperjs/api-configuration-tests.js
+++ b/test/casperjs/api-configuration-tests.js
@@ -7,57 +7,55 @@
spaceghost.test.begin( 'Test the Galaxy configuration API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-spaceghost.user.loginOrRegisterUser( email, password );
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ spaceghost.user.loginOrRegisterUser( email, password );
-// =================================================================== TESTS
-var normKeys = [
- 'enable_unique_workflow_defaults',
- 'ftp_upload_site',
- 'ftp_upload_dir',
- 'wiki_url',
- 'support_url',
- 'logo_url',
- 'terms_url',
- 'allow_user_dataset_purge'
- ],
- adminKeys = normKeys.concat([
- 'library_import_dir',
- 'user_library_import_dir',
- 'allow_library_path_paste',
- 'allow_user_creation',
- 'allow_user_deletion'
- ]);
+ // =================================================================== TESTS
+ var normKeys = [
+ 'enable_unique_workflow_defaults',
+ 'ftp_upload_site',
+ 'ftp_upload_dir',
+ 'wiki_url',
+ 'support_url',
+ 'logo_url',
+ 'terms_url',
+ 'allow_user_dataset_purge'
+ ],
+ adminKeys = normKeys.concat([
+ 'library_import_dir',
+ 'user_library_import_dir',
+ 'allow_library_path_paste',
+ 'allow_user_creation',
+ 'allow_user_deletion'
+ ]);
+ // ------------------------------------------------------------------------------------------- INDEX
+ spaceghost.openHomePage().then( function(){
+ this.test.comment( 'index should get a (shortened) list of configuration settings '
+ + 'when requested by a normal user' );
-// ------------------------------------------------------------------------------------------- INDEX
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
+ var configIndex = this.api.configuration.index();
+ this.debug( this.jsonStr( configIndex ) );
+ this.test.assert( utils.isObject( configIndex ), "index returned an object" );
+ this.test.assert( this.hasKeys( configIndex, normKeys ), 'Has the proper keys' );
- this.test.comment( 'index should get a (shortened) list of configuration settings '
- + 'when requested by a normal user' );
- var configIndex = this.api.configuration.index();
- this.debug( this.jsonStr( configIndex ) );
- this.test.assert( utils.isObject( configIndex ), "index returned an object" );
- this.test.assert( this.hasKeys( configIndex, normKeys ), 'Has the proper keys' );
+ });
+ spaceghost.user.logout();
-});
-spaceghost.user.logout();
+ // ------------------------------------------------------------------------------------------- INDEX (admin)
+ spaceghost.tryStepsCatch( function tryAdminLogin(){
+ spaceghost.user.loginAdmin();
+ }, function(){} );
-// ------------------------------------------------------------------------------------------- INDEX (admin)
-spaceghost.tryStepsCatch( function tryAdminLogin(){
- spaceghost.user.loginAdmin();
-}, function(){} );
-
-//}, function failedLoginRegister(){
-// this.info( 'Admin level configuration API tests not run: no admin account available' );
-spaceghost.thenOpen( spaceghost.baseUrl ).then( function(){
- spaceghost.waitForMasthead( function() {
+ //}, function failedLoginRegister(){
+ // this.info( 'Admin level configuration API tests not run: no admin account available' );
+ spaceghost.openHomePage().waitForMasthead( function(){
if( spaceghost.user.userIsAdmin() ){
this.test.comment( 'index should get a (full) list of configuration settings '
+ 'when requested by an admin user' );
@@ -70,9 +68,8 @@
this.info( 'Admin level configuration API tests not run: no admin account available' );
}
});
-});
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
diff -r 05604a5d31c1b150d4a04347e68c0f30f2d0a598 -r 501f510ff101849c45d9b0925bb55fe59319088b test/casperjs/api-hda-tests.js
--- a/test/casperjs/api-hda-tests.js
+++ b/test/casperjs/api-hda-tests.js
@@ -7,363 +7,359 @@
spaceghost.test.begin( 'Test the HDA API', 0, function suite( test ){
spaceghost.start();
-// =================================================================== SET UP
-var email = spaceghost.user.getRandomEmail(),
- password = '123456';
-if( spaceghost.fixtureData.testUser ){
- email = spaceghost.fixtureData.testUser.email;
- password = spaceghost.fixtureData.testUser.password;
-}
-spaceghost.user.loginOrRegisterUser( email, password );
+ // =================================================================== SET UP
+ var email = spaceghost.user.getRandomEmail(),
+ password = '123456';
+ if( spaceghost.fixtureData.testUser ){
+ email = spaceghost.fixtureData.testUser.email;
+ password = spaceghost.fixtureData.testUser.password;
+ }
+ spaceghost.user.loginOrRegisterUser( email, password );
-spaceghost.thenOpen( spaceghost.baseUrl, function(){
- this.test.comment( '(logged in as ' + this.user.loggedInAs() + ')' );
- this.api.tools.thenUpload( spaceghost.api.histories.index()[0].id, {
+ spaceghost.openHomePage().api.tools.thenUploadToCurrent({
filepath: '../../test-data/1.sam'
});
-});
-// =================================================================== TESTS
-var summaryKeys = [ 'id', 'name', 'history_id', 'state', 'deleted', 'purged', 'visible', 'url', 'type' ],
- detailKeys = [
- // the following are always present regardless of datatype
- 'id', 'name', 'api_type', 'model_class',
- 'history_id', 'hid',
- 'accessible', 'deleted', 'visible', 'purged',
- 'state', 'data_type', 'file_ext', 'file_size',
- 'misc_info', 'misc_blurb',
- 'download_url', 'visualizations', 'display_apps', 'display_types',
- 'genome_build',
- // the following are NOT always present DEPENDING ON datatype
- 'metadata_dbkey',
- 'metadata_column_names', 'metadata_column_types', 'metadata_columns',
- 'metadata_comment_lines', 'metadata_data_lines'
- ];
+ // =================================================================== TESTS
+ var summaryKeys = [ 'id', 'name', 'history_id', 'state', 'deleted', 'purged', 'visible', 'url', 'type' ],
+ detailKeys = [
+ // the following are always present regardless of datatype
+ 'id', 'name', 'api_type', 'model_class',
+ 'history_id', 'hid',
+ 'accessible', 'deleted', 'visible', 'purged',
+ 'state', 'data_type', 'file_ext', 'file_size',
+ 'misc_info', 'misc_blurb',
+ 'download_url', 'visualizations', 'display_apps', 'display_types',
+ 'genome_build',
+ // the following are NOT always present DEPENDING ON datatype
+ 'metadata_dbkey',
+ 'metadata_column_names', 'metadata_column_types', 'metadata_columns',
+ 'metadata_comment_lines', 'metadata_data_lines'
+ ];
-// ------------------------------------------------------------------------------------------- logged in user
-spaceghost.then( function(){
-
- // ------------------------------------------------------------------------------------------- INDEX
- this.test.comment( 'index should return a list of summary data for each hda' );
- var histories = this.api.histories.index(),
- lastHistory = histories[0],
- hdaIndex = this.api.hdas.index( lastHistory.id );
- //this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
+ // ------------------------------------------------------------------------------------------- logged in user
+ spaceghost.then( function(){
+ // ------------------------------------------------------------------------------------------- INDEX
+ this.test.comment( 'index should return a list of summary data for each hda' );
+ var histories = this.api.histories.index(),
+ lastHistory = histories[0],
+ hdaIndex = this.api.hdas.index( lastHistory.id );
+ //this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
- this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
- this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
+ this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
+ this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
- var firstHda = hdaIndex[0];
- this.test.assert( this.hasKeys( firstHda, summaryKeys ), 'Has the proper keys' );
+ var firstHda = hdaIndex[0];
+ this.test.assert( this.hasKeys( firstHda, summaryKeys ), 'Has the proper keys' );
- this.test.assert( this.api.isEncodedId( firstHda.id ), 'Id appears well-formed: ' + firstHda.id );
- this.test.assert( firstHda.name === '1.sam', 'Title matches: ' + firstHda.name );
+ this.test.assert( this.api.isEncodedId( firstHda.id ), 'Id appears well-formed: ' + firstHda.id );
+ this.test.assert( firstHda.name === '1.sam', 'Title matches: ' + firstHda.name );
- // ------------------------------------------------------------------------------------------- SHOW
- this.test.comment( 'show should get an HDA details object' );
- var hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- //this.debug( this.jsonStr( hdaShow ) );
- this.test.assert( this.hasKeys( hdaShow, detailKeys ), 'Has the proper keys' );
+ // ------------------------------------------------------------------------------------------- SHOW
+ this.test.comment( 'show should get an HDA details object' );
+ var hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ //this.debug( this.jsonStr( hdaShow ) );
+ this.test.assert( this.hasKeys( hdaShow, detailKeys ), 'Has the proper keys' );
- //TODO: validate data in each hdaShow attribute...
+ //TODO: validate data in each hdaShow attribute...
- // ------------------------------------------------------------------------------------------- INDEX (detailed)
- this.test.comment( 'index should return a list of detailed data for each hda in "ids" when passed' );
- hdaIndex = this.api.hdas.index( lastHistory.id, [ firstHda.id ] );
- this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
+ // ------------------------------------------------------------------------------------------- INDEX (detailed)
+ this.test.comment( 'index should return a list of detailed data for each hda in "ids" when passed' );
+ hdaIndex = this.api.hdas.index( lastHistory.id, [ firstHda.id ] );
+ this.debug( 'hdaIndex:' + this.jsonStr( hdaIndex ) );
- this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
- this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
+ this.test.assert( utils.isArray( hdaIndex ), "index returned an array: length " + hdaIndex.length );
+ this.test.assert( hdaIndex.length >= 1, 'Has at least one hda' );
- firstHda = hdaIndex[0];
- this.test.assert( this.hasKeys( firstHda, detailKeys ), 'Has the proper keys' );
+ firstHda = hdaIndex[0];
+ this.test.assert( this.hasKeys( firstHda, detailKeys ), 'Has the proper keys' );
- //TODO??: validate data in firstHda attribute? we ASSUME it's from a common method as show...
+ //TODO??: validate data in firstHda attribute? we ASSUME it's from a common method as show...
- // ------------------------------------------------------------------------------------------- CREATE
- //TODO: create from_ld_id
- this.test.comment( 'create should allow copying an accessible hda' );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- var returned = this.api.hdas.create( lastHistory.id, {
- source : 'hda',
- content : hdaShow.id
+ // ------------------------------------------------------------------------------------------- CREATE
+ //TODO: create from_ld_id
+ this.test.comment( 'create should allow copying an accessible hda' );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ var returned = this.api.hdas.create( lastHistory.id, {
+ source : 'hda',
+ content : hdaShow.id
+ });
+ //this.debug( 'returned:' + this.jsonStr( returned ) );
+ this.test.assert( this.hasKeys( returned, detailKeys ), 'Has the proper keys' );
+ this.test.assert( typeof returned.id !== 'number' && isNaN( Number( returned.id ) ),
+ 'id seems to be encoded: ' + returned.id );
+ this.test.assert( typeof returned.history_id !== 'number' && isNaN( Number( returned.history_id ) ),
+ 'history_id seems to be encoded: ' + returned.history_id );
+
+
+ // ------------------------------------------------------------------------------------------- UPDATE
+ // ........................................................................................... idiot proofing
+ this.test.comment( 'updating to the current value should return no value (no change)' );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ var returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : hdaShow.name
+ });
+ this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
+
+ this.test.comment( 'updating using a nonsense key should NOT fail with an error' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ konamiCode : 'uuddlrlrba'
+ });
+ this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
+
+ this.test.comment( 'updating by attempting to change type should cause an error' );
+ this.api.assertRaises( function(){
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ //name : false
+ deleted : 'sure why not'
+ });
+ }, 400, 'deleted must be a boolean', 'changing deleted type failed' );
+
+ // ........................................................................................... name
+ this.test.comment( 'update should allow changing the name' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : 'New name'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === 'New name', "Name successfully set via update: " + hdaShow.name );
+
+ this.test.comment( 'update should sanitize any new name' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : 'New name<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === 'New name', "Update sanitized name: " + hdaShow.name );
+
+ this.test.comment( 'update should allow unicode in names' );
+ var unicodeName = 'Ржевский сапоги';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : unicodeName
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === unicodeName, "Update accepted unicode name: " + hdaShow.name );
+
+ this.test.comment( 'update should allow escaped quotations in names' );
+ var quotedName = '"Bler"';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ name : quotedName
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.name === quotedName,
+ "Update accepted escaped quotations in name: " + hdaShow.name );
+
+
+ // ........................................................................................... deleted
+ this.test.comment( 'update should allow changing the deleted flag' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ deleted: true
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id, true );
+ this.test.assert( hdaShow.deleted === true, "Update set the deleted flag: " + hdaShow.deleted );
+
+ this.test.comment( 'update should allow changing the deleted flag back' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ deleted: false
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.deleted === false, "Update set the deleted flag: " + hdaShow.deleted );
+
+
+ // ........................................................................................... visible/hidden
+ this.test.comment( 'update should allow changing the visible flag' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ visible: false
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.visible === false, "Update set the visible flag: " + hdaShow.visible );
+
+
+ // ........................................................................................... genome/dbkey
+ this.test.comment( 'update should allow changing the genome_build' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : 'hg18'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ //this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
+ this.test.assert( hdaShow.genome_build === 'hg18',
+ "genome_build successfully set via update: " + hdaShow.genome_build );
+ this.test.assert( hdaShow.metadata_dbkey === 'hg18',
+ "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
+ this.test.comment( 'update should sanitize any genome_build' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : 'hg18<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.genome_build === 'hg18',
+ "Update sanitized genome_build: " + hdaShow.genome_build );
+ this.test.assert( hdaShow.metadata_dbkey === 'hg18',
+ "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
+
+ this.test.comment( 'update should allow unicode in genome builds' );
+ var unicodeBuild = 'Ржевский18';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ genome_build : unicodeBuild
+ });
+ this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
+ this.test.assert( hdaShow.genome_build === unicodeBuild,
+ "Update accepted unicode genome_build: " + hdaShow.genome_build );
+
+ // ........................................................................................... misc_info/info
+ this.test.comment( 'update should allow changing the misc_info' );
+ var newInfo = 'I\'ve made a huge mistake.';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : newInfo
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === newInfo,
+ "misc_info successfully set via update: " + hdaShow.misc_info );
+
+ this.test.comment( 'update should sanitize any misc_info' );
+ var newInfo = 'You\'re going to get hop-ons.';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : newInfo + '<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === newInfo,
+ "Update sanitized misc_info: " + hdaShow.misc_info );
+
+ this.test.comment( 'update should allow unicode in misc_info' );
+ var unicodeInfo = '여보!';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ misc_info : unicodeInfo
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.misc_info === unicodeInfo,
+ "Update accepted unicode misc_info: " + hdaShow.misc_info );
+
+ // ........................................................................................... annotation
+ // currently fails because no annotation is returned in details
+ this.test.comment( 'update should allow changing the annotation' );
+ var newAnnotation = 'Found this sample on a movie theatre floor';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : newAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === newAnnotation,
+ "Annotation successfully set via update: " + hdaShow.annotation );
+
+ this.test.comment( 'update should sanitize any new annotation' );
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : 'New annotation<script type="text/javascript" src="bler">alert("blah");</script>'
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === 'New annotation',
+ "Update sanitized annotation: " + hdaShow.annotation );
+
+ this.test.comment( 'update should allow unicode in annotations' );
+ var unicodeAnnotation = 'お願いは、それが落下させない';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : unicodeAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === unicodeAnnotation,
+ "Update accepted unicode annotation: " + hdaShow.annotation );
+
+ this.test.comment( 'update should allow escaped quotations in annotations' );
+ var quotedAnnotation = '"Bler"';
+ returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
+ annotation : quotedAnnotation
+ });
+ //this.debug( 'returned:\n' + this.jsonStr( returned ) );
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.annotation === quotedAnnotation,
+ "Update accepted escaped quotations in annotation: " + hdaShow.annotation );
+
+ // ------------------------------------------------------------------------------------------- ERRORS
+ this.test.comment( 'create should error with "Please define the source" when the param "from_ld_id" is not used' );
+ this.api.assertRaises( function(){
+ this.api.hdas.create( lastHistory.id, { bler: 'bler' } );
+ }, 400, "must be either 'library' or 'hda'", 'create with no source failed' );
+
+ this.test.comment( 'updating using a nonsense key should fail silently' );
+ returned = this.api.hdas.update( lastHistory.id, hdaShow.id, {
+ konamiCode : 'uuddlrlrba'
+ });
+ this.test.assert( returned.konamiCode === undefined, 'key was not set: ' + returned.konamiCode );
+
+ spaceghost.test.comment( 'A bad id should throw an error when using show' );
+ this.api.assertRaises( function(){
+ this.api.hdas.show( lastHistory.id, '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
+ spaceghost.test.comment( 'A bad id should throw an error when using update' );
+ this.api.assertRaises( function(){
+ this.api.hdas.update( lastHistory.id, '1234123412341234', {} );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: update' );
+ spaceghost.test.comment( 'A bad id should throw an error when using delete' );
+ this.api.assertRaises( function(){
+ this.api.hdas.delete_( lastHistory.id, '1234123412341234' );
+ }, 400, 'unable to decode', 'Bad Request with invalid id: delete' );
+ spaceghost.test.comment( 'A bad id should throw an error when using undelete' );
+
+ this.test.comment( 'updating by attempting to change type should cause an error' );
+ [ 'name', 'annotation', 'genome_build', 'misc_info' ].forEach( function( key ){
+ var updatedAttrs = {};
+ updatedAttrs[ key ] = false;
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
+ }, 400, key + ' must be a string or unicode', 'type validation error' );
+ });
+ [ 'deleted', 'visible' ].forEach( function( key ){
+ var updatedAttrs = {};
+ updatedAttrs[ key ] = 'straaang';
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
+ }, 400, key + ' must be a boolean', 'type validation error' );
+ });
+ [ 'you\'re it', [ true ] ].forEach( function( badVal ){
+ spaceghost.api.assertRaises( function(){
+ returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, { tags: badVal });
+ }, 400, 'tags must be a list', 'type validation error' );
+ });
+
+ // ------------------------------------------------------------------------------------------- DELETE
+ this.test.comment( 'calling delete on an hda should mark it as deleted but not change the history size' );
+ lastHistory = this.api.histories.show( lastHistory.id );
+ var sizeBeforeDelete = lastHistory.nice_size;
+
+ returned = this.api.hdas.delete_( lastHistory.id, firstHda.id );
+ //this.debug( this.jsonStr( returned ) );
+
+ hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
+ this.test.assert( hdaShow.deleted, 'hda is marked deleted' );
+ lastHistory = this.api.histories.show( lastHistory.id );
+ this.test.assert( lastHistory.nice_size === sizeBeforeDelete, 'history size has not changed' );
+
+ // by default, purging fails bc uni.ini:allow_user_dataset_purge=False
+ this.api.assertRaises( function(){
+ returned = this.api.hdas.delete_( lastHistory.id, firstHda.id, { purge : true });
+ }, 403, 'This instance does not allow user dataset purging', 'Purge failed' );
+ /*
+ */
});
- //this.debug( 'returned:' + this.jsonStr( returned ) );
- this.test.assert( this.hasKeys( returned, detailKeys ), 'Has the proper keys' );
- this.test.assert( typeof returned.id !== 'number' && isNaN( Number( returned.id ) ),
- 'id seems to be encoded: ' + returned.id );
- this.test.assert( typeof returned.history_id !== 'number' && isNaN( Number( returned.history_id ) ),
- 'history_id seems to be encoded: ' + returned.history_id );
+ //spaceghost.user.logout();
- // ------------------------------------------------------------------------------------------- UPDATE
- // ........................................................................................... idiot proofing
- this.test.comment( 'updating to the current value should return no value (no change)' );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- var returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : hdaShow.name
- });
- this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
-
- this.test.comment( 'updating using a nonsense key should NOT fail with an error' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- konamiCode : 'uuddlrlrba'
- });
- this.test.assert( this.countKeys( returned ) === 0, "No changed returned: " + this.jsonStr( returned ) );
-
- this.test.comment( 'updating by attempting to change type should cause an error' );
- this.api.assertRaises( function(){
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- //name : false
- deleted : 'sure why not'
- });
- }, 400, 'deleted must be a boolean', 'changing deleted type failed' );
-
- // ........................................................................................... name
- this.test.comment( 'update should allow changing the name' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : 'New name'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === 'New name', "Name successfully set via update: " + hdaShow.name );
-
- this.test.comment( 'update should sanitize any new name' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : 'New name<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === 'New name', "Update sanitized name: " + hdaShow.name );
-
- this.test.comment( 'update should allow unicode in names' );
- var unicodeName = 'Ржевский сапоги';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : unicodeName
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === unicodeName, "Update accepted unicode name: " + hdaShow.name );
-
- this.test.comment( 'update should allow escaped quotations in names' );
- var quotedName = '"Bler"';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- name : quotedName
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.name === quotedName,
- "Update accepted escaped quotations in name: " + hdaShow.name );
-
-
- // ........................................................................................... deleted
- this.test.comment( 'update should allow changing the deleted flag' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- deleted: true
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id, true );
- this.test.assert( hdaShow.deleted === true, "Update set the deleted flag: " + hdaShow.deleted );
-
- this.test.comment( 'update should allow changing the deleted flag back' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- deleted: false
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.deleted === false, "Update set the deleted flag: " + hdaShow.deleted );
-
-
- // ........................................................................................... visible/hidden
- this.test.comment( 'update should allow changing the visible flag' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- visible: false
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.visible === false, "Update set the visible flag: " + hdaShow.visible );
-
-
- // ........................................................................................... genome_build/dbkey
- this.test.comment( 'update should allow changing the genome_build' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : 'hg18'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- //this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
- this.test.assert( hdaShow.genome_build === 'hg18',
- "genome_build successfully set via update: " + hdaShow.genome_build );
- this.test.assert( hdaShow.metadata_dbkey === 'hg18',
- "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
- this.test.comment( 'update should sanitize any genome_build' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : 'hg18<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.genome_build === 'hg18',
- "Update sanitized genome_build: " + hdaShow.genome_build );
- this.test.assert( hdaShow.metadata_dbkey === 'hg18',
- "metadata_dbkey successfully set via the same update: " + hdaShow.metadata_dbkey );
-
- this.test.comment( 'update should allow unicode in genome builds' );
- var unicodeBuild = 'Ржевский18';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- genome_build : unicodeBuild
- });
- this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.debug( 'hdaShow:\n' + this.jsonStr( hdaShow ) );
- this.test.assert( hdaShow.genome_build === unicodeBuild,
- "Update accepted unicode genome_build: " + hdaShow.genome_build );
-
- // ........................................................................................... misc_info/info
- this.test.comment( 'update should allow changing the misc_info' );
- var newInfo = 'I\'ve made a huge mistake.';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : newInfo
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === newInfo,
- "misc_info successfully set via update: " + hdaShow.misc_info );
-
- this.test.comment( 'update should sanitize any misc_info' );
- var newInfo = 'You\'re going to get hop-ons.';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : newInfo + '<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === newInfo,
- "Update sanitized misc_info: " + hdaShow.misc_info );
-
- this.test.comment( 'update should allow unicode in misc_info' );
- var unicodeInfo = '여보!';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- misc_info : unicodeInfo
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.misc_info === unicodeInfo,
- "Update accepted unicode misc_info: " + hdaShow.misc_info );
-
- // ........................................................................................... annotation
- // currently fails because no annotation is returned in details
- this.test.comment( 'update should allow changing the annotation' );
- var newAnnotation = 'Found this sample on a movie theatre floor';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : newAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === newAnnotation,
- "Annotation successfully set via update: " + hdaShow.annotation );
-
- this.test.comment( 'update should sanitize any new annotation' );
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : 'New annotation<script type="text/javascript" src="bler">alert("blah");</script>'
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === 'New annotation',
- "Update sanitized annotation: " + hdaShow.annotation );
-
- this.test.comment( 'update should allow unicode in annotations' );
- var unicodeAnnotation = 'お願いは、それが落下させない';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : unicodeAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === unicodeAnnotation,
- "Update accepted unicode annotation: " + hdaShow.annotation );
-
- this.test.comment( 'update should allow escaped quotations in annotations' );
- var quotedAnnotation = '"Bler"';
- returned = this.api.hdas.update( lastHistory.id, firstHda.id, {
- annotation : quotedAnnotation
- });
- //this.debug( 'returned:\n' + this.jsonStr( returned ) );
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.annotation === quotedAnnotation,
- "Update accepted escaped quotations in annotation: " + hdaShow.annotation );
-
- // ------------------------------------------------------------------------------------------- ERRORS
- this.test.comment( 'create should error with "Please define the source" when the param "from_ld_id" is not used' );
- this.api.assertRaises( function(){
- this.api.hdas.create( lastHistory.id, { bler: 'bler' } );
- }, 400, "must be either 'library' or 'hda'", 'create with no source failed' );
-
- this.test.comment( 'updating using a nonsense key should fail silently' );
- returned = this.api.hdas.update( lastHistory.id, hdaShow.id, {
- konamiCode : 'uuddlrlrba'
- });
- this.test.assert( returned.konamiCode === undefined, 'key was not set: ' + returned.konamiCode );
-
- spaceghost.test.comment( 'A bad id should throw an error when using show' );
- this.api.assertRaises( function(){
- this.api.hdas.show( lastHistory.id, '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: show' );
- spaceghost.test.comment( 'A bad id should throw an error when using update' );
- this.api.assertRaises( function(){
- this.api.hdas.update( lastHistory.id, '1234123412341234', {} );
- }, 400, 'unable to decode', 'Bad Request with invalid id: update' );
- spaceghost.test.comment( 'A bad id should throw an error when using delete' );
- this.api.assertRaises( function(){
- this.api.hdas.delete_( lastHistory.id, '1234123412341234' );
- }, 400, 'unable to decode', 'Bad Request with invalid id: delete' );
- spaceghost.test.comment( 'A bad id should throw an error when using undelete' );
-
- this.test.comment( 'updating by attempting to change type should cause an error' );
- [ 'name', 'annotation', 'genome_build', 'misc_info' ].forEach( function( key ){
- var updatedAttrs = {};
- updatedAttrs[ key ] = false;
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
- }, 400, key + ' must be a string or unicode', 'type validation error' );
- });
- [ 'deleted', 'visible' ].forEach( function( key ){
- var updatedAttrs = {};
- updatedAttrs[ key ] = 'straaang';
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, updatedAttrs );
- }, 400, key + ' must be a boolean', 'type validation error' );
- });
- [ 'you\'re it', [ true ] ].forEach( function( badVal ){
- spaceghost.api.assertRaises( function(){
- returned = spaceghost.api.hdas.update( hdaShow.history_id, hdaShow.id, { tags: badVal });
- }, 400, 'tags must be a list', 'type validation error' );
- });
-
- // ------------------------------------------------------------------------------------------- DELETE
- this.test.comment( 'calling delete on an hda should mark it as deleted but not change the history size' );
- lastHistory = this.api.histories.show( lastHistory.id );
- var sizeBeforeDelete = lastHistory.nice_size;
-
- returned = this.api.hdas.delete_( lastHistory.id, firstHda.id );
- //this.debug( this.jsonStr( returned ) );
-
- hdaShow = this.api.hdas.show( lastHistory.id, firstHda.id );
- this.test.assert( hdaShow.deleted, 'hda is marked deleted' );
- lastHistory = this.api.histories.show( lastHistory.id );
- this.test.assert( lastHistory.nice_size === sizeBeforeDelete, 'history size has not changed' );
-
- // by default, purging fails bc uni.ini:allow_user_dataset_purge=False
- this.api.assertRaises( function(){
- returned = this.api.hdas.delete_( lastHistory.id, firstHda.id, { purge : true });
- }, 403, 'This instance does not allow user dataset purging', 'Purge failed' );
-/*
-*/
-});
-//spaceghost.user.logout();
-
-
-// ===================================================================
+ // ===================================================================
spaceghost.run( function(){ test.done(); });
});
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
10 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/9e973ebf7272/
Changeset: 9e973ebf7272
User: jmchilton
Date: 2014-12-22 18:16:25+00:00
Summary: Remove some unused imports from lib/galaxy/tools/__init__.py.
Affected #: 1 file
diff -r 815d38c48a5639d47eed92806ef4c196406f58f1 -r 9e973ebf7272bcd1ff684e82bfb62b4938875f94 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -7,20 +7,15 @@
import json
import logging
import os
-import pipes
import re
import shutil
-import sys
import string
import tarfile
import tempfile
import threading
-import traceback
import types
import urllib
-from math import isinf
-
from galaxy import eggs
eggs.require( "MarkupSafe" ) # MarkupSafe must load before mako
eggs.require( "Mako" )
@@ -35,10 +30,8 @@
from sqlalchemy import and_
from galaxy import jobs, model
-from galaxy.jobs.error_level import StdioErrorLevel
from galaxy.datatypes.metadata import JobExternalOutputMetadataWrapper
from galaxy import exceptions
-from galaxy.jobs import ParallelismInfo
from galaxy.tools import watcher
from galaxy.tools.actions import DefaultToolAction
from galaxy.tools.actions.data_source import DataSourceToolAction
@@ -58,12 +51,11 @@
from galaxy.tools.test import parse_tests
from galaxy.tools.parser import get_tool_source
from galaxy.tools.parser.xml import XmlPageSource
-from galaxy.util import listify, parse_xml, rst_to_html, string_as_bool, string_to_object, xml_text, xml_to_string
+from galaxy.util import listify, parse_xml, rst_to_html, string_as_bool, string_to_object
from galaxy.tools.parameters.meta import expand_meta_parameters
from galaxy.util.bunch import Bunch
from galaxy.util.expressions import ExpressionContext
from galaxy.util.hash_util import hmac_new
-from galaxy.util.none_like import NoneDataset
from galaxy.util.odict import odict
from galaxy.util.template import fill_template
from galaxy.web import url_for
@@ -73,7 +65,7 @@
from galaxy.model import Workflow
from tool_shed.util import common_util
from tool_shed.util import shed_util_common as suc
-from .loader import load_tool, template_macro_params, raw_tool_xml_tree, imported_macro_paths
+from .loader import template_macro_params, raw_tool_xml_tree, imported_macro_paths
from .execute import execute as execute_job
from .wrappers import (
ToolParameterValueWrapper,
https://bitbucket.org/galaxy/galaxy-central/commits/6e956fdb0034/
Changeset: 6e956fdb0034
User: jmchilton
Date: 2014-12-22 18:16:25+00:00
Summary: More PEP-8 style tweaks to lib/galaxy/tools/__init__.py.
Affected #: 1 file
diff -r 9e973ebf7272bcd1ff684e82bfb62b4938875f94 -r 6e956fdb003441f699e24750f02c61c43992a784 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -257,8 +257,9 @@
return tool_path
def __add_tool_to_tool_panel( self, tool, panel_component, section=False ):
- # See if a version of this tool is already loaded into the tool panel. The value of panel_component
- # will be a ToolSection (if the value of section=True) or self.tool_panel (if section=False).
+ # See if a version of this tool is already loaded into the tool panel.
+ # The value of panel_component will be a ToolSection (if the value of
+ # section=True) or self.tool_panel (if section=False).
tool_id = str( tool.id )
tool = self.tools_by_id[ tool_id ]
if section:
@@ -300,13 +301,17 @@
if not inserted:
inserted = True
if not inserted:
- if tool.guid is None or \
- tool.tool_shed is None or \
- tool.repository_name is None or \
- tool.repository_owner is None or \
- tool.installed_changeset_revision is None:
- # We have a tool that was not installed from the Tool Shed, but is also not yet defined in
- # integrated_tool_panel.xml, so append it to the tool panel.
+ if (
+ tool.guid is None or
+ tool.tool_shed is None or
+ tool.repository_name is None or
+ tool.repository_owner is None or
+ tool.installed_changeset_revision is None
+ ):
+ # We have a tool that was not installed from the Tool
+ # Shed, but is also not yet defined in
+ # integrated_tool_panel.xml, so append it to the tool
+ # panel.
panel_dict[ key ] = tool
log.debug( "Loaded tool id: %s, version: %s into tool panel.." % ( tool.id, tool.version ) )
else:
@@ -364,9 +369,10 @@
def load_integrated_tool_panel_keys( self ):
"""
- Load the integrated tool panel keys, setting values for tools and workflows to None. The values will
- be reset when the various tool panel config files are parsed, at which time the tools and workflows are
- loaded.
+ Load the integrated tool panel keys, setting values for tools and
+ workflows to None. The values will be reset when the various tool
+ panel config files are parsed, at which time the tools and workflows
+ are loaded.
"""
tree = parse_xml( self.integrated_tool_panel_config )
root = tree.getroot()
@@ -499,11 +505,11 @@
# We store only the port, if one exists, in the database.
tool_shed = common_util.remove_protocol_from_tool_shed_url( tool_shed )
return self.app.install_model.context.query( self.app.install_model.ToolShedRepository ) \
- .filter( and_( self.app.install_model.ToolShedRepository.table.c.tool_shed == tool_shed,
- self.app.install_model.ToolShedRepository.table.c.name == name,
- self.app.install_model.ToolShedRepository.table.c.owner == owner,
- self.app.install_model.ToolShedRepository.table.c.installed_changeset_revision == installed_changeset_revision ) ) \
- .first()
+ .filter( and_( self.app.install_model.ToolShedRepository.table.c.tool_shed == tool_shed,
+ self.app.install_model.ToolShedRepository.table.c.name == name,
+ self.app.install_model.ToolShedRepository.table.c.owner == owner,
+ self.app.install_model.ToolShedRepository.table.c.installed_changeset_revision == installed_changeset_revision ) ) \
+ .first()
def get_tool_components( self, tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=False ):
"""
@@ -627,12 +633,14 @@
log.exception( "Error reading tool from path: %s" % path )
def __add_tool( self, tool, load_panel_dict, panel_dict ):
- # Allow for the same tool to be loaded into multiple places in the tool panel. We have to handle
- # the case where the tool is contained in a repository installed from the tool shed, and the Galaxy
- # administrator has retrieved updates to the installed repository. In this case, the tool may have
- # been updated, but the version was not changed, so the tool should always be reloaded here. We used
- # to only load the tool if it was not found in self.tools_by_id, but performing that check did
- # not enable this scenario.
+ # Allow for the same tool to be loaded into multiple places in the
+ # tool panel. We have to handle the case where the tool is contained
+ # in a repository installed from the tool shed, and the Galaxy
+ # administrator has retrieved updates to the installed repository. In
+ # this case, the tool may have been updated, but the version was not
+ # changed, so the tool should always be reloaded here. We used to
+ # only load the tool if it was not found in self.tools_by_id, but
+ # performing that check did not enable this scenario.
self.tools_by_id[ tool.id ] = tool
if load_panel_dict:
self.__add_tool_to_tool_panel( tool, panel_dict, section=isinstance( panel_dict, ToolSection ) )
@@ -787,8 +795,6 @@
:param tool_id: the tool ID from app.toolbox
:returns: tuple of tarball filename, success True/False, message/None
"""
- message = ''
- success = True
# Make sure the tool is actually loaded.
if tool_id not in self.tools_by_id:
return None, False, "No tool with id %s" % escape( tool_id )
@@ -870,7 +876,6 @@
if os.path.exists( sample_file ):
tarfile_path, tarfile_name = os.path.split( tar_file )
tarfile_path = os.path.join( 'tool-data', tarfile_name )
- sample_name = tarfile_path + '.sample'
tarball_files.append( ( sample_file, tarfile_path ) )
data_table_definitions.append( data_table.xml_string )
if len( data_table_definitions ) > 0:
https://bitbucket.org/galaxy/galaxy-central/commits/50a4c5ef908c/
Changeset: 50a4c5ef908c
User: jmchilton
Date: 2014-12-22 18:16:26+00:00
Summary: Small simplifications to lib/galaxy/tools/__init__.py.
Affected #: 1 file
diff -r 6e956fdb003441f699e24750f02c61c43992a784 -r 50a4c5ef908c38ecf6530d7ac9dd3a497d1ec313 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -289,8 +289,7 @@
for index, integrated_panel_key in enumerate( self.integrated_tool_panel.keys() ):
if key == integrated_panel_key:
panel_dict.insert( index, key, tool )
- if not inserted:
- inserted = True
+ inserted = True
if not inserted:
# Check the tool's installed versions.
for lineage_id in tool.lineage_ids:
@@ -298,8 +297,7 @@
for index, integrated_panel_key in enumerate( self.integrated_tool_panel.keys() ):
if lineage_id_key == integrated_panel_key:
panel_dict.insert( index, key, tool )
- if not inserted:
- inserted = True
+ inserted = True
if not inserted:
if (
tool.guid is None or
@@ -322,8 +320,7 @@
if lineage_id in self.tools_by_id:
loaded_version_key = 'tool_%s' % lineage_id
if loaded_version_key in panel_dict:
- if not already_loaded:
- already_loaded = True
+ already_loaded = True
if not already_loaded:
# If the tool is not defined in integrated_tool_panel.xml, append it to the tool panel.
panel_dict[ key ] = tool
https://bitbucket.org/galaxy/galaxy-central/commits/de3fff02e89f/
Changeset: de3fff02e89f
User: jmchilton
Date: 2014-12-22 18:16:26+00:00
Summary: Remove broken method fix_integrated_tool_panel_dict.
As of 5f6c670 (Jan 10, 2014) this does nothing (``if section_value is None`` followed by ``if isinstance( section_value, Tool ):``) and nobody seemed to notice - so I assume it is unneeded. If still needed - someone needs to fix it :).
Affected #: 1 file
diff -r 50a4c5ef908c38ecf6530d7ac9dd3a497d1ec313 -r de3fff02e89fd4697e9656742ca8e3f4928b1a53 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -163,24 +163,8 @@
# This will cover cases where the Galaxy administrator manually edited one or more of the tool panel
# config files, adding or removing locally developed tools or workflows. The value of integrated_tool_panel
# will be False when things like functional tests are the caller.
- self.fix_integrated_tool_panel_dict()
self.write_integrated_tool_panel_config_file()
- def fix_integrated_tool_panel_dict( self ):
- # HACK: instead of fixing after the fact, I suggest some combination of:
- # 1) adjusting init_tools() and called methods to get this right
- # 2) redesigning the code and/or data structure used to read/write integrated_tool_panel.xml
- for key, value in self.integrated_tool_panel.iteritems():
- if isinstance( value, ToolSection ):
- for section_key, section_value in value.elems.iteritems():
- if section_value is None:
- if isinstance( section_value, Tool ):
- tool_id = section_key[5:]
- value.elems[section_key] = self.tools_by_id.get( tool_id )
- elif isinstance( section_value, Workflow ):
- workflow_id = section_key[9:]
- value.elems[section_key] = self.workflows_by_id.get( workflow_id )
-
def init_tools( self, config_filename ):
"""
Read the configuration file and load each tool. The following tags are currently supported:
@@ -723,7 +707,6 @@
# This will cover cases where the Galaxy administrator manually edited one or more of the tool panel
# config files, adding or removing locally developed tools or workflows. The value of integrated_tool_panel
# will be False when things like functional tests are the caller.
- self.fix_integrated_tool_panel_dict()
self.write_integrated_tool_panel_config_file()
return tool.id
except Exception:
https://bitbucket.org/galaxy/galaxy-central/commits/79f06cadb486/
Changeset: 79f06cadb486
User: jmchilton
Date: 2014-12-22 18:16:27+00:00
Summary: Slightly rework lib/galaxy/workflow/modules.py for readability.
Affected #: 1 file
diff -r de3fff02e89fd4697e9656742ca8e3f4928b1a53 -r 79f06cadb4861bc6e66a1733a0c3bbfa4606240c lib/galaxy/workflow/modules.py
--- a/lib/galaxy/workflow/modules.py
+++ b/lib/galaxy/workflow/modules.py
@@ -506,16 +506,17 @@
@classmethod
def from_workflow_step( Class, trans, step ):
+ toolbox = trans.app.toolbox
tool_id = step.tool_id
- if trans.app.toolbox and tool_id not in trans.app.toolbox.tools_by_id:
+ if toolbox and tool_id not in toolbox.tools_by_id:
# See if we have access to a different version of the tool.
# TODO: If workflows are ever enhanced to use tool version
# in addition to tool id, enhance the selection process here
# to retrieve the correct version of the tool.
- tool = trans.app.toolbox.get_tool( tool_id )
+ tool = toolbox.get_tool( tool_id )
if tool:
tool_id = tool.id
- if ( trans.app.toolbox and tool_id in trans.app.toolbox.tools_by_id ):
+ if ( toolbox and tool_id in toolbox.tools_by_id ):
if step.config:
# This step has its state saved in the config field due to the
# tool being previously unavailable.
https://bitbucket.org/galaxy/galaxy-central/commits/4be779372d6b/
Changeset: 4be779372d6b
User: jmchilton
Date: 2014-12-22 18:16:27+00:00
Summary: Rework toolbox 'fix' tool tags when multiple configs are loaded.
Looks like the tool tag stuff still assumed there was just one config file - that said toolbox doesn't have a self.sa_session so I think tool tags are broken and have been for some time.
Affected #: 1 file
diff -r 79f06cadb4861bc6e66a1733a0c3bbfa4606240c -r 4be779372d6b89656276307f4ae1ed4a8e6a5737 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -143,6 +143,26 @@
self.tool_watcher = watcher.get_watcher( self, app.config )
self.filter_factory = FilterFactory( self )
self.init_dependency_manager()
+ self.init_tools_from_configs( config_filenames )
+ if self.app.name == 'galaxy' and self.integrated_tool_panel_config_has_contents:
+ # Load self.tool_panel based on the order in self.integrated_tool_panel.
+ self.load_tool_panel()
+ if app.config.update_integrated_tool_panel:
+ # Write the current in-memory integrated_tool_panel to the integrated_tool_panel.xml file.
+ # This will cover cases where the Galaxy administrator manually edited one or more of the tool panel
+ # config files, adding or removing locally developed tools or workflows. The value of integrated_tool_panel
+ # will be False when things like functional tests are the caller.
+ self.write_integrated_tool_panel_config_file()
+
+ def init_tools_from_configs( self, config_filenames ):
+ """ Read through all tool config files and initialize tools in each
+ with init_tools_from_config below.
+ """
+ if self.app.config.get_bool( 'enable_tool_tags', False ):
+ log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")" )
+ self.sa_session.query( self.app.model.ToolTagAssociation ).delete()
+ self.sa_session.flush()
+
config_filenames = listify( config_filenames )
for config_filename in config_filenames:
if os.path.isdir( config_filename ):
@@ -152,20 +172,11 @@
config_filenames.extend( directory_config_files )
for config_filename in config_filenames:
try:
- self.init_tools( config_filename )
+ self.init_tools_from_config( config_filename )
except:
log.exception( "Error loading tools defined in config %s", config_filename )
- if self.app.name == 'galaxy' and self.integrated_tool_panel_config_has_contents:
- # Load self.tool_panel based on the order in self.integrated_tool_panel.
- self.load_tool_panel()
- if app.config.update_integrated_tool_panel:
- # Write the current in-memory integrated_tool_panel to the integrated_tool_panel.xml file.
- # This will cover cases where the Galaxy administrator manually edited one or more of the tool panel
- # config files, adding or removing locally developed tools or workflows. The value of integrated_tool_panel
- # will be False when things like functional tests are the caller.
- self.write_integrated_tool_panel_config_file()
-
- def init_tools( self, config_filename ):
+
+ def init_tools_from_config( self, config_filename ):
"""
Read the configuration file and load each tool. The following tags are currently supported:
@@ -183,10 +194,6 @@
</toolbox>
"""
- if self.app.config.get_bool( 'enable_tool_tags', False ):
- log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")" )
- self.sa_session.query( self.app.model.ToolTagAssociation ).delete()
- self.sa_session.flush()
log.info( "Parsing the tool configuration %s" % config_filename )
tree = parse_xml( config_filename )
root = tree.getroot()
https://bitbucket.org/galaxy/galaxy-central/commits/267fa4b9ab6a/
Changeset: 267fa4b9ab6a
User: jmchilton
Date: 2014-12-22 18:16:28+00:00
Summary: Refactor tool tag handling out of toolbox.
Pretty sure this had been broken (toolbox didn't have a self.sa_session). Anyway - this probably didn't fix that but at least now the big read tool tag loop is more readable (cyclomatic complexity of that method down from 18 to 12).
Affected #: 3 files
diff -r 4be779372d6b89656276307f4ae1ed4a8e6a5737 -r 267fa4b9ab6a80a0ae0a1f2ab5f157303f68d46d lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -51,6 +51,7 @@
from galaxy.tools.test import parse_tests
from galaxy.tools.parser import get_tool_source
from galaxy.tools.parser.xml import XmlPageSource
+from galaxy.tools.toolbox import tool_tag_manager
from galaxy.util import listify, parse_xml, rst_to_html, string_as_bool, string_to_object
from galaxy.tools.parameters.meta import expand_meta_parameters
from galaxy.util.bunch import Bunch
@@ -143,6 +144,7 @@
self.tool_watcher = watcher.get_watcher( self, app.config )
self.filter_factory = FilterFactory( self )
self.init_dependency_manager()
+ self.tool_tag_manager = tool_tag_manager( app )
self.init_tools_from_configs( config_filenames )
if self.app.name == 'galaxy' and self.integrated_tool_panel_config_has_contents:
# Load self.tool_panel based on the order in self.integrated_tool_panel.
@@ -158,11 +160,7 @@
""" Read through all tool config files and initialize tools in each
with init_tools_from_config below.
"""
- if self.app.config.get_bool( 'enable_tool_tags', False ):
- log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")" )
- self.sa_session.query( self.app.model.ToolTagAssociation ).delete()
- self.sa_session.flush()
-
+ self.tool_tag_manager.reset_tags()
config_filenames = listify( config_filenames )
for config_filename in config_filenames:
if os.path.isdir( config_filename ):
@@ -588,27 +586,7 @@
self.app.install_model.context.flush()
# Load the tool's lineage ids.
tool.lineage_ids = tool.tool_version.get_version_ids( self.app )
- if self.app.config.get_bool( 'enable_tool_tags', False ):
- tag_names = elem.get( "tags", "" ).split( "," )
- for tag_name in tag_names:
- if tag_name == '':
- continue
- tag = self.sa_session.query( self.app.model.Tag ).filter_by( name=tag_name ).first()
- if not tag:
- tag = self.app.model.Tag( name=tag_name )
- self.sa_session.add( tag )
- self.sa_session.flush()
- tta = self.app.model.ToolTagAssociation( tool_id=tool.id, tag_id=tag.id )
- self.sa_session.add( tta )
- self.sa_session.flush()
- else:
- for tagged_tool in tag.tagged_tools:
- if tagged_tool.tool_id == tool.id:
- break
- else:
- tta = self.app.model.ToolTagAssociation( tool_id=tool.id, tag_id=tag.id )
- self.sa_session.add( tta )
- self.sa_session.flush()
+ self.tool_tag_manager.handle_tags( tool.id, elem )
self.__add_tool( tool, load_panel_dict, panel_dict )
# Always load the tool into the integrated_panel_dict, or it will not be included in the integrated_tool_panel.xml file.
if key in integrated_panel_dict or index is None:
diff -r 4be779372d6b89656276307f4ae1ed4a8e6a5737 -r 267fa4b9ab6a80a0ae0a1f2ab5f157303f68d46d lib/galaxy/tools/toolbox/__init__.py
--- /dev/null
+++ b/lib/galaxy/tools/toolbox/__init__.py
@@ -0,0 +1,7 @@
+""" API for this module containing functionality related to the tool box.
+"""
+
+from .tags import tool_tag_manager
+
+
+__all__ = ["tool_tag_manager"]
diff -r 4be779372d6b89656276307f4ae1ed4a8e6a5737 -r 267fa4b9ab6a80a0ae0a1f2ab5f157303f68d46d lib/galaxy/tools/toolbox/tags.py
--- /dev/null
+++ b/lib/galaxy/tools/toolbox/tags.py
@@ -0,0 +1,76 @@
+""" Handle details of tool tagging - perhaps a deprecated feature.
+"""
+from abc import ABCMeta
+from abc import abstractmethod
+
+import logging
+log = logging.getLogger( __name__ )
+
+
+def tool_tag_manager( app ):
+ """ Build a tool tag manager according to app's configuration
+ and return it.
+ """
+ if hasattr( app.config, "get_bool" ) and app.config.get_bool( 'enable_tool_tags', False ):
+ return PersistentToolTagManager( app )
+ else:
+ return NullToolTagManager()
+
+
+class AbstractToolTagManager( object ):
+ __metaclass__ = ABCMeta
+
+ @abstractmethod
+ def reset_tags( self ):
+ """ Starting to load tool panels, reset all tags.
+ """
+
+ @abstractmethod
+ def handle_tags( self, tool_id, tool_definition_source ):
+ """ Parse out tags and persist them.
+ """
+
+
+class NullToolTagManager( AbstractToolTagManager ):
+
+ def reset_tags( self ):
+ return None
+
+ def handle_tags( self, tool_id, tool_definition_source ):
+ return None
+
+
+class PersistentToolTagManager( AbstractToolTagManager ):
+
+ def __init__( self, app ):
+ self.app = app
+ self.sa_session = app.sa_session
+
+ def reset_tags( self ):
+ log.info("removing all tool tag associations (" + str( self.sa_session.query( self.app.model.ToolTagAssociation ).count() ) + ")" )
+ self.sa_session.query( self.app.model.ToolTagAssociation ).delete()
+ self.sa_session.flush()
+
+ def handle_tags( self, tool_id, tool_definition_source ):
+ elem = tool_definition_source
+ if self.app.config.get_bool( 'enable_tool_tags', False ):
+ tag_names = elem.get( "tags", "" ).split( "," )
+ for tag_name in tag_names:
+ if tag_name == '':
+ continue
+ tag = self.sa_session.query( self.app.model.Tag ).filter_by( name=tag_name ).first()
+ if not tag:
+ tag = self.app.model.Tag( name=tag_name )
+ self.sa_session.add( tag )
+ self.sa_session.flush()
+ tta = self.app.model.ToolTagAssociation( tool_id=tool_id, tag_id=tag.id )
+ self.sa_session.add( tta )
+ self.sa_session.flush()
+ else:
+ for tagged_tool in tag.tagged_tools:
+ if tagged_tool.tool_id == tool_id:
+ break
+ else:
+ tta = self.app.model.ToolTagAssociation( tool_id=tool_id, tag_id=tag.id )
+ self.sa_session.add( tta )
+ self.sa_session.flush()
https://bitbucket.org/galaxy/galaxy-central/commits/d0c38a7861e5/
Changeset: d0c38a7861e5
User: jmchilton
Date: 2014-12-22 18:16:28+00:00
Summary: Tweak completely broken DataTransfer._execute_workflow to respect toolbox abstraction.
Least of the brokeness at this point I suppose - but I would like to not expose tools_by_id external to the Toolbox.
Affected #: 1 file
diff -r 267fa4b9ab6a80a0ae0a1f2ab5f157303f68d46d -r d0c38a7861e5d42f6068963f0917a78cdc9e6860 lib/galaxy/jobs/deferred/data_transfer.py
--- a/lib/galaxy/jobs/deferred/data_transfer.py
+++ b/lib/galaxy/jobs/deferred/data_transfer.py
@@ -356,7 +356,7 @@
for i, step in enumerate( workflow.steps ):
job = None
if step.type == 'tool' or step.type is None:
- tool = self.app.toolbox.tools_by_id[ step.tool_id ]
+ tool = self.app.toolbox.get_tool( step.tool_id )
def callback( input, value, prefixed_name, prefixed_label ):
if isinstance( input, DataToolParameter ):
if prefixed_name in step.input_connections_by_name:
https://bitbucket.org/galaxy/galaxy-central/commits/34b3e1ca729d/
Changeset: 34b3e1ca729d
User: jmchilton
Date: 2014-12-22 18:16:30+00:00
Summary: Start decoupling Toolbox elements from XML (sections+labels).
Just a small tweak and some tests to verify these things can indeed be created from dictionaries. Also slightly simplifies galaxy.tools.
Affected #: 2 files
diff -r d0c38a7861e5d42f6068963f0917a78cdc9e6860 -r 34b3e1ca729df33c32e96ca9202d3a80836c21ed lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -330,12 +330,13 @@
elif isinstance( val, ToolSectionLabel ):
self.tool_panel[ key ] = val
elif isinstance( val, ToolSection ):
- elem = ElementTree.Element( 'section' )
- elem.attrib[ 'id' ] = val.id or ''
- elem.attrib[ 'name' ] = val.name or ''
- elem.attrib[ 'version' ] = val.version or ''
- section = ToolSection( elem )
- log.debug( "Loading section: %s" % elem.get( 'name' ) )
+ section_dict = {
+ 'id': val.id or '',
+ 'name': val.name or '',
+ 'version': val.version or '',
+ }
+ section = ToolSection( section_dict )
+ log.debug( "Loading section: %s" % section_dict.get( 'name' ) )
for section_key, section_val in val.elems.items():
if isinstance( section_val, Tool ):
tool_id = section_key.replace( 'tool_', '', 1 )
@@ -1050,6 +1051,8 @@
dict_collection_visible_keys = ( 'id', 'name', 'version' )
def __init__( self, elem=None ):
+ """ Build a ToolSection from an ElementTree element or a dictionary.
+ """
f = lambda elem, val: elem is not None and elem.get( val ) or ''
self.name = f( elem, 'name' )
self.id = f( elem, 'id' )
@@ -1089,6 +1092,9 @@
dict_collection_visible_keys = ( 'id', 'text', 'version' )
def __init__( self, elem ):
+ """ Build a ToolSectionLabel from an ElementTree element or a
+ dictionary.
+ """
self.text = elem.get( "text" )
self.id = elem.get( "id" )
self.version = elem.get( "version" ) or ''
diff -r d0c38a7861e5d42f6068963f0917a78cdc9e6860 -r 34b3e1ca729df33c32e96ca9202d3a80836c21ed test/unit/tools/test_tool_panel.py
--- /dev/null
+++ b/test/unit/tools/test_tool_panel.py
@@ -0,0 +1,26 @@
+from xml.etree import ElementTree as ET
+from galaxy.tools import ToolSection
+
+
+def test_tool_section( ):
+ elem = ET.Element( 'section' )
+ elem.attrib[ 'name' ] = "Cool Tools"
+ elem.attrib[ 'id' ] = "cool1"
+
+ section = ToolSection( elem )
+ assert section.id == "cool1"
+ assert section.name == "Cool Tools"
+ assert section.version == ""
+
+ section = ToolSection( dict(
+ id="cool1",
+ name="Cool Tools"
+ ) )
+ assert section.id == "cool1"
+ assert section.name == "Cool Tools"
+ assert section.version == ""
+
+ section = ToolSection()
+ assert section.id == ""
+ assert section.name == ""
+ assert section.version == ""
https://bitbucket.org/galaxy/galaxy-central/commits/1aa8a57c5994/
Changeset: 1aa8a57c5994
User: jmchilton
Date: 2014-12-22 18:16:30+00:00
Summary: Add comment to auto-generated integrated_tool_panel.xml.
Someone more familiar with integrated_tool_panel.xml should feel free to make this comment sharper - but something is better nothing I think.
Affected #: 1 file
diff -r 34b3e1ca729df33c32e96ca9202d3a80836c21ed -r 1aa8a57c599455b2a9faeeadb980b62b8abecc1f lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -96,6 +96,16 @@
HELP_UNINITIALIZED = threading.Lock()
+INTEGRATED_TOOL_PANEL_DESCRIPTION = """
+This is Galaxy's integrated tool panel and probably should not be modified
+directly. It will be regenerated each time Galaxy starts up. To modify locally
+managed tools (e.g. from tool_conf.xml) modify that file directly and restart
+Galaxy. Whenever possible Tool Shed managed tools (e.g. from shed_tool_conf.xml)
+should be managed from within the Galaxy interface of via is UI - but if changes
+are nessecary (such as to hide a tool or re-assign its section) modify that file
+and restart Galaxy.
+"""
+
class ToolNotFoundException( Exception ):
pass
@@ -396,6 +406,9 @@
fd, filename = tempfile.mkstemp()
os.write( fd, '<?xml version="1.0"?>\n' )
os.write( fd, '<toolbox>\n' )
+ os.write( fd, ' <!--\n ')
+ os.write( fd, '\n '.join( [ l for l in INTEGRATED_TOOL_PANEL_DESCRIPTION.split("\n") if l ] ) )
+ os.write( fd, '\n -->\n')
for key, item in self.integrated_tool_panel.items():
if item:
if isinstance( item, Tool ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0