From 0a2aa7fe4afb8ec284d2a0eca2bb4844f21cc5d8 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:16:25 -0700 Subject: [PATCH 01/21] fix typo in comment --- tests/integration/estunnel/tunnel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/estunnel/tunnel.sh b/tests/integration/estunnel/tunnel.sh index 9c4345a..d4467c7 100644 --- a/tests/integration/estunnel/tunnel.sh +++ b/tests/integration/estunnel/tunnel.sh @@ -4,7 +4,7 @@ # Parameterized by: # IP - the ip address of the ES node machine # SSHUSER - the dev's username for ssh -# SSHPASS - the dev's passowrd +# SSHPASS - the dev's password sshpass -e ssh \ -4 \ From c9763e790d44aa65852f723a2a25c3b3504aae3a Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:17:27 -0700 Subject: [PATCH 02/21] add clarifying comments --- src/search1_rpc/service.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/search1_rpc/service.py b/src/search1_rpc/service.py index 52da8b1..c54d083 100644 --- a/src/search1_rpc/service.py +++ b/src/search1_rpc/service.py @@ -1,5 +1,5 @@ """ -JSON-RPC 2.0 service for the legacy API +JSON-RPC 1.1 service for the legacy API All methods follow this workflow: - convert RPC params into Elasticsearch query @@ -10,6 +10,11 @@ - search1_conversion.convert_params - es_client.search - search1_conversion.convert_result + +Note that the methods implement KBase's convention for JSON-RPC 1.1, +in which the request `params` are an array of one element, usually containing +an object, each property of which is considered a `param`, and in which the +results are also wrapped in an array of one element. """ import time @@ -21,6 +26,7 @@ from src.utils.logger import logger from src.search1_rpc.errors import trap_error +# A JSON-RPC 1.1 service description description = ServiceDescription( 'The KBase Legacy Search API', 'https://github.com/kbase/search_api2/src/search1_rpc/schemas', @@ -47,12 +53,10 @@ def get_objects(params, meta): search_result = trap_error(lambda: search(query, meta)) result = convert_result.get_objects(params, search_result, meta) logger.debug(f'Finished get_objects in {time.time() - start}s') - # KBase convention is to return result in a list return [result] def search_objects(params, meta): - # KBase convention is to wrap params in an array if isinstance(params, list) and len(params) == 1: params = params[0] start = time.time() @@ -60,12 +64,10 @@ def search_objects(params, meta): search_result = trap_error(lambda: search(query, meta)) result = convert_result.search_objects(params, search_result, meta) logger.debug(f'Finished search_objects in {time.time() - start}s') - # KBase convention is to return result in a list return [result] def search_types(params, meta): - # KBase convention is to wrap params in an array if isinstance(params, list) and len(params) == 1: params = params[0] start = time.time() @@ -73,7 +75,6 @@ def search_types(params, meta): search_result = trap_error(lambda: search(query, meta)) result = convert_result.search_types(params, search_result, meta) logger.debug(f'Finished search_types in {time.time() - start}s') - # KBase convention is to return result in a list return [result] From 22b8fef50da1b8e9d6b51764d33e1eb78a776a89 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:18:40 -0700 Subject: [PATCH 03/21] improve comment, remove commented-out code, add todo re timeout and commented out code --- src/es_client/query.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/es_client/query.py b/src/es_client/query.py index db58eac..65d4be3 100644 --- a/src/es_client/query.py +++ b/src/es_client/query.py @@ -25,13 +25,9 @@ def search(params, meta): # The query object, which we build up in steps below query = {'bool': {}} # type: dict - # if not params.get('only_public') and meta['auth']: - - # Fetch the workspace IDs that the user can read - # Used for access control and also to ensure that - # workspaces which are inaccessible in the workspace, - # but that fact is not yet updated in search, are - # still filtered out. + # Fetch the workspace IDs that the user can read. + # Used for access control and also to ensure that workspaces which are + # inaccessible, but have not yet been updated in search, are still filtered out. authorized_ws_ids = ws_auth( meta['auth'], params.get('only_public', False), @@ -52,6 +48,11 @@ def search(params, meta): # Make a query request to elasticsearch url = config['elasticsearch_url'] + '/' + index_name_str + '/_search' + # TODO: address the performance settings below: + # - 3m for timeout is seems excessive, and many other elements of the + # search process may have 1m timeouts; perhaps default to a lower limit, and + # allow a parameter to set the timeout to an arbitrary value + # - the "allow_expensive_queries" setting has been disabled, why? options = { 'query': query, 'size': 0 if params.get('count') else params.get('size', 10), From 9022936c32aa357a420b576072328cedff8cc052 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:27:36 -0700 Subject: [PATCH 04/21] remove guid and kbase_id, replace guids with ids for get_objects, rename result fields to align with rest of kbase and be easier to understand, add suffix delimiter and fix index parsing. Most of the functional changes to fix SCT-3001 and SCT-3002. --- src/search1_conversion/convert_params.py | 4 +- src/search1_conversion/convert_result.py | 55 ++++++++----------- .../KBaseSearchEngine.get_objects.params.json | 4 +- src/search2_rpc/service.py | 4 ++ src/utils/config.py | 8 ++- tests/integration/data.py | 2 +- tests/integration/docker/docker-compose.yaml | 1 + tests/unit/search1_conversion/data.py | 52 ++++++++---------- 8 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/search1_conversion/convert_params.py b/src/search1_conversion/convert_params.py index f4e80b9..5e7e815 100644 --- a/src/search1_conversion/convert_params.py +++ b/src/search1_conversion/convert_params.py @@ -119,7 +119,7 @@ def get_objects(params): Convert params from the "get_objects" RPC method into an Elasticsearch query. Retrieve a list of objects based on their upas. params: - guids - list of string - KBase IDs (upas) to fetch + ids - list of string - KBase IDs (upas) to fetch post_processing - object of post-query filters (see PostProcessing def at top of this module) output: objects - list of ObjectData - see the ObjectData type description in the module docstring above. @@ -128,7 +128,7 @@ def get_objects(params): Information about the workspaces in which the objects in the results reside. This data only applies to workspace objects. """ - query = {'query': {'terms': {'_id': params['guids']}}} + query = {'query': {'terms': {'_id': params['ids']}}} return query diff --git a/src/search1_conversion/convert_result.py b/src/search1_conversion/convert_result.py index 32eb08a..95d2929 100644 --- a/src/search1_conversion/convert_result.py +++ b/src/search1_conversion/convert_result.py @@ -1,17 +1,19 @@ -import re from src.utils.config import config from src.utils.formatting import iso8601_to_epoch from src.utils.user_profiles import get_user_profiles from src.utils.workspace import get_workspace_info +import logging + +logger = logging.getLogger('search2') # Mappings from search2 document fields to search1 fields: _KEY_MAPPING = { 'obj_name': 'object_name', - 'access_group': 'access_group', - 'obj_id': 'obj_id', - 'version': 'version', + 'access_group': 'workspace_id', + 'obj_id': 'object_id', + 'version': 'object_version', 'timestamp': 'timestamp', - 'obj_type_name': 'type', + 'obj_type_name': 'workspace_type_name', 'creator': 'creator' } @@ -194,20 +196,22 @@ def _get_object_data_from_search_results(search_results, post_processing): for (search2_key, search1_key) in _KEY_MAPPING.items(): obj[search1_key] = doc.get(search2_key) # The nested 'data' is all object-specific, so exclude all global keys + # TODO: what if an object index happens to use a key that overlaps with + # global keys? Shouldn't they be completely independent? obj_data = {key: doc[key] for key in doc if key not in _KEY_MAPPING} if post_processing.get('skip_data') != 1: obj['data'] = obj_data - obj['guid'] = _get_guid_from_doc(hit) - obj['kbase_id'] = obj['guid'].strip('WS:') - idx_pieces = hit['index'].split(config['prefix_delimiter']) + + obj['id'] = hit['id'] + + # Extracts the index name. + idx_pieces = hit['index'].split(config['suffix_delimiter']) idx_name = idx_pieces[0] idx_ver = int(idx_pieces[1] or 0) if len(idx_pieces) == 2 else 0 obj['index_name'] = idx_name - obj['type_ver'] = idx_ver - # For the UI, make the type field "GenomeFeature" instead of "Genome". - if 'genome_feature_type' in doc: - obj['type'] = 'GenomeFeature' + obj['index_version'] = idx_ver + # Set defaults for required fields in objects/data # Set some more top-level data manually that we use in the UI if post_processing.get('include_highlight') == 1: @@ -217,27 +221,12 @@ def _get_object_data_from_search_results(search_results, post_processing): transformed_highlight[_KEY_MAPPING.get(key, key)] = value obj['highlight'] = transformed_highlight # Always set object_name as a string type + # TODO: how can this ever be missing? obj['object_name'] = obj.get('object_name') or '' - obj['type'] = obj.get('type') or '' + obj['workspace_type_name'] = obj.get('workspace_type_name') or '' + # For the UI, make the type field "GenomeFeature" instead of "Genome". + # TODO: the handling of sub-objects needs to be redesigned. + if 'genome_feature_type' in doc: + obj['workspace_type_name'] = 'GenomeFeature' object_data.append(obj) return object_data - - -def _get_guid_from_doc(doc): - """ - Convert from our guid format 'WS::1:2:3' into the legacy format 'WS:1/2/3' - """ - # TODO this only works on the WS namespace should take into account the - # namespace name - # Remove the first namespace - _id = doc['id'].replace('WS::', '') - # Remove any secondary namespace - _id = re.sub(r'::..::.+', '', _id) - # Replace colon delimiters with slashes - _id = _id.replace(':', '/') - # Add a single-colon delimited workspace namespace - _id = 'WS:' + _id - # Append the object version - ver = str(doc.get('obj_type_version', 1)) - _id = _id + '/' + ver - return _id diff --git a/src/search1_rpc/schemas/KBaseSearchEngine.get_objects.params.json b/src/search1_rpc/schemas/KBaseSearchEngine.get_objects.params.json index d3fb9a6..27876a3 100644 --- a/src/search1_rpc/schemas/KBaseSearchEngine.get_objects.params.json +++ b/src/search1_rpc/schemas/KBaseSearchEngine.get_objects.params.json @@ -6,11 +6,11 @@ "items": { "type": "object", "required": [ - "guids" + "ids" ], "additionalProperties": false, "properties": { - "guids": { + "ids": { "type": "array", "items": { "type": "string" diff --git a/src/search2_rpc/service.py b/src/search2_rpc/service.py index 3a7dbfb..0a62c5d 100644 --- a/src/search2_rpc/service.py +++ b/src/search2_rpc/service.py @@ -50,6 +50,10 @@ def show_config(params, meta): """ Display publicly readable configuration settings for this server. Be sure to add new entries here explicitly so that nothing is shown unintentionally. + + Hidden keys: + - index_prefix_delimiter: should always be "."; should never be overridden + - index_suffix_delimiter: should always be "_"; should never be overridden """ exposed_keys = ['dev', 'elasticsearch_url', 'workspace_url', 'index_prefix', 'global', 'workers', 'user_profile_url'] diff --git a/src/utils/config.py b/src/utils/config.py index d5f573a..f5bae4f 100644 --- a/src/utils/config.py +++ b/src/utils/config.py @@ -7,10 +7,15 @@ def init_config(): """ Initialize configuration data for the whole app """ + # TODO: it might be better to NOT default to testing configuration, + # but rather explicitly set the test environment. + # Reason? A failure to configure one of these in prod could lead to + # confusing failure conditions. ws_url = os.environ.get('WORKSPACE_URL', 'https://ci.kbase.us/services/ws').strip('/') es_url = os.environ.get('ELASTICSEARCH_URL', 'http://localhost:9200').strip('/') index_prefix = os.environ.get('INDEX_PREFIX', 'test') - prefix_delimiter = os.environ.get('INDEX_PREFIX_DELIMITER', '_') + prefix_delimiter = os.environ.get('INDEX_PREFIX_DELIMITER', '.') + suffix_delimiter = os.environ.get('INDEX_SUFFIX_DELIMITER', '_') config_url = os.environ.get( 'GLOBAL_CONFIG_URL', 'https://github.com/kbase/index_runner_spec/releases/latest/download/config.yaml' @@ -34,6 +39,7 @@ def init_config(): 'elasticsearch_url': es_url, 'index_prefix': index_prefix, 'prefix_delimiter': prefix_delimiter, + 'suffix_delimiter': suffix_delimiter, 'workspace_url': ws_url, 'user_profile_url': user_profile_url, 'workers': int(os.environ.get('WORKERS', 8)), diff --git a/tests/integration/data.py b/tests/integration/data.py index a95d5c7..12f16a7 100644 --- a/tests/integration/data.py +++ b/tests/integration/data.py @@ -272,7 +272,7 @@ "object_name": "kb|g.2231", "timestamp": 1453530416321, "type": "GenomeFeature", - "type_ver": 1, + "index_version": 1, "creator": "kbasetest", "mod": "KBase Search", "parent_data": { diff --git a/tests/integration/docker/docker-compose.yaml b/tests/integration/docker/docker-compose.yaml index ca94700..05e4be6 100644 --- a/tests/integration/docker/docker-compose.yaml +++ b/tests/integration/docker/docker-compose.yaml @@ -32,6 +32,7 @@ services: - ELASTICSEARCH_URL=http://estunnel:9500 - INDEX_PREFIX=search2 - INDEX_PREFIX_DELIMITER=. + - INDEX_SUFFIX_DELIMITER=_ - USER_PROFILE_URL=https://ci.kbase.us/services/user_profile/rpc - WORKERS=2 - LOGLEVEL=WARNING diff --git a/tests/unit/search1_conversion/data.py b/tests/unit/search1_conversion/data.py index afd2501..26e31f7 100644 --- a/tests/unit/search1_conversion/data.py +++ b/tests/unit/search1_conversion/data.py @@ -181,33 +181,31 @@ "search_time": 1, "objects": [ { + "id": "WS::1:2", "object_name": "object2", - "access_group": 1, - "obj_id": 2, - "version": 1, + "workspace_id": 1, + "object_id": 2, + "object_version": 1, "timestamp": 0, - "type": "Module.Type-1.0", + "workspace_type_name": "Type", "creator": "username", "data": {"name": "name1"}, - "guid": "WS:1/2/1", - "kbase_id": "1/2/1", "index_name": "test", - "type_ver": 0, + "index_version": 0, "highlight": {"name": "name1"} }, { + "id": "WS::0:2", "object_name": "object2", - "access_group": 0, - "obj_id": 2, - "version": 1, + "workspace_id": 0, + "object_id": 2, + "object_version": 1, "timestamp": 0, - "type": "Module.Type-1.0", + "workspace_type_name": "Type", "creator": "username", "data": {"name": "name2"}, - "guid": "WS:0/2/1", - "kbase_id": "0/2/1", "index_name": "test", - "type_ver": 0, + "index_version": 0, "highlight": {"name": "name2"} } ], @@ -253,33 +251,31 @@ "search_time": 1, "objects": [ { + "id": "WS::1:2", "object_name": "object2", - "access_group": 1, - "obj_id": 2, - "version": 1, + "workspace_id": 1, + "object_id": 2, + "object_version": 1, "timestamp": 0, - "type": "Module.Type-1.0", + "workspace_type_name": "Type", "creator": "username", "data": {"name": "name1"}, - "guid": "WS:1/2/1", - "kbase_id": "1/2/1", "index_name": "test", - "type_ver": 0, + "index_version": 0, "highlight": {"name": "name1"} }, { + "id": "WS::0:2", "object_name": "object2", - "access_group": 0, - "obj_id": 2, - "version": 1, + "workspace_id": 0, + "object_id": 2, + "object_version": 1, "timestamp": 0, - "type": "Module.Type-1.0", + "workspace_type_name": "Type", "creator": "username", "data": {"name": "name2"}, - "guid": "WS:0/2/1", - "kbase_id": "0/2/1", "index_name": "test", - "type_ver": 0, + "index_version": 0, "highlight": {"name": "name2"} } ], From 9c60e14364ec6034cfda1b2875369dc19bcb6615 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:28:32 -0700 Subject: [PATCH 05/21] Test adjustments for the fixes in previous commit, and also a schema fix for the changes. --- src/search1_rpc/schemas/types.json | 85 ++---- .../search_objects/case-01-response.json | 52 ++-- .../search_objects/case-02-response.json | 182 ++++++------ .../search_objects/case-03-response.json | 157 +++++------ .../search_objects/case-04-response.json | 2 +- .../search_objects/case-06-response.json | 2 +- .../search_objects/case-07-response.json | 2 +- .../search_objects/case-08-response.json | 202 +++++++------- .../search_objects/case-09-response.json | 263 ++++++++---------- tests/unit/es_client/test_es_client.py | 2 +- .../test_search1_convert_params.py | 2 +- .../test_search1_convert_result.py | 13 +- tests/unit/search1_rpc/test_search1_rpc.py | 4 +- tests/unit/server/test_server.py | 6 +- 14 files changed, 457 insertions(+), 517 deletions(-) diff --git a/src/search1_rpc/schemas/types.json b/src/search1_rpc/schemas/types.json index 58cc32d..26e3326 100644 --- a/src/search1_rpc/schemas/types.json +++ b/src/search1_rpc/schemas/types.json @@ -18,86 +18,61 @@ ] }, "data": { - "title": "Search result", - "type": "object", - "properties": { - "creator": { - "type": "string" - }, - "shared_users": { - "type": "array", - "items": { - "type": "string" - } - }, - "timestamp": { - "type": "integer" - }, - "creation_date": { - "type": "string" - }, - "is_public": { - "type": "boolean" - }, - "access_group": { - "type": "integer" - }, - "obj_id": { - "type": "integer" - }, - "version": { - "type": "integer" - }, - "copied": { - "type": [ - "string", - "null" - ] - }, - "tags": { - "type": "array", - "items": { - "$ref": "#/definitions/tag" - } - } - } + "title": "Search result object data", + "type": "object" }, "searchResultHit": { "type": "object", "title": "Workspace object search result", "required": [ + "id", + "workspace_id", + "object_id", + "object_version", "object_name", - "type", - "type_ver", - "guid", - "kbase_id", + "workspace_type_name", + "timestamp", + "creator", "index_name", + "index_version", "data" ], "properties": { - "object_name": { + "id": { "type": "string" }, - "type": { - "type": "string" + "workspace_id": { + "type": "integer" + }, + "object_id": { + "type": "integer" }, - "type_ver": { + "object_version": { "type": "integer" }, - "guid": { + "object_name": { + "type": "string" + }, + "workspace_type_name": { "type": "string" }, - "kbase_id": { + "timestamp": { + "type": "integer" + }, + "creator": { "type": "string" }, "index_name": { "type": "string" }, - "data": { - "$ref": "#/definitions/data" + "index_version": { + "type": "integer" }, "highlight": { "$ref": "#/definitions/highlight" + }, + "data": { + "$ref": "#/definitions/data" } } }, diff --git a/tests/integration/data/legacy/search_objects/case-01-response.json b/tests/integration/data/legacy/search_objects/case-01-response.json index b3b94c1..70c10bf 100644 --- a/tests/integration/data/legacy/search_objects/case-01-response.json +++ b/tests/integration/data/legacy/search_objects/case-01-response.json @@ -1,5 +1,5 @@ { - "version": "1.1", + "object_version": "1.1", "result": [{ "pagination": { "start": 0, @@ -18,11 +18,11 @@ "search_time": 793, "objects": [{ "object_name": "ecoli_2contigs_orig", - "access_group": 45320, - "obj_id": 4, - "version": 4, + "workspace_id": 45320, + "object_id": 4, + "object_version": 4, "timestamp": 1574124911386, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "genome_id": "ecoli_2contigs_orig", @@ -69,21 +69,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:45320/4/1", + "id": "WS::45320:4", "kbase_id": "45320/4/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "genome_id": ["ecoli_2contigs_orig"], "object_name": ["ecoli_2contigs_orig"] } }, { "object_name": "Narrative.1574286995467", - "access_group": 45320, - "obj_id": 1, - "version": 13, + "workspace_id": 45320, + "object_id": 1, + "object_version": 13, "timestamp": 1586801969406, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "jayrbolton", "data": { "narrative_title": "Refdata import", @@ -143,20 +143,20 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:45320/1/1", + "id": "WS::45320:1", "kbase_id": "45320/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "data_objects.name": ["ecoli_2contigs_orig"] } }, { "object_name": "ecoli_2contigs_orig", - "access_group": 33192, - "obj_id": 36, - "version": 1, + "workspace_id": 33192, + "object_id": 36, + "object_version": 1, "timestamp": 1574185738033, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "genome_id": "ecoli_2contigs_orig", @@ -203,21 +203,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:33192/36/1", + "id": "WS::33192:36", "kbase_id": "33192/36/1", - "index_name": "genome_2", - "type_ver": 0, + "index_name": "genome", + "index_version": 2, "highlight": { "genome_id": ["ecoli_2contigs_orig"], "object_name": ["ecoli_2contigs_orig"] } }, { "object_name": "Narrative.1528306445083", - "access_group": 33192, - "obj_id": 1, - "version": 57, + "workspace_id": 33192, + "object_id": 1, + "object_version": 57, "timestamp": 1597187547970, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "jayrbolton", "data": { "narrative_title": "Test fiesta", @@ -295,10 +295,10 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:33192/1/1", + "id": "WS::33192:1", "kbase_id": "33192/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "data_objects.name": ["ecoli_2contigs_orig"] } diff --git a/tests/integration/data/legacy/search_objects/case-02-response.json b/tests/integration/data/legacy/search_objects/case-02-response.json index b65a65e..0795394 100644 --- a/tests/integration/data/legacy/search_objects/case-02-response.json +++ b/tests/integration/data/legacy/search_objects/case-02-response.json @@ -1,6 +1,6 @@ { "id": "0008033925138730691", - "version": "1.1", + "version": "1.1", "result": [{ "pagination": { "start": 0, @@ -15,11 +15,11 @@ "search_time": 2445, "objects": [{ "object_name": "Narrative.1594582422207", - "access_group": 52407, - "obj_id": 1, - "version": 65, + "workspace_id": 52407, + "object_id": 1, + "workspace_version": 65, "timestamp": 1614657640817, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "zimingy", "data": { "narrative_title": "KBase Test Data", @@ -145,18 +145,18 @@ "guid": "WS:52407/1/1", "kbase_id": "52407/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Import GFF3/FASTA file as Genome from Staging Area", "Name: KBasederivedGCF002287175.1.gbffgenome (GenomeFileUtil)\nThis is a genome data set.", "Import GenBank File as Genome from Staging Area", "Name: KBasederived16pairedtrimMEGAHIT.contigs.fagenome.gff_genome(AessemblyUtil)\nThis is a genome data"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "metagenome_badabing", - "access_group": 52407, - "obj_id": 41, - "version": 1, + "workspace_id": 52407, + "object_id": 41, + "workspace_version": 1, "timestamp": 1614655779259, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "metagenome_badabing", @@ -200,18 +200,18 @@ "guid": "WS:52407/41/1", "kbase_id": "52407/41/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "warnings": ["Genome molecule_type SingleLetterAlphabet is not expected for domain Unknown.", "SUSPECT: This genome has 131854 genes that needed to be spoofed for existing parentless CDS."], - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "Narrative.1484955375553", - "access_group": 16325, - "obj_id": 1, - "version": 30, + "workspace_id": 16325, + "object_id": 1, + "workspace_version": 30, "timestamp": 1614644544954, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "gaprice", "data": { "narrative_title": "QUASTtest", @@ -256,18 +256,18 @@ "guid": "WS:16325/1/1", "kbase_id": "16325/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["QUAST - Quality Assessment Tool for Genome Assemblies"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "Narrative.1587165662023", - "access_group": 51911, - "obj_id": 16, - "version": 50, + "workspace_id": 51911, + "object_id": 16, + "workspace_version": 50, "timestamp": 1613962939430, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "dylan", "data": { "narrative_title": "CI - BLAST tests on AMA", @@ -450,18 +450,18 @@ "guid": "WS:51911/16/1", "kbase_id": "51911/16/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Batch Create Genome Set - v1.2.0"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "Narrative.1605571868207", - "access_group": 57559, - "obj_id": 11, - "version": 107, + "workspace_id": 57559, + "object_id": 11, + "workspace_version": 107, "timestamp": 1613410653476, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "ialarmedalien", "data": { "narrative_title": "Many cell types", @@ -575,18 +575,18 @@ "guid": "WS:57559/11/1", "kbase_id": "57559/11/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Assess Genome Quality with CheckM - v1.0.8"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "Narrative.1610463857540", - "access_group": 58624, - "obj_id": 1, - "version": 44, + "workspace_id": 58624, + "object_id": 1, + "workspace_version": 44, "timestamp": 1612897762108, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "zimingy", "data": { "narrative_title": "kbase test data", @@ -679,18 +679,18 @@ "guid": "WS:58624/1/1", "kbase_id": "58624/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Import GFF3/FASTA file as Genome from Staging Area"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "Rhodobacter_sphaeroides_2.4.1_KBase.RAST", - "access_group": 59262, - "obj_id": 4, - "version": 1, + "workspace_id": 59262, + "object_id": 4, + "workspace_version": 1, "timestamp": 1611981183498, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "eapearson", "data": { "non_coding_feature_count": 67, @@ -731,18 +731,18 @@ "guid": "WS:59262/4/1", "kbase_id": "59262/4/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "warnings": ["Genome molecule_type Unknown is not expected for domain Bacteria."], - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "KBase_derived_GCF_002287175.1.gbff_genome", - "access_group": 52407, - "obj_id": 29, - "version": 1, + "workspace_id": 52407, + "object_id": 29, + "workspace_version": 1, "timestamp": 1611940994702, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "KBase_derived_GCF_002287175.1.gbff_genome", @@ -790,17 +790,17 @@ "guid": "WS:52407/29/1", "kbase_id": "52407/29/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "GCF_002287175.1_ASM228717v1_genomic.gbff_genome_2", - "access_group": 52407, - "obj_id": 26, - "version": 1, + "workspace_id": 52407, + "object_id": 26, + "workspace_version": 1, "timestamp": 1611933804041, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "GCF_002287175.1_ASM228717v1_genomic.gbff_genome_2", @@ -848,17 +848,17 @@ "guid": "WS:52407/26/1", "kbase_id": "52407/26/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "GCF_002287175.1_ASM228717v1_genomic.gbff_genome", - "access_group": 52407, - "obj_id": 23, - "version": 1, + "workspace_id": 52407, + "object_id": 23, + "workspace_version": 1, "timestamp": 1611933097634, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "GCF_002287175.1_ASM228717v1_genomic.gbff_genome", @@ -906,17 +906,17 @@ "guid": "WS:52407/23/1", "kbase_id": "52407/23/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "GCF_002287175.1_assembly.fa_genome", - "access_group": 52407, - "obj_id": 19, - "version": 1, + "workspace_id": 52407, + "object_id": 19, + "workspace_version": 1, "timestamp": 1611856021670, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "GCF_002287175.1_assembly.fa_genome", @@ -964,18 +964,18 @@ "guid": "WS:52407/19/1", "kbase_id": "52407/19/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "warnings": ["Genome molecule_type SingleLetterAlphabet is not expected for domain Unknown."], - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "GCF_002287175.1", - "access_group": 52407, - "obj_id": 21, - "version": 1, + "workspace_id": 52407, + "object_id": 21, + "workspace_version": 1, "timestamp": 1611847515429, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "GCF_002287175.1", @@ -1023,17 +1023,17 @@ "guid": "WS:52407/21/1", "kbase_id": "52407/21/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "GCF_002287175.1", - "access_group": 58624, - "obj_id": 31, - "version": 20, + "workspace_id": 58624, + "object_id": 31, + "workspace_version": 20, "timestamp": 1611847515429, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "GCF_002287175.1", @@ -1081,17 +1081,17 @@ "guid": "WS:58624/31/1", "kbase_id": "58624/31/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }, { "object_name": "Narrative.1611672842083", - "access_group": 59134, - "obj_id": 1, - "version": 50, + "workspace_id": 59134, + "object_id": 1, + "workspace_version": 50, "timestamp": 1611679881176, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "eapearson", "data": { "narrative_title": "Data Prep Feature Set Viewer Integration Test", @@ -1175,18 +1175,18 @@ "guid": "WS:59134/1/1", "kbase_id": "59134/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Add genome\nWe are going to have featuresets with genome, ama, and mixed genome & ama.", "Create feature sets\nAMA\nGenome\nSimply use buildfeatureset from genome, selecting 10 features.", "Build FeatureSet from Genome", "Merge ama and genome feature sets\nWe want a mixed feature set,"], - "type": ["Narrative"] + "workspace_type_name": ["Narrative"] } }, { "object_name": "KBase_derived_GCF_002287175.1.gff_genome", - "access_group": 52407, - "obj_id": 16, - "version": 1, + "workspace_id": 52407, + "object_id": 16, + "workspace_version": 1, "timestamp": 1611519563370, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "zimingy", "data": { "genome_id": "KBase_derived_GCF_002287175.1.gff_genome", @@ -1234,10 +1234,10 @@ "guid": "WS:52407/16/1", "kbase_id": "52407/16/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "warnings": ["Genome molecule_type SingleLetterAlphabet is not expected for domain Unknown."], - "type": ["Genome"] + "workspace_type_name": ["Genome"] } }], "access_group_narrative_info": { diff --git a/tests/integration/data/legacy/search_objects/case-03-response.json b/tests/integration/data/legacy/search_objects/case-03-response.json index 02c44c8..35d1ddf 100644 --- a/tests/integration/data/legacy/search_objects/case-03-response.json +++ b/tests/integration/data/legacy/search_objects/case-03-response.json @@ -1,5 +1,5 @@ { - "version": "1.1", + "object_version": "1.1", "result": [{ "pagination": { "start": 0, @@ -18,11 +18,11 @@ "search_time": 1544, "objects": [{ "object_name": "GCF_000759885.1", - "access_group": 56638, - "obj_id": 2, - "version": 1, + "workspace_id": 56638, + "object_id": 2, + "object_version": 1, "timestamp": 1531222570501, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "kbasedata", "data": { "genome_id": "GCF_000759885.1", @@ -65,10 +65,8 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:56638/2/1", - "kbase_id": "56638/2/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus"], "scientific_name": ["Prochlorococcus marinus str. GP2"], @@ -76,11 +74,11 @@ } }, { "object_name": "Narrative.1605747150690", - "access_group": 56638, - "obj_id": 1, - "version": 13, + "workspace_id": 56638, + "object_id": 1, + "object_version": 13, "timestamp": 1605765178549, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "kbaseuitest", "data": { "narrative_title": "Test Narrative for FeatureSet Integration Test", @@ -131,20 +129,18 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:56638/1/1", - "kbase_id": "56638/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus", "features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus"] } }, { "object_name": "Prochlorococcus_marinus", - "access_group": 53745, - "obj_id": 2, - "version": 1, + "workspace_id": 53745, + "object_id": 2, + "object_version": 1, "timestamp": 1485796830804, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180265.1", @@ -177,21 +173,19 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:53745/2/1", - "kbase_id": "53745/2/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "Prochlorococcus_marinus", - "access_group": 53744, - "obj_id": 4, - "version": 1, + "workspace_id": 53744, + "object_id": 4, + "object_version": 1, "timestamp": 1485796830804, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180265.1", @@ -224,21 +218,20 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:53744/4/1", - "kbase_id": "53744/4/1", + "id": "WS::53744:4", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "prokka_ouput_1", - "access_group": 47458, - "obj_id": 7, - "version": 1, + "workspace_id": 47458, + "object_id": 7, + "object_version": 1, "timestamp": 1585919913126, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "kbaseuitest", "data": { "genome_id": "GCF_000015645.1", @@ -279,10 +272,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:47458/7/1", - "kbase_id": "47458/7/1", + "id": "WS::47458:7", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Patterns and implications of gene gain and loss in the evolution of Prochlorococcus"], "scientific_name": ["Prochlorococcus marinus str. AS9601"], @@ -290,11 +282,11 @@ } }, { "object_name": "Prochlorococcus_marinus_str._AS9601", - "access_group": 47458, - "obj_id": 6, - "version": 1, + "workspace_id": 47458, + "object_id": 6, + "object_version": 1, "timestamp": 1485794271879, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_000015645.1", @@ -327,10 +319,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:47458/6/1", - "kbase_id": "47458/6/1", + "id": "WS::47458:6", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Patterns and implications of gene gain and loss in the evolution of Prochlorococcus"], "scientific_name": ["Prochlorococcus marinus str. AS9601"], @@ -338,11 +329,11 @@ } }, { "object_name": "Prochlorococcus_marinus", - "access_group": 44697, - "obj_id": 2, - "version": 1, + "workspace_id": 44697, + "object_id": 2, + "object_version": 1, "timestamp": 1485796717279, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180245.1", @@ -375,21 +366,20 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44697/2/1", - "kbase_id": "44697/2/1", + "id": "WS::44697:2", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "Prochlorococcus_marinus", - "access_group": 35753, - "obj_id": 2, - "version": 1, + "workspace_id": 35753, + "object_id": 2, + "object_version": 1, "timestamp": 1485796717279, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180245.1", @@ -422,25 +412,24 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:35753/2/1", - "kbase_id": "35753/2/1", + "id": "WS::35753:2", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "out_tree_1", - "access_group": 35753, - "obj_id": 3, - "version": 1, + "workspace_id": 35753, + "object_id": 3, + "object_version": 1, "timestamp": 1534549148045, - "type": "Tree", + "workspace_type_name": "Tree", "creator": "eapearson", "data": { "tree_name": null, - "type": "SpeciesTree", + "workspace_type_name": "SpeciesTree", "labels": [{ "node_id": "GCF_000007925.1", "label": "Prochlorococcus marinus subsp. marinus str. CCMP1375 (GCF_000007925.1)" @@ -514,20 +503,19 @@ "obj_type_module": "KBaseTrees", "index_runner_ver": "1.9.17" }, - "guid": "WS:35753/3/1", - "kbase_id": "35753/3/1", + "id": "WS::35753:3", "index_name": "tree_1", - "type_ver": 0, + "index_version": 0, "highlight": { "labels.label": ["Prochlorococcus marinus str. MIT 9313 (GCF_000011485.1)", "Prochlorococcus marinus str. NATL2A (GCF_000012465.1)", "Prochlorococcus marinus str. AS9601 (GCF_000015645.1)", "Prochlorococcus sp. MIT 0601 (GCF_000760175.1)", "Prochlorococcus sp. MIT 0603 (GCF_000760215.1)"] } }, { "object_name": "Prochlorococcus_marinus_2", - "access_group": 35011, - "obj_id": 4, - "version": 1, + "workspace_id": 35011, + "object_id": 4, + "object_version": 1, "timestamp": 1531226116626, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "kbasedata", "data": { "genome_id": "GCF_001180305.1", @@ -570,21 +558,20 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:35011/4/1", - "kbase_id": "35011/4/1", + "id": "WS::35011:4", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "Prochlorococcus_marinus", - "access_group": 35011, - "obj_id": 2, - "version": 1, + "workspace_id": 35011, + "object_id": 2, + "object_version": 1, "timestamp": 1485796717279, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180245.1", @@ -617,21 +604,20 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:35011/2/1", - "kbase_id": "35011/2/1", + "id": "WS::35011:2", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] } }, { "object_name": "Prochlorococcus_marinus_1", - "access_group": 35011, - "obj_id": 3, - "version": 1, + "workspace_id": 35011, + "object_id": 3, + "object_version": 1, "timestamp": 1485797107623, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_001180325.1", @@ -664,10 +650,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:35011/3/1", - "kbase_id": "35011/3/1", + "id": "WS::35011:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Prochlorococcus marinus"], "taxonomy": ["Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus"] diff --git a/tests/integration/data/legacy/search_objects/case-04-response.json b/tests/integration/data/legacy/search_objects/case-04-response.json index 9cc03d4..3631eaf 100644 --- a/tests/integration/data/legacy/search_objects/case-04-response.json +++ b/tests/integration/data/legacy/search_objects/case-04-response.json @@ -1,6 +1,6 @@ { "id": "xyz", - "version": "1.1", + "version": "1.1", "result": [{ "pagination": { "start": 0, diff --git a/tests/integration/data/legacy/search_objects/case-06-response.json b/tests/integration/data/legacy/search_objects/case-06-response.json index 078396c..bbe446b 100644 --- a/tests/integration/data/legacy/search_objects/case-06-response.json +++ b/tests/integration/data/legacy/search_objects/case-06-response.json @@ -1,6 +1,6 @@ { "id": "xyz", - "version": "1.1", + "version": "1.1", "result": [{ "pagination": {"start": 0, "count": 20}, "sorting_rules": [{ diff --git a/tests/integration/data/legacy/search_objects/case-07-response.json b/tests/integration/data/legacy/search_objects/case-07-response.json index 8fd47fc..4690c74 100644 --- a/tests/integration/data/legacy/search_objects/case-07-response.json +++ b/tests/integration/data/legacy/search_objects/case-07-response.json @@ -1,5 +1,5 @@ { - "version": "1.1", + "version": "1.1", "id": "17499051636214047", "result": [{ "pagination": { diff --git a/tests/integration/data/legacy/search_objects/case-08-response.json b/tests/integration/data/legacy/search_objects/case-08-response.json index cc9319e..e5ec64e 100644 --- a/tests/integration/data/legacy/search_objects/case-08-response.json +++ b/tests/integration/data/legacy/search_objects/case-08-response.json @@ -1,5 +1,5 @@ { - "version": "1.1", + "version": "1.1", "result": [{ "pagination": { "count": 20, @@ -26,11 +26,11 @@ "search_time": 1764, "objects": [{ "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260", @@ -77,15 +77,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_1", @@ -124,15 +124,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_2", @@ -171,15 +171,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_3", @@ -218,15 +218,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_4", @@ -265,15 +265,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_5", @@ -312,15 +312,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_6", @@ -359,15 +359,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_7", @@ -406,15 +406,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_8", @@ -453,15 +453,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_CDS_9", @@ -500,15 +500,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_1", @@ -547,15 +547,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_2", @@ -594,15 +594,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_3", @@ -641,15 +641,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_4", @@ -688,15 +688,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_5", @@ -735,15 +735,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_6", @@ -782,15 +782,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_7", @@ -829,15 +829,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_8", @@ -876,15 +876,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT2G22260_mRNA_9", @@ -923,15 +923,15 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }, { "object_name": "GCF_000001735.4", - "access_group": 15792, - "obj_id": 235089, - "version": 2, + "workspace_id": 15792, + "object_id": 235089, + "workspace_version": 2, "timestamp": 1593555698230, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "id": "AT3G51790", @@ -970,7 +970,7 @@ "guid": "WS:15792/235089/1", "kbase_id": "15792/235089/1", "index_name": "genome_features_2", - "type_ver": 0, + "index_version": 0, "highlight": {} }], "access_groups_info": { diff --git a/tests/integration/data/legacy/search_objects/case-09-response.json b/tests/integration/data/legacy/search_objects/case-09-response.json index 77b5388..59dcd41 100644 --- a/tests/integration/data/legacy/search_objects/case-09-response.json +++ b/tests/integration/data/legacy/search_objects/case-09-response.json @@ -1,5 +1,5 @@ { - "version": "1.1", + "object_version": "1.1", "result": [{ "pagination": { "start": 0, @@ -11,18 +11,19 @@ "ascending": 0 }, { "is_object_property": 0, - "property": "type", + "property": "workspace_type", "ascending": 1 }], "total": 115, "search_time": 784, "objects": [{ + "id": "WS::52489:1", "object_name": "Narrative.1594758723895", - "access_group": 52489, - "obj_id": 1, - "version": 23, + "workspace_id": 52489, + "object_id": 1, + "object_version": 23, "timestamp": 1609804811154, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "eapearson", "data": { "narrative_title": "Taxonomy Landing Page Testing", @@ -61,20 +62,19 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:52489/1/1", - "kbase_id": "52489/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["NCBI\nnamespace: ncbi_taxonomy\nExample for Escherichia coli:\nhttps://ci.kbase.us#taxonomy/taxon/ncbi_taxonomy", "GTDB\nnamespace: gtdb\nExample for Escherichia coli:\nhttps://ci.kbase.us#taxonomy/taxon/gtdb/GBGCA900481195.1", "RDP\nnamespace: rdb_taxonomy\nExample for Escherichia coli; PK3; X80731:\nhttps://ci.kbase.us#taxonomy/taxon", "SILVA\nnamespace: silva_taxonomy\nExample for Escherichia coli; PK3; X80731:\nhttps://ci.kbase.us#taxonomy"] } }, { + "id": "WS::50631:3", "object_name": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", - "access_group": 50631, - "obj_id": 3, - "version": 1, + "workspace_id": 50631, + "object_id": 3, + "object_version": 1, "timestamp": 1573161872922, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "bsadkhin", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", @@ -120,22 +120,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:50631/3/1", - "kbase_id": "50631/3/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Escherichia coli K-12 MG1655 yqiK-rfaE intergenic region, genomic sequence correction", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Workshop on Annotation of Escherichia coli K-12", "The complete genome sequence of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], "taxonomy": ["Proteobacteria; Gammaproteobacteria; Enterobacterales; Enterobacteriaceae; Escherichia; Escherichia coli", "; Escherichia coli K-12"] } }, { + "id": "WS::48753:1", "object_name": "Narrative.1585596681448", - "access_group": 48753, - "obj_id": 1, - "version": 7, + "workspace_id": 48753, + "object_id": 1, + "object_version": 7, "timestamp": 1586539905964, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "eapearson", "data": { "narrative_title": "RE landing page sample links", @@ -174,20 +173,19 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:48753/1/1", - "kbase_id": "48753/1/1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["Taxonomy Landing Pages\nThe ubiquitous E. coli...", "identifier for the specific item to be viewed; the form of the id depends on the collection,e.g. 562 is E. coli", "search to find taxonomic entities:\njson\n{\n \"params\": [{\n \"ns\": \"gtdb\",\n \"search_text\": \"coli", "GB_GCA_900481195.1\",\n \"last_version\": \"r89\",\n \"name\": \"Escherichia coli", "RS_GCF_002548945.1\",\n \"last_version\": \"r89\",\n \"name\": \"Escherichia coli"] } }, { + "id": "WS::45320:4", "object_name": "ecoli_2contigs_orig", - "access_group": 45320, - "obj_id": 4, - "version": 4, + "workspace_id": 45320, + "object_id": 4, + "object_version": 4, "timestamp": 1574124911386, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "genome_id": "ecoli_2contigs_orig", @@ -234,10 +232,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:45320/4/1", "kbase_id": "45320/4/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["A manual approach to accurate translation start site annotation: an E. coli K-12 case study", "The complete genome sequence of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Workshop on Annotation of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -245,11 +242,11 @@ } }, { "object_name": "small_genbank__test_batch_sub_dir_1", - "access_group": 45320, - "obj_id": 5, - "version": 1, + "workspace_id": 45320, + "object_id": 5, + "object_version": 1, "timestamp": 1549683737483, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "tgu2", "data": { "genome_id": "small_genbank__test_batch_sub_dir_1", @@ -295,10 +292,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:45320/5/1", - "kbase_id": "45320/5/1", + "id": "WS::45320:5", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["A manual approach to accurate translation start site annotation: an E. coli K-12 case study", "The complete genome sequence of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Workshop on Annotation of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -306,11 +302,11 @@ } }, { "object_name": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", - "access_group": 44783, - "obj_id": 3, - "version": 1, + "workspace_id": 44783, + "object_id": 3, + "object_version": 1, "timestamp": 1573159884255, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "bsadkhin", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", @@ -356,10 +352,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44783/3/1", - "kbase_id": "44783/3/1", + "id": "WS::44783:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["The complete genome sequence of Escherichia coli K-12", "Workshop on Annotation of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -367,11 +362,11 @@ } }, { "object_name": "Escherichia_coli", - "access_group": 44697, - "obj_id": 3, - "version": 1, + "workspace_id": 44697, + "object_id": 3, + "object_version": 1, "timestamp": 1527549837859, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_002163935.1", @@ -415,20 +410,19 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44697/3/1", - "kbase_id": "44697/3/1", + "id": "WS::44697:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Escherichia coli"] } }, { "object_name": "Ecoli_go_term", - "access_group": 44640, - "obj_id": 9, - "version": 1, + "workspace_id": 44640, + "object_id": 9, + "object_version": 1, "timestamp": 1572897735244, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "luj", "data": { "genome_id": "Ecoli_go_term", @@ -474,10 +468,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44640/9/1", - "kbase_id": "44640/9/1", + "id": "WS::44640:9", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -485,11 +478,11 @@ } }, { "object_name": "Ecoli_go_term2", - "access_group": 44640, - "obj_id": 12, - "version": 1, + "workspace_id": 44640, + "object_id": 12, + "object_version": 1, "timestamp": 1573105778886, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "bsadkhin", "data": { "genome_id": "Ecoli_go_term2", @@ -535,10 +528,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44640/12/1", - "kbase_id": "44640/12/1", + "id": "WS::44640:12", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -546,11 +538,11 @@ } }, { "object_name": "Ecoli_go", - "access_group": 44640, - "obj_id": 3, - "version": 1, + "workspace_id": 44640, + "object_id": 3, + "object_version": 1, "timestamp": 1572672656546, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "bsadkhin", "data": { "genome_id": "Ecoli_go", @@ -596,10 +588,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:44640/3/1", - "kbase_id": "44640/3/1", + "id": "WS::44640:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -607,11 +598,11 @@ } }, { "object_name": "Narrative.1569012281066", - "access_group": 44150, - "obj_id": 1, - "version": 15, + "workspace_id": 44150, + "object_id": 1, + "object_version": 15, "timestamp": 1582215852059, - "type": "Narrative", + "workspace_type_name": "Narrative", "creator": "eapearson", "data": { "narrative_title": "Relation Engine (RE) Landing Page Demo", @@ -653,20 +644,19 @@ "obj_type_module": "KBaseNarrative", "index_runner_ver": "1.9.17" }, - "guid": "WS:44150/1/1", - "kbase_id": "44150/1/1", + "id": "WS::44150:1", "index_name": "narrative_2", - "type_ver": 0, + "index_version": 0, "highlight": { "cells.desc": ["The E. coli in the data panel to is actually linked from the \"E. coli\" taxon landing page you can get", "Genome Landing Page\n\nE. coli refdata\nThis link leads to a Genome landing page which shows the lineage"] } }, { "object_name": "GCF_000005845.2", - "access_group": 42557, - "obj_id": 2, - "version": 1, + "workspace_id": 42557, + "object_id": 2, + "object_version": 1, "timestamp": 1484680259109, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "qzhang", "data": { "genome_id": "GCF_000005845.2", @@ -699,10 +689,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:42557/2/1", - "kbase_id": "42557/2/1", + "id": "WS::42557:2", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "Workshop on Annotation of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -710,11 +699,11 @@ } }, { "object_name": "GCF_000005845.2.RAST", - "access_group": 42557, - "obj_id": 3, - "version": 1, + "workspace_id": 42557, + "object_id": 3, + "object_version": 1, "timestamp": 1556576383612, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "filipeliu", "data": { "genome_id": "GCF_000005845.2.RAST", @@ -752,10 +741,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:42557/3/1", - "kbase_id": "42557/3/1", + "id": "WS::42557:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "Workshop on Annotation of Escherichia coli K-12", "ASAP: Escherichia coli K-12 strain MG1655 version m56", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -763,11 +751,11 @@ } }, { "object_name": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", - "access_group": 39819, - "obj_id": 2, - "version": 6, + "workspace_id": 39819, + "object_id": 2, + "object_version": 6, "timestamp": 1548276078101, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jjeffryes", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", @@ -813,10 +801,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:39819/2/1", - "kbase_id": "39819/2/1", + "id": "WS::39819:2", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["Escherichia coli K-12 MG1655 yqiK-rfaE intergenic region, genomic sequence correction", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -824,11 +811,11 @@ } }, { "object_name": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", - "access_group": 39218, - "obj_id": 3, - "version": 1, + "workspace_id": 39218, + "object_id": 3, + "object_version": 1, "timestamp": 1547241468826, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jjeffryes", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic.gbff_genome", @@ -874,10 +861,9 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:39218/3/1", - "kbase_id": "39218/3/1", + "id": "WS::39218:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], @@ -885,11 +871,11 @@ } }, { "object_name": "Prokka_genome", - "access_group": 37649, - "obj_id": 3, - "version": 1, + "workspace_id": 37649, + "object_id": 3, + "object_version": 1, "timestamp": 1543271602030, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jjeffryes", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic", @@ -935,22 +921,22 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:37649/3/1", - "kbase_id": "37649/3/1", + "id": "WS::37649:3", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], "taxonomy": ["Proteobacteria; Gammaproteobacteria; Enterobacterales; Enterobacteriaceae; Escherichia; Escherichia coli", "; Escherichia coli K-12"] } }, { + "id": "WS::37649:2", "object_name": "GCF_000005845.2_ASM584v2_genomic", - "access_group": 37649, - "obj_id": 2, - "version": 1, + "workspace_id": 37649, + "object_id": 2, + "object_version": 1, "timestamp": 1522766145529, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jjeffryes", "data": { "genome_id": "GCF_000005845.2_ASM584v2_genomic", @@ -996,22 +982,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:37649/2/1", - "kbase_id": "37649/2/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], "taxonomy": ["Proteobacteria; Gammaproteobacteria; Enterobacterales; Enterobacteriaceae; Escherichia; Escherichia coli", "; Escherichia coli K-12"] } }, { + "id": "WS::37649:5", "object_name": "Rast_genome", - "access_group": 37649, - "obj_id": 5, - "version": 1, + "workspace_id": 37649, + "object_id": 5, + "object_version": 1, "timestamp": 1543294049109, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jjeffryes", "data": { "genome_id": "Rast_genome", @@ -1050,22 +1035,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:37649/5/1", - "kbase_id": "37649/5/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], "taxonomy": ["Proteobacteria; Gammaproteobacteria; Enterobacterales; Enterobacteriaceae; Escherichia; Escherichia coli", "; Escherichia coli K-12"] } }, { + "id": "WS::33192:21", "object_name": "Ecoli_go_term", - "access_group": 33192, - "obj_id": 21, - "version": 1, + "workspace_id": 33192, + "object_id": 21, + "object_version": 1, "timestamp": 1572897735244, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "luj", "data": { "genome_id": "Ecoli_go_term", @@ -1111,22 +1095,21 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:33192/21/1", - "kbase_id": "33192/21/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "publication_titles": ["ASAP: Escherichia coli K-12 strain MG1655 version m56", "Workshop on Annotation of Escherichia coli K-12", "Escherichia coli K-12: a cooperatively developed annotation snapshot--2005", "Highly accurate genome sequences of Escherichia coli K-12 strains MG1655 and W3110", "The complete genome sequence of Escherichia coli K-12"], "scientific_name": ["Escherichia coli str. K-12 substr. MG1655"], "taxonomy": ["Proteobacteria; Gammaproteobacteria; Enterobacterales; Enterobacteriaceae; Escherichia; Escherichia coli", "; Escherichia coli K-12"] } }, { + "id": "WS::33192:34", "object_name": "GCF_004368345.1", - "access_group": 33192, - "obj_id": 34, - "version": 2, + "workspace_id": 33192, + "object_id": 34, + "object_version": 2, "timestamp": 1578704620951, - "type": "Genome", + "workspace_type_name": "Genome", "creator": "jayrbolton", "data": { "genome_id": "GCF_004368345.1", @@ -1171,10 +1154,8 @@ "obj_type_module": "KBaseGenomes", "index_runner_ver": "1.9.17" }, - "guid": "WS:33192/34/1", - "kbase_id": "33192/34/1", "index_name": "genome_2", - "type_ver": 0, + "index_version": 0, "highlight": { "scientific_name": ["Campylobacter coli"] } diff --git a/tests/unit/es_client/test_es_client.py b/tests/unit/es_client/test_es_client.py index c431d0b..6dc1144 100644 --- a/tests/unit/es_client/test_es_client.py +++ b/tests/unit/es_client/test_es_client.py @@ -119,7 +119,7 @@ def test_search_unknown_index(services): with patch('src.es_client.query.ws_auth') as mocked: mocked.return_value = [0, 1] # Public workspaces idx_name = 'xyz' - full_name = config['index_prefix'] + '_' + idx_name + full_name = config['index_prefix'] + config['prefix_delimiter'] + idx_name params = {'indexes': [idx_name]} with pytest.raises(UnknownIndex) as ctx: search(params, {'auth': None}) diff --git a/tests/unit/search1_conversion/test_search1_convert_params.py b/tests/unit/search1_conversion/test_search1_convert_params.py index 5798b18..333a784 100644 --- a/tests/unit/search1_conversion/test_search1_convert_params.py +++ b/tests/unit/search1_conversion/test_search1_convert_params.py @@ -260,7 +260,7 @@ def test_search_types_valid(): def test_get_objects_valid(): params = { - 'guids': ['x', 'y'] + 'ids': ['x', 'y'] } expected = { 'query': {'terms': {'_id': ['x', 'y']}} diff --git a/tests/unit/search1_conversion/test_search1_convert_result.py b/tests/unit/search1_conversion/test_search1_convert_result.py index 5e322a8..98c80bc 100644 --- a/tests/unit/search1_conversion/test_search1_convert_result.py +++ b/tests/unit/search1_conversion/test_search1_convert_result.py @@ -177,11 +177,11 @@ def test_get_object_data_from_search_results_feature(): 'hits': [{ 'highlight': {'name': 'name1'}, 'doc': { - 'access_group': 1, + 'workspace_id': 1, 'creator': 'username', - 'obj_id': 2, - 'obj_name': 'object2', - 'version': 1, + 'object_id': 2, + 'object_name': 'object2', + 'object_version': 1, 'obj_type_name': 'Module.Type-1.0', 'timestamp': 0, 'name': 'name1', @@ -192,11 +192,10 @@ def test_get_object_data_from_search_results_feature(): }] } post_processing = { - } result = convert_result._get_object_data_from_search_results(results, post_processing) assert isinstance(result, list) [obj_data] = result assert isinstance(obj_data, dict) - assert 'type' in obj_data - assert obj_data['type'] == 'GenomeFeature' + assert 'workspace_type_name' in obj_data + assert obj_data['workspace_type_name'] == 'GenomeFeature' diff --git a/tests/unit/search1_rpc/test_search1_rpc.py b/tests/unit/search1_rpc/test_search1_rpc.py index 38352bb..f068b12 100644 --- a/tests/unit/search1_rpc/test_search1_rpc.py +++ b/tests/unit/search1_rpc/test_search1_rpc.py @@ -53,7 +53,7 @@ def test_get_objects_valid(services): "id": 0, "params": [ { - 'guids': ['public-doc1'], + 'ids': ['public-doc1'], 'post_processing': {'ids_only': 1}, } ], @@ -98,7 +98,7 @@ def test_get_objects_bad_auth(services): "version": "1.1", "params": [ { - 'guids': ['public-doc1'], + 'ids': ['public-doc1'], 'post_processing': {'ids_only': 1}, } ], diff --git a/tests/unit/server/test_server.py b/tests/unit/server/test_server.py index c07c28a..bab5012 100644 --- a/tests/unit/server/test_server.py +++ b/tests/unit/server/test_server.py @@ -28,7 +28,7 @@ def test_get_auth_auth_fail_resp(services): data=json.dumps({ "version": "1.1", "method": "KBaseSearchEngine.get_objects", - "params": [{"guids": ["xyz"]}], + "params": [{"ids": ["xyz"]}], }) ) result = resp.json() @@ -89,7 +89,7 @@ def test_legacy_valid(services): "id": 0, "method": "KBaseSearchEngine.get_objects", "params": [{ - "guids": ['xyz'] + "ids": ['xyz'] }] }) ) @@ -162,7 +162,7 @@ def test_legacy_rpc_conversion(services): "id": 0, "method": "KBaseSearchEngine.get_objects", "params": [{ - "guids": ['xyz'] + "ids": ['xyz'] }] }) ) From 4241d12ec445a964553be9f58ff83bec8fa60b40 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 14 Apr 2021 14:29:16 -0700 Subject: [PATCH 06/21] Fix json-rpc version for legacy endpoint doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20676ce..25dc5fd 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Show the names of all indexes, and show what aliases stand for what indexes. ### /legacy -A JSON-RPC 2.0 API that mimics the legacy Java server, [found here](https://github.com/kbase/KBaseSearchEngin://github.com/kbase/KBaseSearchEngine). Refer to the `src/search1_rpc/schemas` file for a reference on the method parameter types. +A JSON-RPC 1.1 API that mimics the legacy Java server, [found here](https://github.com/kbase/KBaseSearchEngin://github.com/kbase/KBaseSearchEngine). Refer to the `src/search1_rpc/schemas` file for a reference on the method parameter types. ## Development From 48ecefc1091f4978167ecc8e05a6bca03f86db5e Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 15:57:36 -0700 Subject: [PATCH 07/21] remove genomefeature integration tests --- .../search_objects/case-07-request.json | 30 - .../search_objects/case-07-response.json | 18 - .../data/legacy/search_objects/case-07.md | 1 - .../search_objects/case-08-request.json | 47 - .../search_objects/case-08-response.json | 984 ------------------ .../data/legacy/search_objects/case-08.md | 1 - .../integration/test_legacy_search_objects.py | 22 - 7 files changed, 1103 deletions(-) delete mode 100644 tests/integration/data/legacy/search_objects/case-07-request.json delete mode 100644 tests/integration/data/legacy/search_objects/case-07-response.json delete mode 100644 tests/integration/data/legacy/search_objects/case-07.md delete mode 100644 tests/integration/data/legacy/search_objects/case-08-request.json delete mode 100644 tests/integration/data/legacy/search_objects/case-08-response.json delete mode 100644 tests/integration/data/legacy/search_objects/case-08.md diff --git a/tests/integration/data/legacy/search_objects/case-07-request.json b/tests/integration/data/legacy/search_objects/case-07-request.json deleted file mode 100644 index af9cc63..0000000 --- a/tests/integration/data/legacy/search_objects/case-07-request.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "id": "17499051636214047", - "method": "KBaseSearchEngine.search_objects", - "params": [{ - "access_filter": { - "with_private": 1, - "with_public": 1 - }, - "match_filter": { - "exclude_subobjects": 0, - "full_text_in_all": "coli", - "source_tags": [], - "source_tags_blacklist": 0 - }, - "object_types": ["GenomeFeature"], - "pagination": { - "count": 0, - "start": 0 - }, - "post_processing": { - "add_access_group_info": 0, - "ids_only": 1, - "include_highlight": 0, - "skip_data": 1, - "skip_info": 1, - "skip_keys": 1 - } - }], - "version": "1.1" -} \ No newline at end of file diff --git a/tests/integration/data/legacy/search_objects/case-07-response.json b/tests/integration/data/legacy/search_objects/case-07-response.json deleted file mode 100644 index 4690c74..0000000 --- a/tests/integration/data/legacy/search_objects/case-07-response.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "1.1", - "id": "17499051636214047", - "result": [{ - "pagination": { - "start": 0, - "count": 0 - }, - "sorting_rules": [{ - "property": "timestamp", - "is_object_property": 0, - "ascending": 1 - }], - "objects": [], - "total": 94222799, - "search_time": 355 - }] -} \ No newline at end of file diff --git a/tests/integration/data/legacy/search_objects/case-07.md b/tests/integration/data/legacy/search_objects/case-07.md deleted file mode 100644 index d97806e..0000000 --- a/tests/integration/data/legacy/search_objects/case-07.md +++ /dev/null @@ -1 +0,0 @@ -# About case 7 \ No newline at end of file diff --git a/tests/integration/data/legacy/search_objects/case-08-request.json b/tests/integration/data/legacy/search_objects/case-08-request.json deleted file mode 100644 index 3654918..0000000 --- a/tests/integration/data/legacy/search_objects/case-08-request.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "id": "2328138435664152", - "method": "KBaseSearchEngine.search_objects", - "params": [{ - "access_filter": { - "with_private": 1, - "with_public": 1 - }, - "match_filter": { - "exclude_subobjects": 0, - "full_text_in_all": "coli", - "source_tags": [], - "source_tags_blacklist": 0 - }, - "object_types": ["GenomeFeature"], - "pagination": { - "count": 20, - "start": 0 - }, - "post_processing": { - "add_access_group_info": 1, - "ids_only": 0, - "include_highlight": 1, - "skip_data": 0, - "skip_info": 0, - "skip_keys": 0 - }, - "sorting_rules": [{ - "ascending": 1, - "is_object_property": 1, - "property": "genome_scientific_name" - }, { - "ascending": 1, - "is_object_property": 0, - "property": "guid" - }, { - "ascending": 1, - "is_object_property": 1, - "property": "feature_type" - }, { - "ascending": 1, - "is_object_property": 1, - "property": "id" - }] - }], - "version": "1.1" -} \ No newline at end of file diff --git a/tests/integration/data/legacy/search_objects/case-08-response.json b/tests/integration/data/legacy/search_objects/case-08-response.json deleted file mode 100644 index e5ec64e..0000000 --- a/tests/integration/data/legacy/search_objects/case-08-response.json +++ /dev/null @@ -1,984 +0,0 @@ -{ - "version": "1.1", - "result": [{ - "pagination": { - "count": 20, - "start": 0 - }, - "sorting_rules": [{ - "ascending": 1, - "is_object_property": 1, - "property": "genome_scientific_name" - }, { - "ascending": 1, - "is_object_property": 0, - "property": "guid" - }, { - "ascending": 1, - "is_object_property": 1, - "property": "feature_type" - }, { - "ascending": 1, - "is_object_property": 1, - "property": "id" - }], - "total": 16249124, - "search_time": 1764, - "objects": [{ - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260", - "feature_type": "gene", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7"], - "sequence_length": 2644, - "assembly_ref": "15792:235088:2", - "starts": [9460918], - "strands": ["+"], - "stops": [2644], - "aliases": [ - ["protein_id", "NP_001324995.1"], - ["protein_id", "NP_001325000.1"], - ["locus_tag", "AT2G22260"], - ["protein_id", "NP_001324998.1"], - ["protein_id", "NP_001324997.1"], - ["protein_id", "NP_001324999.1"], - ["protein_id", "NP_001324994.1"], - ["protein_id", "NP_001324996.1"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["gene", "ALKBH2"], - ["protein_id", "NP_001324993.1"], - ["protein_id", "NP_565530.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_1", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1044, - "assembly_ref": "15792:235088:2", - "starts": [9461125, 9461313, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+", "+"], - "stops": [70, 74, 65, 112, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324997.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_2", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 945, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001325000.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_3", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 945, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324998.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_4", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 945, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324999.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_5", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 945, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_565530.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_6", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 774, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 219], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324994.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_7", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 774, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 219], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324995.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_8", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 774, - "assembly_ref": "15792:235088:2", - "starts": [9461342, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+"], - "stops": [45, 65, 112, 216, 117, 219], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324996.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_CDS_9", - "feature_type": "CDS", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 894, - "assembly_ref": "15792:235088:2", - "starts": [9461647, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+"], - "stops": [171, 216, 117, 193, 197], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["protein_id", "NP_001324993.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_1", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1825, - "assembly_ref": "15792:235088:2", - "starts": [9460918, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [469, 65, 112, 216, 117, 193, 653], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335786.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_2", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1715, - "assembly_ref": "15792:235088:2", - "starts": [9460918, 9461305, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+", "+"], - "stops": [277, 82, 65, 112, 216, 117, 193, 653], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335788.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_3", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1752, - "assembly_ref": "15792:235088:2", - "starts": [9460918, 9461305, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [232, 82, 65, 112, 216, 117, 928], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335787.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_4", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1670, - "assembly_ref": "15792:235088:2", - "starts": [9460918, 9461305, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+", "+", "+", "+"], - "stops": [232, 82, 65, 112, 216, 117, 193, 653], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_127792.4"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_5", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1594, - "assembly_ref": "15792:235088:2", - "starts": [9460918, 9461305, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857, 9463152], - "strands": ["+", "+", "+", "+", "+", "+", "+", "+", "+"], - "stops": [232, 82, 65, 112, 216, 117, 193, 219, 358], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335789.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_6", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1552, - "assembly_ref": "15792:235088:2", - "starts": [9460995, 9461313, 9461472, 9461706, 9461931, 9462385, 9462582, 9462857, 9463152], - "strands": ["+", "+", "+", "+", "+", "+", "+", "+", "+"], - "stops": [200, 74, 65, 112, 216, 117, 193, 219, 356], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335790.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_7", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1795, - "assembly_ref": "15792:235088:2", - "starts": [9461082, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+"], - "stops": [305, 65, 112, 216, 117, 980], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335791.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_8", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1685, - "assembly_ref": "15792:235088:2", - "starts": [9461082, 9461305, 9461472, 9461706, 9461931, 9462385, 9462582], - "strands": ["+", "+", "+", "+", "+", "+", "+"], - "stops": [113, 82, 65, 112, 216, 117, 980], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335792.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT2G22260_mRNA_9", - "feature_type": "mrna", - "functions": ["oxidoreductase, 2OG-Fe(II) oxygenase family protein"], - "contig_ids": ["NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7", "NC_003071.7"], - "sequence_length": 1365, - "assembly_ref": "15792:235088:2", - "starts": [9461630, 9461931, 9462385, 9462582, 9462857], - "strands": ["+", "+", "+", "+", "+"], - "stops": [188, 216, 117, 193, 651], - "aliases": [ - ["gene", "ALKBH2"], - ["locus_tag", "AT2G22260"], - ["gene_synonym", "homolog of E. coli alkB; T26C19.8; T26C19_8"], - ["transcript_id", "NM_001335793.1"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }, { - "object_name": "GCF_000001735.4", - "workspace_id": 15792, - "object_id": 235089, - "workspace_version": 2, - "timestamp": 1593555698230, - "workspace_type_name": "Genome", - "creator": "jayrbolton", - "data": { - "id": "AT3G51790", - "feature_type": "gene", - "functions": ["transmembrane protein G1P-related 1"], - "contig_ids": ["NC_003074.8"], - "sequence_length": 1335, - "assembly_ref": "15792:235088:2", - "starts": [19210849], - "strands": ["-"], - "stops": [1335], - "aliases": [ - ["protein_id", "NP_190747.1"], - ["gene_synonym", "A. thaliana homolog of E. coli CcmE; AtCCME; ATG1; transmembrane protein G1P-related 1"], - ["gene", "G1"], - ["locus_tag", "AT3G51790"] - ], - "parent_id": "WS::15792:235089", - "genome_version": 2, - "genome_scientific_name": "Arabidopsis thaliana", - "genome_taxonomy": "cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina; Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida; Mesangiospermae; eudicotyledons; Gunneridae; Pentapetalae; rosids; malvids; Brassicales; Brassicaceae; Camelineae; Arabidopsis", - "genome_source": "RefSeq", - "genome_source_id": "NC_003070", - "genome_size": 119668634, - "genome_num_contigs": 7, - "genome_feature_count": 27562, - "genome_gc_content": 0.36, - "shared_users": ["qzhang", "jayrbolton", "scanonadmin", "kbasedata", "kbaseindexer"], - "creation_date": "2020-01-29T02:05:09+0000", - "is_public": true, - "copied": null, - "tags": ["refdata"], - "obj_type_version": "17.0", - "obj_type_module": "KBaseGenomes" - }, - "guid": "WS:15792/235089/1", - "kbase_id": "15792/235089/1", - "index_name": "genome_features_2", - "index_version": 0, - "highlight": {} - }], - "access_groups_info": { - "15792": [15792, "ReferenceDataManager", "qzhang", "2020-10-09T23:46:00+0000", 274292, "n", "r", "unlocked", { - "searchtags": "refdata", - "refdata_source": "NCBI RefSeq" - }] - } - }], - "id": "2328138435664152" -} \ No newline at end of file diff --git a/tests/integration/data/legacy/search_objects/case-08.md b/tests/integration/data/legacy/search_objects/case-08.md deleted file mode 100644 index c5926bd..0000000 --- a/tests/integration/data/legacy/search_objects/case-08.md +++ /dev/null @@ -1 +0,0 @@ -# Case 8 Description \ No newline at end of file diff --git a/tests/integration/test_legacy_search_objects.py b/tests/integration/test_legacy_search_objects.py index d516938..cd29a5b 100644 --- a/tests/integration/test_legacy_search_objects.py +++ b/tests/integration/test_legacy_search_objects.py @@ -33,28 +33,6 @@ def test_search_example3(service): assert len(res['objects']) > 0 -def test_search_example4(service): - """Genome features count with no data""" - request_data = load_data_file('search_objects', 'case-07-request.json') - response_data = load_data_file('search_objects', 'case-07-response.json') - url = service['app_url'] + '/legacy' - res = do_rpc(url, request_data, response_data) - assert res['total'] > 0 - assert res['search_time'] > 0 - - -def test_search_example5(service): - """Genome features search with results""" - request_data = load_data_file('search_objects', 'case-08-request.json') - response_data = load_data_file('search_objects', 'case-08-response.json') - url = service['app_url'] + '/legacy' - res = do_rpc(url, request_data, response_data) - assert_equal_results(res, response_data['result'][0]) - assert len(res['objects']) > 0 - assert res['total'] > 0 - assert res['search_time'] > 0 - - def test_search_objects_private(service): """Search over private data""" if 'WS_TOKEN' not in os.environ: From c5959f9a46852681880858a5bc237546a4f3ee70 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:07:43 -0700 Subject: [PATCH 08/21] fix legacy response go use the proper content type --- src/server/__main__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/__main__.py b/src/server/__main__.py index 7825955..f30a9a4 100644 --- a/src/server/__main__.py +++ b/src/server/__main__.py @@ -57,7 +57,9 @@ async def legacy(request): return sanic.response.raw(b'', status=405) auth = request.headers.get('Authorization') result = legacy_service.call(request.body, {'auth': auth}) - return sanic.response.text(result) + return sanic.response.raw( + bytes(result, 'utf-8'), + headers={'content-type': 'application/json'}) @app.middleware('response') From 194faabb886d60f940616e3f98c1f099829bf8fc Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:17:26 -0700 Subject: [PATCH 09/21] changes to legacy search conversion: meta renamed ctx, since referred to as the "context" (but just passes auth token around); missing access group throw error does not silently succeed; missing profile throws error does not silently succeed; fix dates to be uniform epoch ms; improve (make more uniform and understandable) result keys; refactor key mapping, copying, transformation, exclusion - the old logic was difficult to trace; --- src/search1_conversion/convert_result.py | 219 +++++++++++++++-------- 1 file changed, 149 insertions(+), 70 deletions(-) diff --git a/src/search1_conversion/convert_result.py b/src/search1_conversion/convert_result.py index 95d2929..ecb3ed0 100644 --- a/src/search1_conversion/convert_result.py +++ b/src/search1_conversion/convert_result.py @@ -1,24 +1,55 @@ from src.utils.config import config -from src.utils.formatting import iso8601_to_epoch +from src.utils.formatting import iso8601_to_epoch_ms from src.utils.user_profiles import get_user_profiles from src.utils.workspace import get_workspace_info -import logging +from src.exceptions import NoAccessGroupError, NoUserProfileError -logger = logging.getLogger('search2') +# TODO: The structure of the ES docs and of the API's result +# data should be documented in detail outside of this file, with a +# reference here. -# Mappings from search2 document fields to search1 fields: -_KEY_MAPPING = { +# Mappings from search2 document fields to search1 fields. +_GLOBAL_DOC_KEY_MAPPING = { 'obj_name': 'object_name', 'access_group': 'workspace_id', 'obj_id': 'object_id', 'version': 'object_version', - 'timestamp': 'timestamp', + 'obj_type_module': 'workspace_type_module', 'obj_type_name': 'workspace_type_name', - 'creator': 'creator' + 'obj_type_version': 'workspace_type_version', + 'timestamp': 'modified_at' } +# These keys are copied over literally without renaming +# keys or transformation +_GLOBAL_DOC_KEY_COPYING = [ + 'creator', + 'copied' +] -def search_objects(params: dict, results: dict, meta: dict): +# These keys are copied from the result "hit", not "hit.doc" as +# above. +_GLOBAL_HIT_KEY_COPYING = [ + 'id' +] + +# These keys are to be neither mapped nor copied, but when copying the rest of the +# doc fields into the data field, should be excluded, or omitted. +_GLOBAL_DOC_KEY_EXCLUSION = [ + 'is_public', + 'shared_users', + 'tags', + 'index_runner_ver' +] + +# Similar to excluded fields, these fields are transformed and copied in code below +# (see the "# Transforms" comment) and should be ignored when copying into the data field. +_GLOBAL_DOC_KEY_TRANSFORMS = [ + 'creation_date' +] + + +def search_objects(params: dict, results: dict, ctx: dict): """ Convert Elasticsearch results into the RPC results conforming to the "search_objects" method @@ -32,30 +63,33 @@ def search_objects(params: dict, results: dict, meta: dict): 'search_time': results['search_time'], 'objects': objects, } - _add_access_group_info(ret, results, meta, post_processing) - _add_objects_and_info(ret, results, meta, post_processing) + _add_access_group_info(ret, results, ctx, post_processing) + _add_objects_and_info(ret, results, ctx, post_processing) + return ret -def search_types(params, results, meta): +def search_types(_params, results, _ctx): """ - Convert Elasticsearch results into RPC results conforming to the spec for - the "search_types" method. + Convert Elasticsearch results into RPC results conforming to the + "search_types" method. """ - # Now we need to convert the ES result format into the API format + # Convert the ES result format into the API format search_time = results['search_time'] - buckets = results['aggregations']['type_count']['counts'] - counts_dict = {} # type: dict - for count_obj in buckets: - counts_dict[count_obj['key']] = counts_dict.get(count_obj['key'], 0) - counts_dict[count_obj['key']] += count_obj['count'] + type_counts = results['aggregations']['type_count']['counts'] + type_to_count = {} # type: dict + + for type_count in type_counts: + key = type_count['key'] + count = type_count['count'] + type_to_count[key] = count return { - 'type_to_count': counts_dict, + 'type_to_count': type_to_count, 'search_time': int(search_time) } -def get_objects(params, results, meta): +def get_objects(params, results, ctx): """ Convert Elasticsearch results into RPC results conforming to the spec for the "get_objects" method. @@ -64,8 +98,8 @@ def get_objects(params, results, meta): ret = { 'search_time': results['search_time'], } - _add_access_group_info(ret, results, meta, post_processing) - _add_objects_and_info(ret, results, meta, post_processing) + _add_access_group_info(ret, results, ctx, post_processing) + _add_objects_and_info(ret, results, ctx, post_processing) return ret @@ -82,21 +116,21 @@ def _get_post_processing(params: dict) -> dict: return pp -def _add_objects_and_info(ret: dict, search_results: dict, meta: dict, post_processing: dict): +def _add_objects_and_info(ret: dict, search_results: dict, ctx: dict, post_processing: dict): """ Populate the fields for `objects`. Args: ret: final method result object (mutated) search_results: return value from es_client.query.search - meta: RPC meta object (contains auth token) + ctx: RPC context object (contains auth token) post_processing: some query options pulled from the RPC method params """ objects = _get_object_data_from_search_results(search_results, post_processing) ret['objects'] = objects -def _add_access_group_info(ret: dict, search_results: dict, meta: dict, post_processing: dict): +def _add_access_group_info(ret: dict, search_results: dict, ctx: dict, post_processing: dict): """ Populate the fields for `access_group_narrative_info` and/or `access_groups_info` depending on keys from the `post_processing` field. @@ -105,31 +139,36 @@ def _add_access_group_info(ret: dict, search_results: dict, meta: dict, post_pro Args: ret: final method result object (mutated) search_results: return value from es_client.query.search - meta: RPC meta object (contains auth token) + ctx: RPC context object (contains auth token) post_processing: some query options pulled from the RPC method params """ fetch_narratives = post_processing.get('add_narrative_info') == 1 fetch_ws_infos = post_processing.get('add_access_group_info') == 1 if fetch_narratives or fetch_ws_infos: - (ws_infos, narrative_infos) = _fetch_narrative_info(search_results, meta) + (ws_infos, narrative_infos) = _fetch_narrative_info(search_results, ctx) if fetch_narratives: ret['access_group_narrative_info'] = narrative_infos if fetch_ws_infos: ret['access_groups_info'] = ws_infos -def _fetch_narrative_info(results, meta): +def _fetch_narrative_info(es_result, ctx): """ - For each result object, we construct a single bulk query to ES that fetches - the narrative data. We then construct that data into a "narrative_info" - tuple, which contains: (narrative_name, object_id, time_last_saved, - owner_username, owner_displayname) Returns a dictionary of workspace_id - mapped to the narrative_info tuple above. + Returns a to mappings of workspaces, each keyed on the workspace id: + - a subset of workspace info as returned by the workspace: + (id, name, owner, save_date, max_objid, user_perm, global_perm, + lockstat, metadata) + - a subset of narrative info for workspaces which are narratives, a tuple + of selected values: + (narrative title, object id, workspace modification timestamp, + owner username, owner realname) + + The reason for the duplication is historical, not intentional design. + One day we will rectify this. - This also returns a dictionary of workspace infos for each object: (id, name, owner, save_date, max_objid, user_perm, global_perm, lockstat, metadata) """ - hit_docs = [hit['doc'] for hit in results['hits']] + hit_docs = [hit['doc'] for hit in es_result['hits']] workspace_ids = set() ws_infos = {} owners = set() @@ -138,7 +177,7 @@ def _fetch_narrative_info(results, meta): # results for hit_doc in hit_docs: if 'access_group' not in hit_doc: - continue + raise NoAccessGroupError() workspace_id = hit_doc['access_group'] workspace_ids.add(workspace_id) @@ -146,34 +185,32 @@ def _fetch_narrative_info(results, meta): return {}, {} for workspace_id in workspace_ids: - workspace_info = get_workspace_info(workspace_id, meta['auth']) + workspace_info = get_workspace_info(workspace_id, ctx['auth']) if len(workspace_info) > 2: owners.add(workspace_info[2]) ws_infos[str(workspace_id)] = workspace_info # Get profile for all owners in the search results - user_profiles = get_user_profiles(list(owners), meta['auth']) + owner_list = list(owners) + user_profiles = get_user_profiles(owner_list, ctx['auth']) user_profile_map = {} - for profile in user_profiles: - if profile is not None: - username = profile['user']['username'] - user_profile_map[username] = profile + for index, profile in enumerate(user_profiles): + if profile is None: + raise NoUserProfileError(owner_list[index]) + username = profile['user']['username'] + user_profile_map[username] = profile # Get all the source document objects for each narrative result narr_infos = {} for ws_info in ws_infos.values(): [workspace_id, _, owner, moddate, _, _, _, _, ws_metadata] = ws_info user_profile = user_profile_map.get(owner) - if user_profile is not None: - real_name = user_profile['user']['realname'] - else: - # default to real name if the user profile is absent. - real_name = owner + real_name = user_profile['user']['realname'] if 'narrative' in ws_metadata: narr_infos[str(workspace_id)] = [ ws_metadata.get('narrative_nice_name', ''), int(ws_metadata.get('narrative')), - iso8601_to_epoch(moddate) * 1000, + iso8601_to_epoch_ms(moddate), owner, real_name ] @@ -188,45 +225,87 @@ def _get_object_data_from_search_results(search_results, post_processing): """ # TODO post_processing/skip_info,skip_keys,skip_data -- look at results in current api # TODO post_processing/ids_only -- look at results in current api + object_data = [] # type: list # Keys found in every ws object for hit in search_results['hits']: doc = hit['doc'] obj: dict = {} - for (search2_key, search1_key) in _KEY_MAPPING.items(): + + # Copy fields from the "hit" to the result "object". + for key in _GLOBAL_HIT_KEY_COPYING: + obj[key] = hit.get(key) + + # Simple key mapping from the doc to the object. + # The mapping transforms the raw keys from the ES result into + # friendlier keys expected by the API. + # Defined at top of file. + global_doc_keys = [] + for (search2_key, search1_key) in _GLOBAL_DOC_KEY_MAPPING.items(): + global_doc_keys.append(search2_key) obj[search1_key] = doc.get(search2_key) - # The nested 'data' is all object-specific, so exclude all global keys - # TODO: what if an object index happens to use a key that overlaps with - # global keys? Shouldn't they be completely independent? - obj_data = {key: doc[key] for key in doc if key not in _KEY_MAPPING} - if post_processing.get('skip_data') != 1: - obj['data'] = obj_data - obj['id'] = hit['id'] + # Even simpler key mapping - no key substitution + for key in _GLOBAL_DOC_KEY_COPYING: + global_doc_keys.append(key) + obj[key] = doc.get(key) + + # Transforms + obj['created_at'] = iso8601_to_epoch_ms((doc['creation_date'])) - # Extracts the index name. + # The index name from the external pov is unqualified and + # unversioned; it is equivalent to the index alias, and + # symmetric with any parameters which limit searches by + # index. + # The form of object indexes is: + # NAMESPACE.INDEXNAME_VERSION + # (why different separators for prefix and suffix?) + # e.g. search2.genome_2 + # We are interested in the INDEXNAME and VERSION, + # although there is no need for clients to know the version + # it may be useful for diagnostics. idx_pieces = hit['index'].split(config['suffix_delimiter']) idx_name = idx_pieces[0] - idx_ver = int(idx_pieces[1] or 0) if len(idx_pieces) == 2 else 0 + # TODO: we should not default to 0, but rather raise an + # error. All indexes involved should be namespaced. + idx_ver = int(idx_pieces[1] or 0) if len(idx_pieces) == 2 else 0 obj['index_name'] = idx_name obj['index_version'] = idx_ver - # Set defaults for required fields in objects/data - # Set some more top-level data manually that we use in the UI + # Funny Business + # Always set object_name as a string type + # TODO: how can this ever be missing? It is simply impossible, every + # object has a name and a type. + obj['object_name'] = obj.get('object_name') or '' + obj['workspace_type_name'] = obj.get('workspace_type_name') or '' + + # The nested 'data' is all object-specific, so exclude all global keys + # The indexed doc mixes global keys and index-specific ones. + # The search1 api separated them, so this transformation respects that. + obj_data = {key: doc[key] for key in doc if key not in global_doc_keys + and key not in _GLOBAL_DOC_KEY_EXCLUSION + and key not in _GLOBAL_DOC_KEY_TRANSFORMS} + + if post_processing.get('skip_data') != 1: + obj['data'] = obj_data + + # Highlights are mappings of key to a formatted string + # derived from the field with "hit" terms highlighted with + # html. + # These fields may be any field in the indexed doc, which + # mixes global and index-specific fields. + # We need to transform the keys, if the GLOBAL_KEY_MAPPING + # so deems; otherwise we use the keys directly. + # TODO: improvements needed here; not all search terms are highlighted + # as a result of this transform, which results in a confusing message + # on the front end. if post_processing.get('include_highlight') == 1: highlight = hit.get('highlight', {}) transformed_highlight = {} for key, value in highlight.items(): - transformed_highlight[_KEY_MAPPING.get(key, key)] = value + transformed_highlight[_GLOBAL_DOC_KEY_MAPPING.get(key, key)] = value obj['highlight'] = transformed_highlight - # Always set object_name as a string type - # TODO: how can this ever be missing? - obj['object_name'] = obj.get('object_name') or '' - obj['workspace_type_name'] = obj.get('workspace_type_name') or '' - # For the UI, make the type field "GenomeFeature" instead of "Genome". - # TODO: the handling of sub-objects needs to be redesigned. - if 'genome_feature_type' in doc: - obj['workspace_type_name'] = 'GenomeFeature' + object_data.append(obj) return object_data From ffd04ebd12b6ebb4a94a7f204cc270502709483f Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:19:02 -0700 Subject: [PATCH 10/21] Remove hard-coded genome feature support; currently features are not indexed (at least no uniformly) and not supported in the user search tools; if features or subobjects should return to general search, it should be a generic feature without hardcoding of types. --- src/search1_conversion/convert_params.py | 47 +++++++++--------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/search1_conversion/convert_params.py b/src/search1_conversion/convert_params.py index 5e7e815..40e62ba 100644 --- a/src/search1_conversion/convert_params.py +++ b/src/search1_conversion/convert_params.py @@ -33,15 +33,10 @@ entirety. Longer fields are shown as snippets preceded or followed by "...". """ -from src.utils.config import config + from src.utils.obj_utils import get_any from jsonrpc11base.errors import InvalidParamsError -# Unversioned feature index name/alias, (eg "genome_features") -_FEATURES_UNVERSIONED = config['global']['genome_features_current_index_name'] -# Versioned feature index name (eg "genome_features_2") -_GENOME_FEATURES_IDX_NAME = config['global']['latest_versions'][_FEATURES_UNVERSIONED] - # Mapping of special sorting properties names from the Java API to search2 key names _SORT_PROP_MAPPING = { 'scientific_name': 'scientific_name.raw', @@ -99,7 +94,6 @@ def search_types(params): with_all_history - ignored output: type_to_count - dict where keys are type names and vals are counts - search_time - int - total time performing search This method constructs the same search parameters as `search_objects`, but aggregates results based on `obj_type_name`. """ @@ -119,17 +113,12 @@ def get_objects(params): Convert params from the "get_objects" RPC method into an Elasticsearch query. Retrieve a list of objects based on their upas. params: - ids - list of string - KBase IDs (upas) to fetch - post_processing - object of post-query filters (see PostProcessing def at top of this module) + ids - list of string - Search document ids to fetch; ids are in a specific + format for object indexes: "WS:::" output: - objects - list of ObjectData - see the ObjectData type description in the module docstring above. - search_time - int - time it took to perform the search on ES - access_group_narrative_info - dict of {access_group_id: narrative_info} - - Information about the workspaces in which the objects in the - results reside. This data only applies to workspace objects. + query - elasticsearch query for document ids specified in the params argument """ - query = {'query': {'terms': {'_id': params['ids']}}} - return query + return {'query': {'terms': {'_id': params['ids']}}} def _get_search_params(params): @@ -179,10 +168,13 @@ def _get_search_params(params): } }) else: - raise InvalidParamsError(message="Invalid timestamp range in match_filter/timestamp") + raise InvalidParamsError( + message="Invalid timestamp range in match_filter/timestamp") - # Handle a search on tags, which corresponds to the generic `tags` field in all indexes. - # search_tags is populated on a workspace to indicate the type of workspace. Currently + # Handle a search on tags, which corresponds to the generic `tags` field in all + # indexes. + # search_tags is populated on a workspace to indicate the type of workspace. + # Currently # supported are "narrative", "refseq", and "noindex" if match_filter.get('source_tags'): # If source_tags_blacklist is `1`, then we are **excluding** these tags. @@ -202,11 +194,9 @@ def _get_search_params(params): object_types = params.get('object_types', []) if object_types: # For this fake type, we search on the specific index instead (see lower down). - type_blacklist = ['GenomeFeature'] query['bool']['filter']['bool']['should'] = [ {'term': {'obj_type_name': obj_type}} for obj_type in object_types - if obj_type not in type_blacklist ] # Translate with_private and with_public to only_private and only_public. @@ -238,9 +228,9 @@ def _get_search_params(params): # Handle sorting options if 'sorting_rules' not in params: params['sorting_rules'] = [{ - "property": "timestamp", - "is_object_property": 0, - "ascending": 1 + "property": "timestamp", + "is_object_property": 0, + "ascending": 1 }] sort = [] # type: list for sort_rule in params['sorting_rules']: @@ -280,20 +270,19 @@ def _get_search_params(params): 'track_total_hits': True } - if 'GenomeFeature' in object_types: - search_params['indexes'] = [_GENOME_FEATURES_IDX_NAME] - return search_params def _handle_lookup_in_keys(match_filter, query): """ Handle the match_filter/lookup_in_keys option from the legacy API. - This allows the user to pass a number of field names and term or range values for filtering. + This allows the user to pass a number of field names and term or range values for + filtering. """ if not match_filter.get('lookup_in_keys'): return query - # This will be a dict where each key is a field name and each val is a MatchValue type + # This will be a dict where each key is a field name and each val is a MatchValue + # type lookup_in_keys = match_filter['lookup_in_keys'] for (key, match_value) in lookup_in_keys.items(): # match_value will be a dict with one of these keys set: From 2122ab6a24e44ba9502779b8b3d34e34ce773cd4 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:22:19 -0700 Subject: [PATCH 11/21] iso8601 to epoch time now in ms; previously it was in seconds and converted to ms elsewhere --- src/utils/formatting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/formatting.py b/src/utils/formatting.py index cbe955b..bafec12 100644 --- a/src/utils/formatting.py +++ b/src/utils/formatting.py @@ -1,5 +1,5 @@ from datetime import datetime -def iso8601_to_epoch(time_string): - return round(datetime.strptime(time_string, '%Y-%m-%dT%H:%M:%S%z').timestamp()) +def iso8601_to_epoch_ms(time_string): + return round(datetime.strptime(time_string, '%Y-%m-%dT%H:%M:%S%z').timestamp() * 1000) From 9c5c80a5984f197625b77461e9df60e33ddbdb6e Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:24:14 -0700 Subject: [PATCH 12/21] add additional errors - No user profile, No access group (workspace id) --- src/exceptions.py | 55 +++++++++++++------ .../legacy/search_types/case-01/params.json | 22 ++++++++ 2 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/params.json diff --git a/src/exceptions.py b/src/exceptions.py index dc17c02..406e246 100644 --- a/src/exceptions.py +++ b/src/exceptions.py @@ -1,6 +1,8 @@ from src.utils.obj_utils import get_path +# TODO: we should use the jsonrpc11base libraries base exception for +# server errors class ResponseError(Exception): def __init__(self, code=-32000, message='Server error'): @@ -8,23 +10,28 @@ def __init__(self, code=-32000, message='Server error'): self.jsonrpc_code = code -class UnknownType(ResponseError): +class AuthError(ResponseError): - def __init__(self, message) -> object: - super().__init__(code=-32005, message=message) + def __init__(self, auth_resp_json, resp_text): + # Extract the error message from the auth service's RPC response + msg = get_path(auth_resp_json, ['error', 'message']) + if msg is None: + # Fall back to the full response body + msg = resp_text + super().__init__(code=-32001, message=msg) -class ElasticsearchError(ResponseError): +class UnknownIndex(ResponseError): def __init__(self, message): - msg = f"Elasticsearch request error:\n{message}" - super().__init__(code=-32003, message=msg) + super().__init__(code=-32002, message=message) -class UnknownIndex(ResponseError): +class ElasticsearchError(ResponseError): def __init__(self, message): - super().__init__(code=-32002, message=message) + msg = f"Elasticsearch request error:\n{message}" + super().__init__(code=-32003, message=msg) class UserProfileError(ResponseError): @@ -36,12 +43,28 @@ def __init__(self, url, resp_text): super().__init__(code=-32004, message=msg) -class AuthError(ResponseError): +class UnknownType(ResponseError): - def __init__(self, resp_json, resp_text): - # Extract the error message from the RPC response - msg = get_path(resp_json, ['error', 'message']) - if msg is None: - # Fall back to the full response body - msg = resp_text - super().__init__(code=-32001, message=msg) + def __init__(self, message) -> object: + super().__init__(code=-32005, message=message) + + +class NoAccessGroupError(ResponseError): + """ + Raised when a search result does not contain an "access_group" + key, which should be impossible. + """ + + def __init__(self): + message = 'A search document does not contain an access group' + super().__init__(code=-32006, message=message) + + +class NoUserProfileError(ResponseError): + """ + Raised when a username does not have an associated user profile. + """ + + def __init__(self, username): + message = f'A user profile could not be found for "{username}"' + super().__init__(code=-32007, message=message) diff --git a/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/params.json b/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/params.json new file mode 100644 index 0000000..6701ac8 --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/params.json @@ -0,0 +1,22 @@ +{ + "match_filter": { + "full_text_in_all": "Prochlorococcus marinus str. GP2", + "exclude_subobjects": 1, + "source_tags": [ + "refdata", + "noindex" + ], + "source_tags_blacklist": 1 + }, + "access_filter": { + "with_private": 1, + "with_public": 1 + }, + "sorting_rules": [ + { + "property": "timestamp", + "is_object_property": 0, + "ascending": 1 + } + ] +} \ No newline at end of file From 247291e6553f0e1f22479e539e8a7afeafb79df8 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:26:24 -0700 Subject: [PATCH 13/21] expand testing; add service api mocks; trim out obsolete tests --- src/utils/user_profiles.py | 2 +- tests/helpers/unit_setup.py | 10 + tests/unit/es_client/test_es_client.py | 4 +- tests/unit/mocks/data/README.md | 15 + .../legacy/get_objects/case-02/params.json | 14 + .../legacy/get_objects/case-02/request.json | 21 ++ .../legacy/get_objects/case-02/result.json | 142 ++++++++ .../legacy/search_objects/case-01/params.json | 40 +++ .../search_objects/case-01/request.json | 47 +++ .../legacy/search_objects/case-01/result.json | 196 +++++++++++ .../legacy/search_types/case-01/result.json | 7 + .../UserProfile/get_profile/kbaseuitest.json | 109 ++++++ .../Workspace/get_object_info3/56638_2_1.json | 22 ++ .../get_workspace_info/10056638.json | 17 + .../Workspace/get_workspace_info/56638.json | 17 + .../legacy/get_objects/case-02/result.json | 147 ++++++++ .../legacy/search_objects/case-01/result.json | 167 +++++++++ .../legacy/search_types/case-01/result.json | 21 ++ tests/unit/mocks/mocked.py | 189 +++++++++++ tests/unit/search1_conversion/__init__.py | 0 tests/unit/search1_conversion/data.py | 12 +- .../test_search1_convert_params.py | 9 +- .../test_search1_convert_result.py | 318 ++++++++---------- tests/unit/utils/test_formatting.py | 15 + 24 files changed, 1345 insertions(+), 196 deletions(-) create mode 100644 tests/unit/mocks/data/README.md create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/params.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/request.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/result.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/params.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/request.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/result.json create mode 100644 tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/result.json create mode 100644 tests/unit/mocks/data/UserProfile/get_profile/kbaseuitest.json create mode 100644 tests/unit/mocks/data/Workspace/get_object_info3/56638_2_1.json create mode 100644 tests/unit/mocks/data/Workspace/get_workspace_info/10056638.json create mode 100644 tests/unit/mocks/data/Workspace/get_workspace_info/56638.json create mode 100644 tests/unit/mocks/data/elasticsearch/legacy/get_objects/case-02/result.json create mode 100644 tests/unit/mocks/data/elasticsearch/legacy/search_objects/case-01/result.json create mode 100644 tests/unit/mocks/data/elasticsearch/legacy/search_types/case-01/result.json create mode 100644 tests/unit/mocks/mocked.py create mode 100644 tests/unit/search1_conversion/__init__.py create mode 100644 tests/unit/utils/test_formatting.py diff --git a/src/utils/user_profiles.py b/src/utils/user_profiles.py index 7783c44..cc2b894 100644 --- a/src/utils/user_profiles.py +++ b/src/utils/user_profiles.py @@ -5,7 +5,7 @@ from src.exceptions import UserProfileError -def get_user_profiles(usernames: list, auth_token): +def get_user_profiles(usernames: list, auth_token=None): """ Get a list of workspace IDs that the given username is allowed to access in the workspace. diff --git a/tests/helpers/unit_setup.py b/tests/helpers/unit_setup.py index bf2ed5d..773c843 100644 --- a/tests/helpers/unit_setup.py +++ b/tests/helpers/unit_setup.py @@ -3,6 +3,8 @@ from src.utils.wait_for_service import wait_for_service from src.utils.logger import logger from . import common +import json +import os container_process = None @@ -11,6 +13,14 @@ stop_timeout = 30 +def load_data_file(name): + """Load the json test data file with the given name from ./data/legacy """ + file_path = os.path.join(os.path.dirname(__file__), '../unit/data', name) + logger.info(f'loading data file from "{file_path}"') + with open(file_path) as f: + return json.load(f) + + def start_service(wait_for_url, wait_for_name): global container_process global container_out diff --git a/tests/unit/es_client/test_es_client.py b/tests/unit/es_client/test_es_client.py index 6dc1144..f66db61 100644 --- a/tests/unit/es_client/test_es_client.py +++ b/tests/unit/es_client/test_es_client.py @@ -62,8 +62,8 @@ def test_search_aggs_valid(services): result = search(params, {'auth': None}) assert result['count'] == 4 assert result['aggregations']['count_by_index']['counts'] == [ - {'key': 'test_index1', 'count': 2}, - {'key': 'test_index2', 'count': 2}, + {'key': 'test.index1', 'count': 2}, + {'key': 'test.index2', 'count': 2}, ] diff --git a/tests/unit/mocks/data/README.md b/tests/unit/mocks/data/README.md new file mode 100644 index 0000000..8a11132 --- /dev/null +++ b/tests/unit/mocks/data/README.md @@ -0,0 +1,15 @@ +Data for mocks + +Generally all mock described herein uses a query for "Prochlorococcus marinus str. GP2". For search_objects and search_types, a query generated by the data-search ui was used as the basis. For get_objects a hand-crafted query was created with the same post_processing. + +Each case includes the initial request, the params, the elasticsearch result, the prepared result, and the api response. + +All test data is in JSON, stored in *.json files. + +Each test data file is located in a directory named after the service, and for the api, a subdirectory for the method. + +Data files use the naming convention -.json, where is 'case-01', 'case-02', etc., and usage is one of 'request', 'params', 'result', or 'response'. + +case-01: A default public + private search, with all post processing additions enabled, no result parts disabled, via the data-search interface with search query for "Prochlorococcus marinus str. GP2". + +case-02: Designed for get_objects, using the ids returned by case-01. \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/params.json b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/params.json new file mode 100644 index 0000000..23dfda1 --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/params.json @@ -0,0 +1,14 @@ +{ + "ids": [ + "WS::56638:2", + "WS::56638:1" + ], + "post_processing": { + "ids_only": 0, + "skip_info": 0, + "skip_keys": 0, + "skip_data": 0, + "include_highlight": 1, + "add_narrative_info": 1 + } +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/request.json b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/request.json new file mode 100644 index 0000000..f78657a --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/request.json @@ -0,0 +1,21 @@ +{ + "params": [ + { + "ids": [ + "WS::56638:2", + "WS::56638:1" + ], + "post_processing": { + "ids_only": 0, + "skip_info": 0, + "skip_keys": 0, + "skip_data": 0, + "include_highlight": 1, + "add_narrative_info": 1 + } + } + ], + "method": "KBaseSearchEngine.get_objects", + "version": "1.1", + "id": "12345" +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/result.json b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/result.json new file mode 100644 index 0000000..4c02447 --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/get_objects/case-02/result.json @@ -0,0 +1,142 @@ +{ + "search_time": 91945, + "access_group_narrative_info": { + "56638": [ + "Test Narrative for FeatureSet Integration Test", + 1, + 1605765178000, + "kbaseuitest", + "KBase UI Test User" + ] + }, + "objects": [ + { + "id": "WS::56638:2", + "object_name": "GCF_000759885.1", + "workspace_id": 56638, + "object_id": 2, + "object_version": 1, + "workspace_type_module": "KBaseGenomes", + "workspace_type_name": "Genome", + "workspace_type_version": "14.2", + "modified_at": 1531222570501, + "creator": "kbasedata", + "copied": "15792/64028/2", + "created_at": 1605748053000, + "index_name": "genome", + "index_version": 2, + "data": { + "genome_id": "GCF_000759885.1", + "scientific_name": "Prochlorococcus marinus str. GP2", + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus", + "Direct Submission" + ], + "publication_authors": [ + "Biller,S., Berube,P., Thompson,J., Kelly,L., Roggensack,S., Awad,L., Roache-Johnson,K., Ding,H., Giovannoni,S.J., Moore,L.R. and Chisholm,S.W.", + "Biller,S.J., Berube,P.M., Berta-Thompson,J.W., Kelly,L., Roggensack,S.E., Awad,L., Roache-Johnson,K.H., Ding,H., Giovannoni,S.J., Rocap,G., Moore,L.R. and Chisholm,S.W." + ], + "size": 1624310, + "num_contigs": 11, + "genome_type": null, + "gc_content": 0.31164, + "taxonomy": "cellular organisms; Bacteria; Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus; Prochlorococcus marinus", + "mean_contig_length": 147664.54545454544, + "external_origination_date": "11-Apr-2017", + "original_source_file_name": "GCF_000759885.1_ASM75988v1_genomic.gbff", + "cds_count": 1760, + "feature_count": 1760, + "mrna_count": 0, + "non_coding_feature_count": 89, + "assembly_ref": "15792:64027:2", + "source_id": "NZ_JNAH01000001", + "feature_counts": { + "CDS": 1760, + "gene": 1804, + "ncRNA": 3, + "non-protein_encoding_gene": 44, + "protein_encoding_gene": 1760, + "rRNA": 3, + "regulatory": 1, + "tRNA": 37, + "tmRNA": 1 + }, + "source": "RefSeq", + "warnings": [ + "SUSPECT: CDS EU91_RS03000_CDS_1 has a length of 974 which is not consistent with the length of the translation included (323 amino acids)." + ] + }, + "highlight": {} + }, + { + "id": "WS::56638:1", + "object_name": "Narrative.1605747150690", + "workspace_id": 56638, + "object_id": 1, + "object_version": 13, + "workspace_type_module": "KBaseNarrative", + "workspace_type_name": "Narrative", + "workspace_type_version": "4.0", + "modified_at": 1605765178549, + "creator": "kbaseuitest", + "copied": null, + "created_at": 1605747150000, + "index_name": "narrative", + "index_version": 2, + "data": { + "narrative_title": "Test Narrative for FeatureSet Integration Test", + "is_narratorial": false, + "data_objects": [ + { + "name": "GCF_000759885.1", + "obj_type": "KBaseGenomes.Genome-14.2" + }, + { + "name": "GCF_001766235.1", + "obj_type": "KBaseGenomes.Genome-17.0" + }, + { + "name": "featureset2", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "featureset1", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "mergedfeatureset", + "obj_type": "KBaseCollections.FeatureSet-4.0" + } + ], + "owner": "kbaseuitest", + "modified_at": 1605765178000, + "cells": [ + { + "desc": "Test Narrative for FeatureSet Integration Test.\nTo reproduce:\n\nremove add a markdown cell (this one!), remove the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus marinus str. GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative from their landing pages\ncreate a FeatureSet for each Genome, using Build FeatureSet from Genome\n\nchoose the first 3 features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus \"featureset2\"\n\ncreate another FeatureSet combining these two using \"Merge FeatureSets\"\nin the Description parameter add the text \"merged feature set\", or whatever text you like (it will need to match the integration test.)\nin \"Output FeatureSet Name\" name it \"mergedfeatureset\"\ninsert the merged feature set object into the narrative as the last cell; it should be the 6th cell.\nfinally make the narrative public.\n\n", + "cell_type": "markdown" + }, + { + "desc": "Build FeatureSet from Genome", + "cell_type": "kbase_app" + }, + { + "desc": "Merge FeatureSets - v1.0.1", + "cell_type": "kbase_app" + }, + { + "desc": "kbaseReportView", + "cell_type": "widget" + }, + { + "desc": "mergedfeatureset", + "cell_type": "data" + } + ], + "total_cells": 6, + "static_narrative_saved": null, + "static_narrative_ref": null + }, + "highlight": {} + } + ] +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/params.json b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/params.json new file mode 100644 index 0000000..d7e1e3b --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/params.json @@ -0,0 +1,40 @@ +{ + "match_filter": { + "full_text_in_all": "Prochlorococcus marinus str. GP2", + "exclude_subobjects": 1, + "source_tags": [ + "refdata", + "noindex" + ], + "source_tags_blacklist": 1 + }, + "pagination": { + "start": 0, + "count": 20 + }, + "post_processing": { + "ids_only": 0, + "skip_info": 0, + "skip_keys": 0, + "skip_data": 0, + "include_highlight": 1, + "add_narrative_info": 1, + "add_access_group_info": 1 + }, + "access_filter": { + "with_private": 1, + "with_public": 1 + }, + "sorting_rules": [ + { + "is_object_property": 0, + "property": "access_group_id", + "ascending": 0 + }, + { + "is_object_property": 0, + "property": "type", + "ascending": 1 + } + ] +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/request.json b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/request.json new file mode 100644 index 0000000..002df5f --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/request.json @@ -0,0 +1,47 @@ +{ + "params": [ + { + "match_filter": { + "full_text_in_all": "Prochlorococcus marinus str. GP2", + "exclude_subobjects": 1, + "source_tags": [ + "refdata", + "noindex" + ], + "source_tags_blacklist": 1 + }, + "pagination": { + "start": 0, + "count": 20 + }, + "post_processing": { + "ids_only": 0, + "skip_info": 0, + "skip_keys": 0, + "skip_data": 0, + "include_highlight": 1, + "add_narrative_info": 1, + "add_access_group_info": 1 + }, + "access_filter": { + "with_private": 1, + "with_public": 1 + }, + "sorting_rules": [ + { + "is_object_property": 0, + "property": "access_group_id", + "ascending": 0 + }, + { + "is_object_property": 0, + "property": "type", + "ascending": 1 + } + ] + } + ], + "method": "KBaseSearchEngine.search_objects", + "version": "1.1", + "id": "12345" +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/result.json b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/result.json new file mode 100644 index 0000000..bac190d --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/search_objects/case-01/result.json @@ -0,0 +1,196 @@ +{ + "pagination": { + "start": 0, + "count": 20 + }, + "sorting_rules": [ + { + "is_object_property": 0, + "property": "access_group_id", + "ascending": 0 + }, + { + "is_object_property": 0, + "property": "type", + "ascending": 1 + } + ], + "total": 2, + "search_time": 103122, + "objects": [ + { + "id": "WS::56638:2", + "object_name": "GCF_000759885.1", + "workspace_id": 56638, + "object_id": 2, + "object_version": 1, + "workspace_type_module": "KBaseGenomes", + "workspace_type_name": "Genome", + "workspace_type_version": "14.2", + "modified_at": 1531222570501, + "creator": "kbasedata", + "copied": "15792/64028/2", + "created_at": 1605748053000, + "index_name": "genome", + "index_version": 2, + "data": { + "genome_id": "GCF_000759885.1", + "scientific_name": "Prochlorococcus marinus str. GP2", + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus", + "Direct Submission" + ], + "publication_authors": [ + "Biller,S., Berube,P., Thompson,J., Kelly,L., Roggensack,S., Awad,L., Roache-Johnson,K., Ding,H., Giovannoni,S.J., Moore,L.R. and Chisholm,S.W.", + "Biller,S.J., Berube,P.M., Berta-Thompson,J.W., Kelly,L., Roggensack,S.E., Awad,L., Roache-Johnson,K.H., Ding,H., Giovannoni,S.J., Rocap,G., Moore,L.R. and Chisholm,S.W." + ], + "size": 1624310, + "num_contigs": 11, + "genome_type": null, + "gc_content": 0.31164, + "taxonomy": "cellular organisms; Bacteria; Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus; Prochlorococcus marinus", + "mean_contig_length": 147664.54545454544, + "external_origination_date": "11-Apr-2017", + "original_source_file_name": "GCF_000759885.1_ASM75988v1_genomic.gbff", + "cds_count": 1760, + "feature_count": 1760, + "mrna_count": 0, + "non_coding_feature_count": 89, + "assembly_ref": "15792:64027:2", + "source_id": "NZ_JNAH01000001", + "feature_counts": { + "CDS": 1760, + "gene": 1804, + "ncRNA": 3, + "non-protein_encoding_gene": 44, + "protein_encoding_gene": 1760, + "rRNA": 3, + "regulatory": 1, + "tRNA": 37, + "tmRNA": 1 + }, + "source": "RefSeq", + "warnings": [ + "SUSPECT: CDS EU91_RS03000_CDS_1 has a length of 974 which is not consistent with the length of the translation included (323 amino acids)." + ] + }, + "highlight": { + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus" + ], + "scientific_name": [ + "Prochlorococcus marinus str. GP2" + ], + "taxonomy": [ + "Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus", + "; Prochlorococcus marinus" + ] + } + }, + { + "id": "WS::56638:1", + "object_name": "Narrative.1605747150690", + "workspace_id": 56638, + "object_id": 1, + "object_version": 13, + "workspace_type_module": "KBaseNarrative", + "workspace_type_name": "Narrative", + "workspace_type_version": "4.0", + "modified_at": 1605765178549, + "creator": "kbaseuitest", + "copied": null, + "created_at": 1605747150000, + "index_name": "narrative", + "index_version": 2, + "data": { + "narrative_title": "Test Narrative for FeatureSet Integration Test", + "is_narratorial": false, + "data_objects": [ + { + "name": "GCF_000759885.1", + "obj_type": "KBaseGenomes.Genome-14.2" + }, + { + "name": "GCF_001766235.1", + "obj_type": "KBaseGenomes.Genome-17.0" + }, + { + "name": "featureset2", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "featureset1", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "mergedfeatureset", + "obj_type": "KBaseCollections.FeatureSet-4.0" + } + ], + "owner": "kbaseuitest", + "modified_at": 1605765178000, + "cells": [ + { + "desc": "Test Narrative for FeatureSet Integration Test.\nTo reproduce:\n\nremove add a markdown cell (this one!), remove the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus marinus str. GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative from their landing pages\ncreate a FeatureSet for each Genome, using Build FeatureSet from Genome\n\nchoose the first 3 features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus \"featureset2\"\n\ncreate another FeatureSet combining these two using \"Merge FeatureSets\"\nin the Description parameter add the text \"merged feature set\", or whatever text you like (it will need to match the integration test.)\nin \"Output FeatureSet Name\" name it \"mergedfeatureset\"\ninsert the merged feature set object into the narrative as the last cell; it should be the 6th cell.\nfinally make the narrative public.\n\n", + "cell_type": "markdown" + }, + { + "desc": "Build FeatureSet from Genome", + "cell_type": "kbase_app" + }, + { + "desc": "Merge FeatureSets - v1.0.1", + "cell_type": "kbase_app" + }, + { + "desc": "kbaseReportView", + "cell_type": "widget" + }, + { + "desc": "mergedfeatureset", + "cell_type": "data" + } + ], + "total_cells": 6, + "static_narrative_saved": null, + "static_narrative_ref": null + }, + "highlight": { + "cells.desc": [ + "the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus", + "marinus str.", + "GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative", + "features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus" + ] + } + } + ], + "access_group_narrative_info": { + "56638": [ + "Test Narrative for FeatureSet Integration Test", + 1, + 1605765178000, + "kbaseuitest", + "KBase UI Test User" + ] + }, + "access_groups_info": { + "56638": [ + 56638, + "kbaseuitest:narrative_1605747150690", + "kbaseuitest", + "2020-11-19T05:52:58+0000", + 9, + "a", + "r", + "unlocked", + { + "cell_count": "1", + "narrative_nice_name": "Test Narrative for FeatureSet Integration Test", + "searchtags": "narrative", + "is_temporary": "false", + "narrative": "1" + } + ] + } +} \ No newline at end of file diff --git a/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/result.json b/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/result.json new file mode 100644 index 0000000..675fd6d --- /dev/null +++ b/tests/unit/mocks/data/SearchAPI/legacy/search_types/case-01/result.json @@ -0,0 +1,7 @@ +{ + "type_to_count": { + "Genome": 1, + "Narrative": 1 + }, + "search_time": 2815 +} \ No newline at end of file diff --git a/tests/unit/mocks/data/UserProfile/get_profile/kbaseuitest.json b/tests/unit/mocks/data/UserProfile/get_profile/kbaseuitest.json new file mode 100644 index 0000000..ef61713 --- /dev/null +++ b/tests/unit/mocks/data/UserProfile/get_profile/kbaseuitest.json @@ -0,0 +1,109 @@ +{ + "user": { + "username": "kbaseuitest", + "realname": "KBase UI Test User" + }, + "profile": { + "metadata": { + "createdBy": "userprofile_ui_service", + "created": "2020-01-06T21:48:12.352Z" + }, + "preferences": {}, + "userdata": { + "organization": "", + "department": "", + "affiliations": [ + { + "title": "tester", + "organization": "kbase / lbnl", + "started": 2020, + "ended": 2020 + } + ], + "city": "", + "state": "California", + "postalCode": "", + "country": "", + "researchStatement": "Test user account for ui integration tests.\n\nPlease don't modify the profile.\n\nThis **can** be markdown, but who would know?", + "gravatarDefault": "monsterid", + "avatarOption": "gravatar", + "researchInterests": [ + "Comparative Genomics", + "Genome Annotation", + "Metabolic Modeling", + "Read Processing", + "Sequence Analysis" + ], + "researchInterestsOther": null, + "jobTitleOther": "My job", + "jobTitle": "Other", + "fundingSource": "" + }, + "synced": { + "gravatarHash": "b4d95f8595104614355e6ee9c4c03e3f" + }, + "plugins": { + "data-search": { + "settings": { + "history": { + "search": { + "history": [ + "Prochlorococcus marinus str. GP2", + "Prochlorococcus", + "coli", + "Prochlorococcus marinus", + "marinus", + "sphaeroides", + "abcde12345", + "cooli", + "Prochlorococcus Unconfirmed", + "Prochlorococcus Unconfirmed" + ], + "time": { + "$numberLong": "1618589834094" + } + } + } + } + }, + "jgi-search": { + "settings": { + "history": { + "search": { + "history": [ + "coli" + ], + "time": { + "$numberLong": "1582608583358" + } + } + }, + "jgiDataTerms": { + "agreed": true, + "time": { + "$numberLong": "1580251462454" + } + } + } + }, + "public-search": { + "settings": { + "history": { + "history": [ + "prochlorococcus marinus", + "prochlorococcus marnius", + "AnnotatedMetagenomeAssembly", + "AnnotatedGenomeAssembly", + "coli", + "prochlorococcus unconfirmed", + "prochlorococcus" + ], + "time": { + "$numberLong": "1615932685001" + } + } + } + } + } + } +} diff --git a/tests/unit/mocks/data/Workspace/get_object_info3/56638_2_1.json b/tests/unit/mocks/data/Workspace/get_object_info3/56638_2_1.json new file mode 100644 index 0000000..2c91986 --- /dev/null +++ b/tests/unit/mocks/data/Workspace/get_object_info3/56638_2_1.json @@ -0,0 +1,22 @@ +{ + "infos": [ + [ + 2, + "GCF_000759885.1", + "KBaseGenomes.Genome-14.2", + "2020-11-19T01:07:33+0000", + 1, + "kbaseuitest", + 56638, + "kbaseuitest:narrative_1605747150690", + "eb43f0b7ced19611f02b9dd1599fce05", + 5845963, + null + ] + ], + "paths": [ + [ + "56638/2/1" + ] + ] +} \ No newline at end of file diff --git a/tests/unit/mocks/data/Workspace/get_workspace_info/10056638.json b/tests/unit/mocks/data/Workspace/get_workspace_info/10056638.json new file mode 100644 index 0000000..6bceb46 --- /dev/null +++ b/tests/unit/mocks/data/Workspace/get_workspace_info/10056638.json @@ -0,0 +1,17 @@ +[ + 56638, + "kbaseuitest:narrative_1605747150690", + "kbaseuitestx", + "2020-11-19T05:52:58+0000", + 9, + "a", + "r", + "unlocked", + { + "cell_count": "1", + "narrative_nice_name": "Test Narrative for FeatureSet Integration Test", + "searchtags": "narrative", + "is_temporary": "false", + "narrative": "1" + } +] \ No newline at end of file diff --git a/tests/unit/mocks/data/Workspace/get_workspace_info/56638.json b/tests/unit/mocks/data/Workspace/get_workspace_info/56638.json new file mode 100644 index 0000000..d510402 --- /dev/null +++ b/tests/unit/mocks/data/Workspace/get_workspace_info/56638.json @@ -0,0 +1,17 @@ +[ + 56638, + "kbaseuitest:narrative_1605747150690", + "kbaseuitest", + "2020-11-19T05:52:58+0000", + 9, + "a", + "r", + "unlocked", + { + "cell_count": "1", + "narrative_nice_name": "Test Narrative for FeatureSet Integration Test", + "searchtags": "narrative", + "is_temporary": "false", + "narrative": "1" + } +] \ No newline at end of file diff --git a/tests/unit/mocks/data/elasticsearch/legacy/get_objects/case-02/result.json b/tests/unit/mocks/data/elasticsearch/legacy/get_objects/case-02/result.json new file mode 100644 index 0000000..9740414 --- /dev/null +++ b/tests/unit/mocks/data/elasticsearch/legacy/get_objects/case-02/result.json @@ -0,0 +1,147 @@ +{ + "count": 2, + "hits": [ + { + "index": "genome_2", + "id": "WS::56638:2", + "doc": { + "genome_id": "GCF_000759885.1", + "scientific_name": "Prochlorococcus marinus str. GP2", + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus", + "Direct Submission" + ], + "publication_authors": [ + "Biller,S., Berube,P., Thompson,J., Kelly,L., Roggensack,S., Awad,L., Roache-Johnson,K., Ding,H., Giovannoni,S.J., Moore,L.R. and Chisholm,S.W.", + "Biller,S.J., Berube,P.M., Berta-Thompson,J.W., Kelly,L., Roggensack,S.E., Awad,L., Roache-Johnson,K.H., Ding,H., Giovannoni,S.J., Rocap,G., Moore,L.R. and Chisholm,S.W." + ], + "size": 1624310, + "num_contigs": 11, + "genome_type": null, + "gc_content": 0.31164, + "taxonomy": "cellular organisms; Bacteria; Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus; Prochlorococcus marinus", + "mean_contig_length": 147664.54545454544, + "external_origination_date": "11-Apr-2017", + "original_source_file_name": "GCF_000759885.1_ASM75988v1_genomic.gbff", + "cds_count": 1760, + "feature_count": 1760, + "mrna_count": 0, + "non_coding_feature_count": 89, + "assembly_ref": "15792:64027:2", + "source_id": "NZ_JNAH01000001", + "feature_counts": { + "CDS": 1760, + "gene": 1804, + "ncRNA": 3, + "non-protein_encoding_gene": 44, + "protein_encoding_gene": 1760, + "rRNA": 3, + "regulatory": 1, + "tRNA": 37, + "tmRNA": 1 + }, + "source": "RefSeq", + "warnings": [ + "SUSPECT: CDS EU91_RS03000_CDS_1 has a length of 974 which is not consistent with the length of the translation included (323 amino acids)." + ], + "creator": "kbasedata", + "access_group": 56638, + "obj_name": "GCF_000759885.1", + "shared_users": [ + "kbaseuitest" + ], + "timestamp": 1531222570501, + "creation_date": "2020-11-19T01:07:33+0000", + "is_public": true, + "version": 1, + "obj_id": 2, + "copied": "15792/64028/2", + "tags": [ + "narrative" + ], + "obj_type_version": "14.2", + "obj_type_module": "KBaseGenomes", + "obj_type_name": "Genome", + "index_runner_ver": "1.9.17" + } + }, + { + "index": "narrative_2", + "id": "WS::56638:1", + "doc": { + "narrative_title": "Test Narrative for FeatureSet Integration Test", + "is_narratorial": false, + "data_objects": [ + { + "name": "GCF_000759885.1", + "obj_type": "KBaseGenomes.Genome-14.2" + }, + { + "name": "GCF_001766235.1", + "obj_type": "KBaseGenomes.Genome-17.0" + }, + { + "name": "featureset2", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "featureset1", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "mergedfeatureset", + "obj_type": "KBaseCollections.FeatureSet-4.0" + } + ], + "owner": "kbaseuitest", + "modified_at": 1605765178000, + "cells": [ + { + "desc": "Test Narrative for FeatureSet Integration Test.\nTo reproduce:\n\nremove add a markdown cell (this one!), remove the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus marinus str. GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative from their landing pages\ncreate a FeatureSet for each Genome, using Build FeatureSet from Genome\n\nchoose the first 3 features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus \"featureset2\"\n\ncreate another FeatureSet combining these two using \"Merge FeatureSets\"\nin the Description parameter add the text \"merged feature set\", or whatever text you like (it will need to match the integration test.)\nin \"Output FeatureSet Name\" name it \"mergedfeatureset\"\ninsert the merged feature set object into the narrative as the last cell; it should be the 6th cell.\nfinally make the narrative public.\n\n", + "cell_type": "markdown" + }, + { + "desc": "Build FeatureSet from Genome", + "cell_type": "kbase_app" + }, + { + "desc": "Merge FeatureSets - v1.0.1", + "cell_type": "kbase_app" + }, + { + "desc": "kbaseReportView", + "cell_type": "widget" + }, + { + "desc": "mergedfeatureset", + "cell_type": "data" + } + ], + "creator": "kbaseuitest", + "total_cells": 6, + "static_narrative_saved": null, + "static_narrative_ref": null, + "access_group": 56638, + "obj_name": "Narrative.1605747150690", + "shared_users": [ + "kbaseuitest" + ], + "timestamp": 1605765178549, + "creation_date": "2020-11-19T00:52:30+0000", + "is_public": true, + "version": 13, + "obj_id": 1, + "copied": null, + "tags": [ + "narrative" + ], + "obj_type_version": "4.0", + "obj_type_module": "KBaseNarrative", + "obj_type_name": "Narrative", + "index_runner_ver": "1.9.17" + } + } + ], + "search_time": 91945, + "aggregations": {} +} \ No newline at end of file diff --git a/tests/unit/mocks/data/elasticsearch/legacy/search_objects/case-01/result.json b/tests/unit/mocks/data/elasticsearch/legacy/search_objects/case-01/result.json new file mode 100644 index 0000000..7ae80dd --- /dev/null +++ b/tests/unit/mocks/data/elasticsearch/legacy/search_objects/case-01/result.json @@ -0,0 +1,167 @@ +{ + "count": 2, + "hits": [ + { + "index": "genome_2", + "id": "WS::56638:2", + "doc": { + "genome_id": "GCF_000759885.1", + "scientific_name": "Prochlorococcus marinus str. GP2", + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus", + "Direct Submission" + ], + "publication_authors": [ + "Biller,S., Berube,P., Thompson,J., Kelly,L., Roggensack,S., Awad,L., Roache-Johnson,K., Ding,H., Giovannoni,S.J., Moore,L.R. and Chisholm,S.W.", + "Biller,S.J., Berube,P.M., Berta-Thompson,J.W., Kelly,L., Roggensack,S.E., Awad,L., Roache-Johnson,K.H., Ding,H., Giovannoni,S.J., Rocap,G., Moore,L.R. and Chisholm,S.W." + ], + "size": 1624310, + "num_contigs": 11, + "genome_type": null, + "gc_content": 0.31164, + "taxonomy": "cellular organisms; Bacteria; Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus; Prochlorococcus marinus", + "mean_contig_length": 147664.54545454544, + "external_origination_date": "11-Apr-2017", + "original_source_file_name": "GCF_000759885.1_ASM75988v1_genomic.gbff", + "cds_count": 1760, + "feature_count": 1760, + "mrna_count": 0, + "non_coding_feature_count": 89, + "assembly_ref": "15792:64027:2", + "source_id": "NZ_JNAH01000001", + "feature_counts": { + "CDS": 1760, + "gene": 1804, + "ncRNA": 3, + "non-protein_encoding_gene": 44, + "protein_encoding_gene": 1760, + "rRNA": 3, + "regulatory": 1, + "tRNA": 37, + "tmRNA": 1 + }, + "source": "RefSeq", + "warnings": [ + "SUSPECT: CDS EU91_RS03000_CDS_1 has a length of 974 which is not consistent with the length of the translation included (323 amino acids)." + ], + "creator": "kbasedata", + "access_group": 56638, + "obj_name": "GCF_000759885.1", + "shared_users": [ + "kbaseuitest" + ], + "timestamp": 1531222570501, + "creation_date": "2020-11-19T01:07:33+0000", + "is_public": true, + "version": 1, + "obj_id": 2, + "copied": "15792/64028/2", + "tags": [ + "narrative" + ], + "obj_type_version": "14.2", + "obj_type_module": "KBaseGenomes", + "obj_type_name": "Genome", + "index_runner_ver": "1.9.17" + }, + "highlight": { + "publication_titles": [ + "Genomes of diverse isolates of the marine cyanobacterium Prochlorococcus" + ], + "scientific_name": [ + "Prochlorococcus marinus str. GP2" + ], + "taxonomy": [ + "Terrabacteria group; Cyanobacteria/Melainabacteria group; Cyanobacteria; Synechococcales; Prochloraceae; Prochlorococcus", + "; Prochlorococcus marinus" + ] + } + }, + { + "index": "narrative_2", + "id": "WS::56638:1", + "doc": { + "narrative_title": "Test Narrative for FeatureSet Integration Test", + "is_narratorial": false, + "data_objects": [ + { + "name": "GCF_000759885.1", + "obj_type": "KBaseGenomes.Genome-14.2" + }, + { + "name": "GCF_001766235.1", + "obj_type": "KBaseGenomes.Genome-17.0" + }, + { + "name": "featureset2", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "featureset1", + "obj_type": "KBaseCollections.FeatureSet-4.0" + }, + { + "name": "mergedfeatureset", + "obj_type": "KBaseCollections.FeatureSet-4.0" + } + ], + "owner": "kbaseuitest", + "modified_at": 1605765178000, + "cells": [ + { + "desc": "Test Narrative for FeatureSet Integration Test.\nTo reproduce:\n\nremove add a markdown cell (this one!), remove the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus marinus str. GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative from their landing pages\ncreate a FeatureSet for each Genome, using Build FeatureSet from Genome\n\nchoose the first 3 features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus \"featureset2\"\n\ncreate another FeatureSet combining these two using \"Merge FeatureSets\"\nin the Description parameter add the text \"merged feature set\", or whatever text you like (it will need to match the integration test.)\nin \"Output FeatureSet Name\" name it \"mergedfeatureset\"\ninsert the merged feature set object into the narrative as the last cell; it should be the 6th cell.\nfinally make the narrative public.\n\n", + "cell_type": "markdown" + }, + { + "desc": "Build FeatureSet from Genome", + "cell_type": "kbase_app" + }, + { + "desc": "Merge FeatureSets - v1.0.1", + "cell_type": "kbase_app" + }, + { + "desc": "kbaseReportView", + "cell_type": "widget" + }, + { + "desc": "mergedfeatureset", + "cell_type": "data" + } + ], + "creator": "kbaseuitest", + "total_cells": 6, + "static_narrative_saved": null, + "static_narrative_ref": null, + "access_group": 56638, + "obj_name": "Narrative.1605747150690", + "shared_users": [ + "kbaseuitest" + ], + "timestamp": 1605765178549, + "creation_date": "2020-11-19T00:52:30+0000", + "is_public": true, + "version": 13, + "obj_id": 1, + "copied": null, + "tags": [ + "narrative" + ], + "obj_type_version": "4.0", + "obj_type_module": "KBaseNarrative", + "obj_type_name": "Narrative", + "index_runner_ver": "1.9.17" + }, + "highlight": { + "cells.desc": [ + "the welcome cell\nImport 2 genomes\nin this case, I copied, from RefSeq refdata:\n\nAcetobacter ascendens\nProchlorococcus", + "marinus str.", + "GP2\n\nat the time of writing, the public data search for refseq is broken, so I copied into this narrative", + "features from each genome for the feature set\nname the feature set for Acetobacter \"featureset1\", for Prochlorococcus" + ] + } + } + ], + "search_time": 103122, + "aggregations": {} +} diff --git a/tests/unit/mocks/data/elasticsearch/legacy/search_types/case-01/result.json b/tests/unit/mocks/data/elasticsearch/legacy/search_types/case-01/result.json new file mode 100644 index 0000000..e49cf89 --- /dev/null +++ b/tests/unit/mocks/data/elasticsearch/legacy/search_types/case-01/result.json @@ -0,0 +1,21 @@ +{ + "count": 2, + "hits": [], + "search_time": 2815, + "aggregations": { + "type_count": { + "count_err_upper_bound": 0, + "count_other_docs": 0, + "counts": [ + { + "key": "Genome", + "count": 1 + }, + { + "key": "Narrative", + "count": 1 + } + ] + } + } +} \ No newline at end of file diff --git a/tests/unit/mocks/mocked.py b/tests/unit/mocks/mocked.py new file mode 100644 index 0000000..95754b0 --- /dev/null +++ b/tests/unit/mocks/mocked.py @@ -0,0 +1,189 @@ +import json +import os + + +def get_data(name): + """Load the json test data file with the given name from ./data/legacy """ + + file_path = os.path.join(os.path.dirname(__file__), 'data', name) + if os.path.isfile(file_path): + with open(file_path) as f: + return True, json.load(f) + else: + return False, None + + +def mocked_get_workspace_info(workspace_id, auth_token): + # if auth provided, assume the private workspaces. + found, info = get_data(f'Workspace/get_workspace_info/{workspace_id}.json') + if not found: + return None + + # Variable names taken from workspace spec + [_id, _workspace, _owner, _moddate, _max_objid, user_permission, globalread, + _lockstat, _metadata] = info + if auth_token is not None: + # If authenticated, access is granted if either + # public (globalread) or private (user_permission) is + # not denied ('n') + if globalread != 'n' or user_permission != 'n': + return info + else: + # Without authentication, access is granted only if + # public (globalread) is not denied + if globalread != 'n': + return info + + return None + + +def mocked_get_user_profiles(usernames, token=None): + """ + mocks get_user_profiles in src/utils/user_profiles.py + + :param usernames: + :return: + """ + profiles = [] + for username in usernames: + found, profile = get_data(f'UserProfile/get_profile/{username}.json') + if not found: + profiles.append(None) + else: + profiles.append(profile) + return profiles + + +def handle_get_workspace_info(rpc, auth_token): + workspace_id = rpc['params'][0]['id'] + # if auth provided, assume the private workspaces. + found, info = get_data(f'Workspace/get_workspace_info/{workspace_id}.json') + if not found: + return None + + # Variable names taken from workspace spec + [_id, _workspace, _owner, _moddate, _max_objid, user_permission, globalread, + _lockstat, _metadata] = info + if auth_token is not None: + # If authenticated, access is granted if either + # public (globalread) or private (user_permission) is + # not denied ('n') + if globalread != 'n' or user_permission != 'n': + return info + else: + # Without authentication, access is granted only if + # public (globalread) is not denied + if globalread != 'n': + return info + + return None + + +def handle_get_user_profile(rpc, auth_token): + usernames = rpc['params'][0] + profiles = [] + for username in usernames: + found, profile = get_data(f'UserProfile/get_profile/{username}.json') + if not found: + profiles.append(None) + else: + profiles.append(profile) + return profiles + + +def workspace_call(request): + header = { + 'Content-Type': 'application/json' + } + auth_token = request.headers.get('Authorization') + rpc = json.loads(request.body) + method = rpc['method'] + if auth_token is not None and auth_token == 'bad_token': + return (500, header, json.dumps({ + 'version': '1.1', + 'id': rpc['id'], + 'error': { + 'name': 'JSONRPCError', + 'code': -32001, + 'message': 'INVALID TOKEN' + } + })) + + # TODO: emulate permission denied + + # TODO: support the ws methods we do support + + if method == 'Workspace.get_workspace_info': + result = handle_get_workspace_info(rpc, auth_token) + else: + # TODO: make this correct + return (500, header, json.dumps({ + 'version': '1.1', + 'id': rpc['id'], + 'error': { + 'name': 'JSONRPCError', + 'code': -32601, + 'message': f'Method Not Supported "{method}' + } + })) + + return (200, header, json.dumps({ + 'version': '1.1', + 'id': rpc['id'], + 'result': [result] + })) + + +def error_value(code, message): + return { + 'name': 'JSONRPCError', + 'code': code, + 'message': message + } + + +def error_response(request_rpc, error_value): + header = { + 'Content-Type': 'application/json' + } + return_rpc = { + 'version': '1.1', + 'error': error_value + } + if 'id' in request_rpc: + return_rpc['id'] = request_rpc['id'] + return 500, header, json.dumps(return_rpc) + + +def result_response(request_rpc, result_value): + header = { + 'Content-Type': 'application/json' + } + return_rpc = { + 'version': '1.1', + 'result': result_value + } + if 'id' in request_rpc: + return_rpc['id'] = request_rpc['id'] + return 200, header, json.dumps(return_rpc) + + +def user_profile_call(request): + auth_token = request.headers.get('Authorization') + rpc = json.loads(request.body) + method = rpc['method'] + if auth_token is not None and auth_token == 'bad_token': + return error_response(rpc, error_value(-32001, 'INVALID TOKEN')) + + # TODO: emulate permission denied + + # TODO: support the ws methods we do support + + if method == 'UserProfile.get_user_profile': + result = handle_get_user_profile(rpc, auth_token) + else: + # TODO: make this correct + return error_response(rpc, + error_value(-32601, f'Method Not Supported "{method}')) + + return result_response(rpc, [result]) diff --git a/tests/unit/search1_conversion/__init__.py b/tests/unit/search1_conversion/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/search1_conversion/data.py b/tests/unit/search1_conversion/data.py index 26e31f7..0ef57a2 100644 --- a/tests/unit/search1_conversion/data.py +++ b/tests/unit/search1_conversion/data.py @@ -13,7 +13,7 @@ 'obj_id': 2, 'obj_name': 'object2', 'version': 1, - 'obj_type_name': 'Module.Type-1.0', + 'obj_type_name': 'Type', 'timestamp': 0, 'name': 'name1' }, @@ -28,7 +28,7 @@ 'obj_id': 2, 'obj_name': 'object2', 'version': 1, - 'obj_type_name': 'Module.Type-1.0', + 'obj_type_name': 'Type', 'timestamp': 0, 'name': 'name2' }, @@ -186,7 +186,7 @@ "workspace_id": 1, "object_id": 2, "object_version": 1, - "timestamp": 0, + "modified_at": 0, "workspace_type_name": "Type", "creator": "username", "data": {"name": "name1"}, @@ -200,7 +200,7 @@ "workspace_id": 0, "object_id": 2, "object_version": 1, - "timestamp": 0, + "modified_at": 0, "workspace_type_name": "Type", "creator": "username", "data": {"name": "name2"}, @@ -256,7 +256,7 @@ "workspace_id": 1, "object_id": 2, "object_version": 1, - "timestamp": 0, + "modified_at": 0, "workspace_type_name": "Type", "creator": "username", "data": {"name": "name1"}, @@ -270,7 +270,7 @@ "workspace_id": 0, "object_id": 2, "object_version": 1, - "timestamp": 0, + "modified_at": 0, "workspace_type_name": "Type", "creator": "username", "data": {"name": "name2"}, diff --git a/tests/unit/search1_conversion/test_search1_convert_params.py b/tests/unit/search1_conversion/test_search1_convert_params.py index 333a784..0142b7b 100644 --- a/tests/unit/search1_conversion/test_search1_convert_params.py +++ b/tests/unit/search1_conversion/test_search1_convert_params.py @@ -137,7 +137,8 @@ def test_search_objects_source_tags(): 'query': {'bool': {'must': [{'term': {'tags': 'x'}}, {'term': {'tags': 'y'}}]}}, 'size': 20, 'from': 0, 'sort': [{'timestamp': {'order': 'asc'}}], - 'only_public': False, 'only_private': False, + 'only_public': False, + 'only_private': False, 'track_total_hits': True } query = convert_params.search_objects(params) @@ -152,7 +153,8 @@ def test_search_objects_source_tags_blacklist(): 'query': {'bool': {'must_not': [{'term': {'tags': 'x'}}, {'term': {'tags': 'y'}}]}}, 'size': 20, 'from': 0, 'sort': [{'timestamp': {'order': 'asc'}}], - 'only_public': False, 'only_private': False, + 'only_public': False, + 'only_private': False, 'track_total_hits': True } query = convert_params.search_objects(params) @@ -161,7 +163,7 @@ def test_search_objects_source_tags_blacklist(): def test_search_objects_objtypes(): params = { - 'object_types': ['x', 'y', 'GenomeFeature'] + 'object_types': ['x', 'y'] } expected = { 'query': { @@ -176,7 +178,6 @@ def test_search_objects_objtypes(): } } }, - 'indexes': ['genome_features_2'], 'size': 20, 'from': 0, 'sort': [{'timestamp': {'order': 'asc'}}], 'only_public': False, 'only_private': False, diff --git a/tests/unit/search1_conversion/test_search1_convert_result.py b/tests/unit/search1_conversion/test_search1_convert_result.py index 98c80bc..6dfafed 100644 --- a/tests/unit/search1_conversion/test_search1_convert_result.py +++ b/tests/unit/search1_conversion/test_search1_convert_result.py @@ -1,201 +1,153 @@ -from unittest import mock -import json +import unittest +import responses +from src.exceptions import NoAccessGroupError, NoUserProfileError from src.search1_conversion import convert_result - -from tests.unit.search1_conversion.data import ( - mock_ws_info, - mock_user_profiles, - test_search_results, - expected_search_results, - expected_get_objects, -) - -original_expected = json.dumps(expected_search_results) +from src.utils.config import config +from tests.unit.mocks.mocked import \ + get_data, \ + workspace_call, user_profile_call # TODO test post processing # TODO test the following fields: object_name, obj_id, version, type, creator -def mocked_get_workspace_info(workspace_id, auth_token): - # if auth provided, assume the private workspaces. - info = mock_ws_info.get(str(workspace_id)) - if info is not None: - if auth_token is not None: - # private and public workspaces, if either - # public or user perms are not n (no access) - # can access. - if info[6] != 'n' or info[5] != 'n': - return info - else: - # public workspaces - if info[6] != 'n': - return info - - return None - - -@mock.patch('src.search1_conversion.convert_result.get_workspace_info') -@mock.patch('src.search1_conversion.convert_result.get_user_profiles') -def test_search_objects_valid(get_user_profiles_patched, get_workspace_info_patched, services): - get_workspace_info_patched.side_effect = mocked_get_workspace_info - get_user_profiles_patched.return_value = mock_user_profiles - - params = { - 'post_processing': { - 'add_narrative_info': 1, - 'add_access_group_info': 1, - 'include_highlight': 1, - } - } +class Search1ConversionTest(unittest.TestCase): + @responses.activate + def test_search_objects_valid(self): + responses.add_callback(responses.POST, config['workspace_url'], + callback=workspace_call) + + responses.add_callback(responses.POST, config['user_profile_url'], + callback=user_profile_call) + + # Using case-01 params, ES result and api result. + _found, test_params = get_data( + 'SearchAPI/legacy/search_objects/case-01/params.json') + _found, test_es_search_results = get_data( + 'elasticsearch/legacy/search_objects/case-01/result.json') + _found, test_expected = get_data( + 'SearchAPI/legacy/search_objects/case-01/result.json') + + final = convert_result.search_objects(test_params, test_es_search_results, + {'auth': None}) + + # Remove unwanted comparisons. + del final['search_time'] + del test_expected['search_time'] - final = convert_result.search_objects(params, test_search_results, {'auth': None}) + self.maxDiff = None + self.assertEqual(final, test_expected) - for key in expected_search_results: - assert key in final - assert expected_search_results[key] == final[key], key + @responses.activate + def test_get_objects_valid(self): + responses.add_callback(responses.POST, config['workspace_url'], + callback=workspace_call) + responses.add_callback(responses.POST, config['user_profile_url'], + callback=user_profile_call) -@mock.patch('src.search1_conversion.convert_result.get_workspace_info') -@mock.patch('src.search1_conversion.convert_result.get_user_profiles') -def test_get_objects_valid(get_user_profiles_patched, get_workspace_info_patched, services): - get_workspace_info_patched.side_effect = mocked_get_workspace_info - get_user_profiles_patched.return_value = mock_user_profiles + _found, test_params = get_data( + 'SearchAPI/legacy/get_objects/case-02/params.json') + _found, test_es_search_results = get_data( + 'elasticsearch/legacy/get_objects/case-02/result.json') + _found, test_expected = get_data( + 'SearchAPI/legacy/get_objects/case-02/result.json') - params = { - 'post_processing': { - 'add_narrative_info': 1, - 'add_access_group_info': 1, - 'include_highlight': 1, + final = convert_result.get_objects(test_params, test_es_search_results, {'auth': None}) + self.assertEqual(final, test_expected) + + def test_search_types_valid(self): + _found, test_es_search_results = get_data( + 'elasticsearch/legacy/search_types/case-01/result.json') + _found, test_expected = get_data( + 'SearchAPI/legacy/search_types/case-01/result.json') + + # Not that converting search_types does not require any + # params or context. + final = convert_result.search_types({}, test_es_search_results, {}) + + self.assertEqual(final['type_to_count'], test_expected['type_to_count']) + + def test_fetch_narrative_info_no_hits(self): + results = { + 'hits': [] } - } + ctx = {} + result = convert_result._fetch_narrative_info(results, ctx) + assert len(result) == 2 + assert result[0] == {} + assert result[1] == {} + + # TODO: This condition should not occur in any object index! + def test_fetch_narrative_info_no_access_group(self): + results = { + 'hits': [{ + 'doc': {} + }] + } + with self.assertRaises(NoAccessGroupError): + convert_result._fetch_narrative_info(results, {'auth': None}) + + @responses.activate + def test_fetch_narrative_info_owner_has_profile(self): + responses.add_callback(responses.POST, config['workspace_url'], + callback=workspace_call) - final = convert_result.get_objects(params, test_search_results, {'auth': None}) - for key in expected_get_objects: - assert key in final - assert expected_get_objects[key] == final[key], key + responses.add_callback(responses.POST, config['user_profile_url'], + callback=user_profile_call) + _found, test_es_search_results = get_data( + 'elasticsearch/legacy/search_objects/case-01/result.json') + _found, test_expected = get_data( + 'SearchAPI/legacy/search_objects/case-01/result.json') -def test_search_types_valid(services): - params = { - 'post_processing': { + ctx = { + 'auth': None + } + result = convert_result._fetch_narrative_info(test_es_search_results, ctx) + self.assertEqual(len(result), 2) + + expected_result = test_expected['access_group_narrative_info'] + self.assertEqual(result[1], expected_result) + + @responses.activate + def test_fetch_narrative_info_owner_has_no_profile(self): + responses.add_callback(responses.POST, config['workspace_url'], + callback=workspace_call) + + responses.add_callback(responses.POST, config['user_profile_url'], + callback=user_profile_call) + results = { + 'hits': [{ + 'doc': { + 'access_group': 10056638 + } + }] } - } - test_results = { - 'search_time': 1, - 'hits': [], - 'aggregations': { - 'type_count': { - 'counts': [ - {'key': 'x', 'count': 10}, - {'key': 'y', 'count': 20}, - ] - } + meta = { + 'auth': None } - } - expected = { - "search_time": 1, - "type_to_count": { - 'x': 10, - 'y': 20, - }, - } - final = convert_result.search_types(params, test_results, {'auth': None}) - for key in expected: - assert key in final - assert expected[key] == final[key], key - - -def test_fetch_narrative_info_no_hits(): - results = { - 'hits': [] - } - meta = {} - result = convert_result._fetch_narrative_info(results, meta) - assert len(result) == 2 - assert result[0] == {} - assert result[1] == {} - - -def test_fetch_narrative_info_no_access_group(): - results = { - 'hits': [{ - 'doc': {} - }] - } - meta = {} - result = convert_result._fetch_narrative_info(results, meta) - assert len(result) == 2 - assert result[0] == {} - assert result[1] == {} - - -@mock.patch('src.search1_conversion.convert_result.get_workspace_info') -@mock.patch('src.search1_conversion.convert_result.get_user_profiles') -def test_fetch_narrative_info_owner_has_profile(get_user_profiles_patched, get_workspace_info_patched, services): - get_workspace_info_patched.side_effect = mocked_get_workspace_info - get_user_profiles_patched.return_value = mock_user_profiles - results = { - 'hits': [{ - 'doc': { - 'access_group': 1 - } - }] - } - meta = { - 'auth': None - } - result = convert_result._fetch_narrative_info(results, meta) - assert len(result) == 2 - narrative_info = result[1] - assert narrative_info['1'][4] == 'User Example' - - -@mock.patch('src.search1_conversion.convert_result.get_workspace_info') -@mock.patch('src.search1_conversion.convert_result.get_user_profiles') -def test_fetch_narrative_info_owner_has_no_profile(get_user_profiles_patched, get_workspace_info_patched, services): - get_workspace_info_patched.side_effect = mocked_get_workspace_info - get_user_profiles_patched.return_value = [] - results = { - 'hits': [{ - 'doc': { - 'access_group': 1 - } - }] - } - meta = { - 'auth': None - } - result = convert_result._fetch_narrative_info(results, meta) - assert len(result) == 2 - narrative_info = result[1] - assert narrative_info['1'][4] == 'username' - - -def test_get_object_data_from_search_results_feature(): - results = { - 'hits': [{ - 'highlight': {'name': 'name1'}, - 'doc': { - 'workspace_id': 1, - 'creator': 'username', - 'object_id': 2, - 'object_name': 'object2', - 'object_version': 1, - 'obj_type_name': 'Module.Type-1.0', - 'timestamp': 0, - 'name': 'name1', - 'genome_feature_type': 1 - }, - 'id': 'WS::1:2', - 'index': 'test_index1_1', - }] - } - post_processing = { - } - result = convert_result._get_object_data_from_search_results(results, post_processing) - assert isinstance(result, list) - [obj_data] = result - assert isinstance(obj_data, dict) - assert 'workspace_type_name' in obj_data - assert obj_data['workspace_type_name'] == 'GenomeFeature' + with self.assertRaises(NoUserProfileError) as e: + convert_result._fetch_narrative_info(results, meta) + self.assertEqual(e.exception.message, + 'A user profile could not be found for "kbaseuitestx"') + + def test_get_object_data_from_search_results(self): + responses.add_callback(responses.POST, config['workspace_url'], + callback=workspace_call) + responses.add_callback(responses.POST, config['user_profile_url'], + callback=user_profile_call) + + _found, test_params = get_data( + 'SearchAPI/legacy/search_objects/case-01/params.json') + _found, test_es_search_results = get_data( + 'elasticsearch/legacy/search_objects/case-01/result.json') + _found, test_expected = get_data( + 'SearchAPI/legacy/search_objects/case-01/result.json') + + post_processing = test_params['post_processing'] + converted = convert_result._get_object_data_from_search_results( + test_es_search_results, + post_processing) + self.assertEqual(converted, test_expected['objects']) diff --git a/tests/unit/utils/test_formatting.py b/tests/unit/utils/test_formatting.py new file mode 100644 index 0000000..2e6baf9 --- /dev/null +++ b/tests/unit/utils/test_formatting.py @@ -0,0 +1,15 @@ +import unittest + +from src.utils.formatting import iso8601_to_epoch_ms + + +class UtilsFormattingTest(unittest.TestCase): + def test_iso8601_to_epoch_ms_valid(self): + cases = [ + { + 'input': '1970-01-01T00:00:00Z', + 'expected': 0 + } + ] + for case in cases: + self.assertEqual(iso8601_to_epoch_ms(case['input']), case['expected']) From 754991eb03c53097b680c3296673a7b53f0d603e Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:26:52 -0700 Subject: [PATCH 14/21] schema changes to reflect result key changes --- src/search1_rpc/schemas/types.json | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/search1_rpc/schemas/types.json b/src/search1_rpc/schemas/types.json index 26e3326..0464a59 100644 --- a/src/search1_rpc/schemas/types.json +++ b/src/search1_rpc/schemas/types.json @@ -30,8 +30,11 @@ "object_id", "object_version", "object_name", + "workspace_type_module", "workspace_type_name", - "timestamp", + "workspace_type_version", + "modified_at", + "created_at", "creator", "index_name", "index_version", @@ -53,10 +56,19 @@ "object_name": { "type": "string" }, + "workspace_type_module": { + "type": "string" + }, "workspace_type_name": { "type": "string" }, - "timestamp": { + "workspace_type_version": { + "type": "string" + }, + "modified_at": { + "type": "integer" + }, + "created_at": { "type": "integer" }, "creator": { From 5a5407a9869dbd8464b3768a79505a2defdf3b84 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:27:18 -0700 Subject: [PATCH 15/21] doc changes to reflect new errors --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 25dc5fd..1952966 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,9 @@ The [search configuration file](https://github.com/kbase/index_runner_spec/blob/ * `-32003` - Elasticsearch response error * `-32004` - User profile service response error * `-32005` - Unknown workspace type +* `-32006` - Access group missing +* `-32007` - User profile missing + ### `/rpc` From 7a69102737a249e06e6409a6276232d06287ae48 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Mon, 19 Apr 2021 16:27:27 -0700 Subject: [PATCH 16/21] clarify prerequisites --- docs/ez-guide.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/ez-guide.md b/docs/ez-guide.md index 18e73f5..d81c552 100644 --- a/docs/ez-guide.md +++ b/docs/ez-guide.md @@ -4,6 +4,16 @@ This is a set of tasks which worked well for me on macOS. ## Unit Testing +### Host dependencies + +You will need to have, at a minimum: + +- make +- python 3.7 +- docker + +### Set up python + Install virtual environment for python: ```sh @@ -24,6 +34,8 @@ Unit tests are run locally, so need to install all python dependencies: poetry install ``` +### Run Tests + > TODO: should be able to run unit tests in a container, to avoid the need for any host-level installs. Run the tests! @@ -34,6 +46,12 @@ This will run all the unit tests plus associated code quality evaluations. make test ``` +or for coverage + +```sh +make test-coverage +``` + > Note: Ensure that https://ci.kbase.us is accessible from the host machine; some unit tests require this (and should not be unit tests!) To run tests in a given directory or individual test modules: @@ -55,6 +73,8 @@ See [Integration Testing](integration-testing.md) ## Using with kbase-ui +This workflow is very handy for working on both the search api back end and search tool front ends. + ``` IP="" SSHHOST="login1.berkeley.kbase.us" SSHUSER="" SSHPASS="" make run-dev-server ``` From a1a0231a0d142dfb366ab19f540aaf3ff26b0834 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Tue, 20 Apr 2021 05:54:24 -0700 Subject: [PATCH 17/21] update changelog --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 142d263..01c5984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [1.0.0] - 2021-03-05 +## [1.0.0] - 2021-04-20 ### Fixed - fix SCT-2930: not honoring withPublic and withPrivate - fix SCT-2931: maximum reported search results was 10,000 - fixed to report actual search results with > 10K. @@ -16,9 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - fix SCT-2947: unauthenticated search not working correctly (no ws or narr info) - fix SCT-2969: not honoring object_types - fix SCT-2970: not narrowing search with additional terms +- fix SCT-3001: Data-search ui / Searchapi2 legacy endpoint generates incorrect object landing page links +- fix SCT-3002: Searchpi2 legacy endpoint returns incorrect index and index version ### Added -- implement SCT-2966: add a "build and test" workflow for GitHub Actions which builds an image, runs tests, and pushes the resulting image too GH Container Registry. +- implement SCT-2966: add a "build and test" workflow for GitHub Actions which builds an image, runs tests, and pushes the resulting image to GH Container Registry. ## [0.4.9] - 2020-09-11 ### Changed From e4666562cebcbad44613ce60e6dcc23d05c19e29 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Tue, 20 Apr 2021 10:15:34 -0700 Subject: [PATCH 18/21] simplify naming of make task --- Makefile | 2 +- docs/integration-testing.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 70d6170..1082d6e 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ test: sh scripts/run_tests -build-integration-test-images: +build-dev-images: @echo Building integration test images... sh scripts/build-integration-test-images.sh @echo Integration test images built diff --git a/docs/integration-testing.md b/docs/integration-testing.md index 44df32d..9e77927 100644 --- a/docs/integration-testing.md +++ b/docs/integration-testing.md @@ -7,7 +7,7 @@ The integration tests run inside a Docker container. An associated ssh tunnel pr Although the integration test script will build the images if they are missing, the build can take a few minutes, which may cause the integration test script to time out. It is more reliable to simply build the containers first. ```bash -make build-integration-test-images +make build-dev-images ``` You can view the files `container.out` and `container.err` to monitor progress building the images. From fe6d5f6b88faa265b0909271265ed102383d36dc Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Tue, 20 Apr 2021 15:09:20 -0700 Subject: [PATCH 19/21] remove errant space --- .../data/legacy/search_objects/case-06-response.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/data/legacy/search_objects/case-06-response.json b/tests/integration/data/legacy/search_objects/case-06-response.json index bbe446b..078396c 100644 --- a/tests/integration/data/legacy/search_objects/case-06-response.json +++ b/tests/integration/data/legacy/search_objects/case-06-response.json @@ -1,6 +1,6 @@ { "id": "xyz", - "version": "1.1", + "version": "1.1", "result": [{ "pagination": {"start": 0, "count": 20}, "sorting_rules": [{ From 09007f02a38e3ca36902fb8956d070b5db17ec38 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Tue, 20 Apr 2021 15:10:30 -0700 Subject: [PATCH 20/21] undo doc change --- docs/integration-testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integration-testing.md b/docs/integration-testing.md index 9e77927..44df32d 100644 --- a/docs/integration-testing.md +++ b/docs/integration-testing.md @@ -7,7 +7,7 @@ The integration tests run inside a Docker container. An associated ssh tunnel pr Although the integration test script will build the images if they are missing, the build can take a few minutes, which may cause the integration test script to time out. It is more reliable to simply build the containers first. ```bash -make build-dev-images +make build-integration-test-images ``` You can view the files `container.out` and `container.err` to monitor progress building the images. From 26173ab3f02ba8d55c138a672e85e0983524ed02 Mon Sep 17 00:00:00 2001 From: Erik Pearson Date: Wed, 21 Apr 2021 14:49:29 -0700 Subject: [PATCH 21/21] remove unused parameters from convert_result.search_types, usage, and test. --- src/search1_conversion/convert_result.py | 2 +- src/search1_rpc/service.py | 2 +- tests/unit/search1_conversion/test_search1_convert_result.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/search1_conversion/convert_result.py b/src/search1_conversion/convert_result.py index ecb3ed0..5e864ee 100644 --- a/src/search1_conversion/convert_result.py +++ b/src/search1_conversion/convert_result.py @@ -69,7 +69,7 @@ def search_objects(params: dict, results: dict, ctx: dict): return ret -def search_types(_params, results, _ctx): +def search_types(results: dict): """ Convert Elasticsearch results into RPC results conforming to the "search_types" method. diff --git a/src/search1_rpc/service.py b/src/search1_rpc/service.py index c54d083..2abdf27 100644 --- a/src/search1_rpc/service.py +++ b/src/search1_rpc/service.py @@ -73,7 +73,7 @@ def search_types(params, meta): start = time.time() query = convert_params.search_types(params) search_result = trap_error(lambda: search(query, meta)) - result = convert_result.search_types(params, search_result, meta) + result = convert_result.search_types(search_result) logger.debug(f'Finished search_types in {time.time() - start}s') return [result] diff --git a/tests/unit/search1_conversion/test_search1_convert_result.py b/tests/unit/search1_conversion/test_search1_convert_result.py index 6dfafed..ca083f4 100644 --- a/tests/unit/search1_conversion/test_search1_convert_result.py +++ b/tests/unit/search1_conversion/test_search1_convert_result.py @@ -65,7 +65,7 @@ def test_search_types_valid(self): # Not that converting search_types does not require any # params or context. - final = convert_result.search_types({}, test_es_search_results, {}) + final = convert_result.search_types(test_es_search_results) self.assertEqual(final['type_to_count'], test_expected['type_to_count'])