diff --git a/poetry.lock b/poetry.lock index a7ad678..bc6a667 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "anyio" @@ -1217,13 +1217,13 @@ typing-extensions = ">=4.4" [[package]] name = "pyasn1" -version = "0.5.1" +version = "0.6.0" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.8" files = [ - {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"}, - {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"}, + {file = "pyasn1-0.6.0-py2.py3-none-any.whl", hash = "sha256:cca4bb0f2df5504f02f6f8a775b6e416ff9b0b3b16f7ee80b5a3153d9b804473"}, + {file = "pyasn1-0.6.0.tar.gz", hash = "sha256:3a35ab2c4b5ef98e17dfdec8ab074046fbda76e281c5a706ccd82328cfc8f64c"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index a6fa625..6cb5265 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "geneweaver-api" -version = "0.4.0a7" +version = "0.4.0a9" description = "The Geneweaver API" authors = [ "Alexander Berger ", diff --git a/src/geneweaver/api/controller/genesets.py b/src/geneweaver/api/controller/genesets.py index ee9f3fd..f1c57cb 100644 --- a/src/geneweaver/api/controller/genesets.py +++ b/src/geneweaver/api/controller/genesets.py @@ -6,14 +6,13 @@ from tempfile import TemporaryDirectory from typing import Optional -from fastapi import APIRouter, Depends, HTTPException, Path, Security +from fastapi import APIRouter, Depends, HTTPException, Path, Query, Security from fastapi.responses import FileResponse from geneweaver.api import dependencies as deps from geneweaver.api.schemas.auth import UserInternal from geneweaver.api.services import geneset as genset_service from geneweaver.api.services import publications as publication_service -from geneweaver.core.enum import GeneIdentifier -from geneweaver.db import geneset as db_geneset +from geneweaver.core.enum import GeneIdentifier, GenesetTier, Species from typing_extensions import Annotated from . import message as api_message @@ -25,10 +24,94 @@ def get_visible_genesets( user: UserInternal = Security(deps.full_user), cursor: Optional[deps.Cursor] = Depends(deps.cursor), + gs_id: Annotated[ + Optional[int], + Query( + format="int64", + minimum=0, + maxiumum=9223372036854775807, + description=api_message.GENESET_ID, + ), + ] = None, + only_my_genesets: Annotated[ + Optional[bool], Query(description=api_message.ONLY_MY_GS) + ] = False, + curation_tier: Optional[GenesetTier] = None, + species: Optional[Species] = None, + name: Annotated[Optional[str], Query(description=api_message.NAME)] = None, + abbreviation: Annotated[ + Optional[str], Query(description=api_message.ABBREVIATION) + ] = None, + publication_id: Annotated[ + Optional[int], + Query( + format="int64", + minimum=0, + maxiumum=9223372036854775807, + description=api_message.PUBLICATION_ID, + ), + ] = None, + pubmed_id: Annotated[ + Optional[int], + Query( + format="int64", + minimum=0, + maxiumum=9223372036854775807, + description=api_message.PUBMED_ID, + ), + ] = None, + gene_id_type: Optional[GeneIdentifier] = None, + search_text: Annotated[ + Optional[str], Query(description=api_message.SEARCH_TEXT) + ] = None, + with_publication_info: Annotated[ + bool, Query(description=api_message.ONLY_MY_GS) + ] = True, + limit: Annotated[ + Optional[int], + Query( + format="int64", + minimum=0, + maxiumum=1000, + description=api_message.LIMIT, + ), + ] = 10, + offset: Annotated[ + Optional[int], + Query( + format="int64", + minimum=0, + maxiumum=9223372036854775807, + description=api_message.OFFSET, + ), + ] = None, ) -> dict: """Get all visible genesets.""" - user_genesets = db_geneset.by_owner_id(cursor, user.id) - return {"genesets": user_genesets} + response = genset_service.get_visible_genesets( + cursor=cursor, + user=user, + gs_id=gs_id, + curation_tier=curation_tier, + species=species, + name=name, + abbreviation=abbreviation, + publication_id=publication_id, + pubmed_id=pubmed_id, + gene_id_type=gene_id_type, + search_text=search_text, + with_publication_info=with_publication_info, + only_my_genesets=only_my_genesets, + limit=limit, + offset=offset, + ) + + if "error" in response: + if response.get("message") == api_message.ACCESS_FORBIDDEN: + raise HTTPException(status_code=403, detail=api_message.ACCESS_FORBIDDEN) + else: + raise HTTPException(status_code=500, detail=api_message.UNEXPECTED_ERROR) + + return response @router.get("/{geneset_id}") diff --git a/src/geneweaver/api/controller/message.py b/src/geneweaver/api/controller/message.py index 31c42fe..f823ab7 100644 --- a/src/geneweaver/api/controller/message.py +++ b/src/geneweaver/api/controller/message.py @@ -12,3 +12,11 @@ GENE_PREFERRED = "Whether to search for preferred genes" LIMIT = "The limit of results to return" OFFSET = "The offset of results to return" +GENESET_ID = "Geneset ID" +ONLY_MY_GS = "Show only geneset results owned by this user ID" +NAME = "Show only results with this name" +ABBREVIATION = "Show only results with this abbreviation" +PUBLICATION_ID = "Show only results with this publication ID" +PUBMED_ID = "Show only results with this PubMed ID" +SEARCH_TEXT = "Return genesets that match this search text" +WITH_PUBLICATION = "Include publication info in the return" diff --git a/src/geneweaver/api/services/geneset.py b/src/geneweaver/api/services/geneset.py index 970e555..48c9cda 100644 --- a/src/geneweaver/api/services/geneset.py +++ b/src/geneweaver/api/services/geneset.py @@ -1,18 +1,83 @@ """Service functions for dealing with genesets.""" -from typing import Iterable +from typing import Iterable, Optional from fastapi.logger import logger from geneweaver.api.controller import message from geneweaver.api.schemas.auth import User -from geneweaver.core.enum import GeneIdentifier +from geneweaver.core.enum import GeneIdentifier, GenesetTier, Species from geneweaver.db import gene as db_gene from geneweaver.db import geneset as db_geneset from geneweaver.db import geneset_value as db_geneset_value -from geneweaver.db.geneset import is_readable as db_is_readable from psycopg import Cursor +def get_visible_genesets( + cursor: Cursor, + user: User, + gs_id: Optional[int] = None, + only_my_genesets: Optional[bool] = None, + curation_tier: Optional[GenesetTier] = None, + species: Optional[Species] = None, + name: Optional[str] = None, + abbreviation: Optional[str] = None, + publication_id: Optional[int] = None, + pubmed_id: Optional[int] = None, + gene_id_type: Optional[GeneIdentifier] = None, + search_text: Optional[str] = None, + limit: Optional[int] = None, + offset: Optional[int] = None, + with_publication_info: bool = True, +) -> dict: + """Get genesets from the database. + + :param cursor: A database cursor. + :param gs_id: Show only results with this geneset ID. + :param curation_tier: Show only results of this curation tier. + :param species: Show only results associated with this species. + :param name: Show only results with this name. + :param abbreviation: Show only results with this abbreviation. + :param publication_id: Show only results with this publication ID (internal). + :param pubmed_id: Show only results with this PubMed ID. + :param gene_id_type: Show only results with this gene ID type. + :param search_text: Return genesets that match this search text (using PostgreSQL + full-text search). + :param limit: Limit the number of results. + :param offset: Offset the results. + :param with_publication_info: Include publication info in the return. + """ + try: + if user is None or user.id is None: + return {"error": True, "message": message.ACCESS_FORBIDDEN} + + owner_id = None + if only_my_genesets: + owner_id = user.id + + results = db_geneset.get( + cursor, + is_readable_by=user.id, + owner_id=owner_id, + gs_id=gs_id, + curation_tier=curation_tier, + species=species, + name=name, + abbreviation=abbreviation, + publication_id=publication_id, + pubmed_id=pubmed_id, + gene_id_type=gene_id_type, + search_text=search_text, + with_publication_info=with_publication_info, + limit=limit, + offset=offset, + ) + return {"data": results} + + except Exception as err: + logger.error(err) + raise err + + def get_geneset_metadata( cursor: Cursor, geneset_id: int, user: User, include_pub_info: bool = False ) -> dict: @@ -25,11 +90,16 @@ def get_geneset_metadata( @return: dictionary response (geneset). """ try: - if not is_geneset_readable_by_user(cursor, geneset_id, user): + if user is None or user.id is None: return {"error": True, "message": message.ACCESS_FORBIDDEN} - geneset = db_geneset.by_id(cursor, geneset_id, include_pub_info) - return {"geneset": geneset} + results = db_geneset.get( + cursor, + is_readable_by=user.id, + gs_id=geneset_id, + with_publication_info=include_pub_info, + ) + return {"geneset": results[0]} except Exception as err: logger.error(err) @@ -45,10 +115,16 @@ def get_geneset(cursor: Cursor, geneset_id: int, user: User) -> dict: @return: dictionary response (geneset and genset values). """ try: - if not is_geneset_readable_by_user(cursor, geneset_id, user): + if user is None or user.id is None: return {"error": True, "message": message.ACCESS_FORBIDDEN} - geneset = db_geneset.by_id(cursor, geneset_id) + results = db_geneset.get( + cursor, + is_readable_by=user.id, + gs_id=geneset_id, + with_publication_info=False, + ) + geneset = results[0] geneset_values = db_geneset_value.by_geneset_id(cursor, geneset_id) return {"geneset": geneset, "geneset_values": geneset_values} @@ -69,10 +145,16 @@ def get_geneset_w_gene_id_type( @return: Dictionary response (geneset identifier, geneset, and genset values). """ try: - if not is_geneset_readable_by_user(cursor, geneset_id, user): + if user is None or user.id is None: return {"error": True, "message": message.ACCESS_FORBIDDEN} - geneset = db_geneset.by_id(cursor, geneset_id) + results = db_geneset.get( + cursor, + is_readable_by=user.id, + gs_id=geneset_id, + with_publication_info=False, + ) + geneset = results[0] mapping_across_species = False original_gene_id_type = gene_id_type @@ -132,21 +214,3 @@ def map_geneset_homology( except Exception as err: logger.error(err) raise err - - -def is_geneset_readable_by_user(cursor: Cursor, geneset_id: int, user: User) -> bool: - """Check if the user can read the geneset from DB. - - @param cursor: DB cursor object - @param geneset_id: geneset identifier - @param user: GW user - @return: True if geneset is readable by user. - """ - readable: bool = False - try: - readable = db_is_readable(cursor, user.id, geneset_id) - except Exception as err: - logger.error(err) - raise err - - return readable diff --git a/tests/controllers/test_genesets.py b/tests/controllers/test_genesets.py index a0bdb3c..f7b3e36 100644 --- a/tests/controllers/test_genesets.py +++ b/tests/controllers/test_genesets.py @@ -2,7 +2,7 @@ from unittest.mock import patch -import pytest +from geneweaver.api.controller import message from tests.data import test_geneset_data, test_publication_data @@ -13,34 +13,27 @@ @patch("geneweaver.api.services.geneset.get_geneset") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_response(mock_genset_is_readable, mock_get_genenset, client): +def test_get_geneset_response(mock_get_genenset, client): """Test get geneset ID data response.""" - mock_genset_is_readable.return_value = True - mock_get_genenset.return_value = geneset_by_id_resp + mock_get_genenset.return_value = geneset_by_id_resp.get("geneset") response = client.get("/api/genesets/1234") assert response.status_code == 200 - assert response.json() == geneset_by_id_resp + assert response.json() == geneset_by_id_resp.get("geneset") -@patch("geneweaver.api.services.geneset.db_is_readable") -def test_get_geneset_forbidden(mock_genset_is_readable, client): - """Test forbidden response.""" - mock_genset_is_readable.return_value = False - response = client.get("/api/genesets/1234") +@patch("geneweaver.api.services.geneset.get_geneset") +def test_get_geneset_errors(mock_get_geneset, client): + """Test get geneset ID data response.""" + mock_get_geneset.return_value = {"error": True, "message": message.ACCESS_FORBIDDEN} - assert response.json() == {"detail": "Forbidden"} + response = client.get("/api/genesets/1234") assert response.status_code == 403 + mock_get_geneset.return_value = {"error": True, "message": "other"} -@patch("geneweaver.api.services.geneset.db_is_readable") -def test_get_geneset_unexpected_error(mock_genset_is_readable, client): - """Test unexpected error response.""" - mock_genset_is_readable.side_effect = Exception - - with pytest.raises(expected_exception=Exception): - client.get("/api/genesets/1234") + response = client.get("/api/genesets/1234") + assert response.status_code == 500 @patch("geneweaver.api.services.geneset.get_geneset_w_gene_id_type") @@ -53,16 +46,6 @@ def test_get_geneset_w_gene_id_type(mock_service_get_geneset_w_gene_id_type, cli assert response.status_code == 200 -@patch("geneweaver.api.services.geneset.db_is_readable") -def test_get_geneset_export_forbidden(mock_genset_is_readable, client): - """Test export forbidden response.""" - mock_genset_is_readable.return_value = False - response = client.get("/api/genesets/1234/file?gene_id_type=2") - - assert response.json() == {"detail": "Forbidden"} - assert response.status_code == 403 - - @patch("geneweaver.api.services.geneset.get_geneset_w_gene_id_type") def test_export_geneset_w_gene_id_type(mock_service_get_geneset_w_gene_id_type, client): """Test geneset file export.""" @@ -84,25 +67,50 @@ def test_invalid_gene_type_id(mock_service_get_geneset_w_gene_id_type, client): assert response.status_code == 422 +@patch("geneweaver.api.services.geneset.get_geneset") +def test_export_geneset_errors(mock_get_geneset, client): + """Test error in geneset file export.""" + mock_get_geneset.return_value = {"error": True, "message": message.ACCESS_FORBIDDEN} + + response = client.get("/api/genesets/1234/file") + assert response.status_code == 403 + + mock_get_geneset.return_value = {"error": True, "message": "other"} + + response = client.get("/api/genesets/1234/file") + assert response.status_code == 500 + + @patch("geneweaver.api.services.geneset.get_geneset_metadata") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_metadata(mock_genset_is_readable, mock_get_genenset, client): +def test_get_geneset_metadata(mock_get_genenset, client): """Test get geneset metadata.""" - mock_genset_is_readable.return_value = True - mock_get_genenset.return_value = geneset_by_id_resp + mock_get_genenset.return_value = geneset_by_id_resp.get("geneset") response = client.get("/api/genesets/1234/metadata") assert response.status_code == 200 - assert response.json() == geneset_by_id_resp + assert response.json() == geneset_by_id_resp.get("geneset") @patch("geneweaver.api.services.geneset.get_geneset_metadata") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_metadata_w_publication( - mock_genset_is_readable, mock_get_genenset, client -): +def test_get_geneset_metadata_errors(mock_get_geneset_metadata, client): + """Test errors in geneset metadata response.""" + mock_get_geneset_metadata.return_value = { + "error": True, + "message": message.ACCESS_FORBIDDEN, + } + + response = client.get("/api/genesets/1234/metadata") + assert response.status_code == 403 + + mock_get_geneset_metadata.return_value = {"error": True, "message": "other"} + + response = client.get("/api/genesets/1234/metadata") + assert response.status_code == 500 + + +@patch("geneweaver.api.services.geneset.get_geneset_metadata") +def test_get_geneset_metadata_w_publication(mock_get_genenset, client): """Test get geneset ID data response.""" - mock_genset_is_readable.return_value = True mock_get_genenset.return_value = geneset_metadata_w_pub_info response = client.get("/api/genesets/1234/metadata?include_pub_info=true") @@ -111,13 +119,11 @@ def test_get_geneset_metadata_w_publication( @patch("geneweaver.api.services.geneset.get_geneset_metadata") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") @patch("geneweaver.api.services.publications.get_publication") def test_publication_for_geneset( - mock_pub_service_call, mock_genset_is_readable, mock_get_genenset_metadata, client + mock_pub_service_call, mock_get_genenset_metadata, client ): """Test valid url request to get publication for a geneset.""" - mock_genset_is_readable.return_value = True mock_get_genenset_metadata.return_value = geneset_metadata_w_pub_info mock_pub_service_call.return_value = publication_by_id_resp @@ -129,16 +135,66 @@ def test_publication_for_geneset( @patch("geneweaver.api.services.geneset.get_geneset_metadata") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") @patch("geneweaver.api.services.publications.get_publication") def test_publication_not_found_for_geneset( - mock_pub_service_call, mock_genset_is_readable, mock_get_genenset_metadata, client + mock_pub_service_call, mock_get_genenset_metadata, client ): """Test get publication for a geneset with not found record.""" - mock_genset_is_readable.return_value = True - mock_get_genenset_metadata.return_value = geneset_by_id_resp.get("geneset") + mock_get_genenset_metadata.return_value = geneset_metadata_w_pub_info mock_pub_service_call.return_value = {"publication": None} response = client.get("/api/genesets/1234/publication") assert response.status_code == 404 + + geneset = geneset_metadata_w_pub_info.copy() + geneset["publication_id"] = None + + mock_get_genenset_metadata.return_value = geneset + response = client.get("/api/genesets/1234/publication") + + assert response.status_code == 404 + + +@patch("geneweaver.api.services.geneset.get_geneset_metadata") +def test_get_publication_errors(mock_get_geneset_metadata, client): + """Test get geneset ID data response.""" + mock_get_geneset_metadata.return_value = { + "error": True, + "message": message.ACCESS_FORBIDDEN, + } + + response = client.get("/api/genesets/1234/publication") + assert response.status_code == 403 + + mock_get_geneset_metadata.return_value = {"error": True, "message": "other"} + + response = client.get("/api/genesets/1234/publication") + assert response.status_code == 500 + + +@patch("geneweaver.api.services.geneset.get_visible_genesets") +def test_get_visible_geneset_response(mock_get_visible_genesets, client): + """Test get geneset ID data response.""" + mock_get_visible_genesets.return_value = geneset_by_id_resp.get("geneset") + + response = client.get("/api/genesets?gs_id=1234") + assert response.status_code == 200 + assert response.json() == geneset_by_id_resp.get("geneset") + + +@patch("geneweaver.api.services.geneset.get_visible_genesets") +def test_get_visible_geneset_errors(mock_get_visible_genesets, client): + """Test get geneset ID data response.""" + mock_get_visible_genesets.return_value = { + "error": True, + "message": message.ACCESS_FORBIDDEN, + } + + response = client.get("/api/genesets?gs_id=1234") + assert response.status_code == 403 + + mock_get_visible_genesets.return_value = {"error": True, "message": "other"} + + response = client.get("/api/genesets?gs_id=1234") + assert response.status_code == 500 diff --git a/tests/data/__init__.py b/tests/data/__init__.py index c814c95..9f7861c 100644 --- a/tests/data/__init__.py +++ b/tests/data/__init__.py @@ -14,6 +14,8 @@ "tests.data", "response_geneset_w_gene_id_type.json" ) +geneset_list_response_json = importlib.resources.read_text("tests.data", "geneset.json") + gene_homologus_ids_json = importlib.resources.read_text( "tests.data", "homologus_ids.json" ) @@ -39,6 +41,7 @@ "geneset_metadata_w_pub_info": json.loads(geneset_response_json).get( "geneset_with_publication_info" ), + "geneset_list_resp": json.loads(geneset_list_response_json), } # Gene homolog ids test data diff --git a/tests/data/geneset.json b/tests/data/geneset.json new file mode 100644 index 0000000..8aba928 --- /dev/null +++ b/tests/data/geneset.json @@ -0,0 +1,284 @@ +{ + "geneset_resp_1_list_10": [ + { + "id": 723, + "user_id": 40, + "file_id": 118046, + "curation_id": 3, + "species_id": 1, + "name": "test", + "abbreviation": "test", + "publication_id": null, + "description": "test", + "count": 42, + "score_type": 3, + "threshold": "0.5", + "status": "deleted", + "gene_id_type": 8, + "attribution": null, + "created": "2007-07-03", + "updated": "2016-11-17T10:48:44.684116", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 400677, + "user_id": 22507473, + "file_id": 464385, + "curation_id": 4, + "species_id": 2, + "name": "test", + "abbreviation": "test", + "publication_id": null, + "description": "test", + "count": 1213, + "score_type": 1, + "threshold": "0.5", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": "2021-08-05", + "updated": "2021-08-05T11:25:37.685706", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 750, + "user_id": 40, + "file_id": 118076, + "curation_id": 4, + "species_id": 1, + "name": "testing", + "abbreviation": "testing", + "publication_id": 26, + "description": "testing", + "count": 8286, + "score_type": 4, + "threshold": "0.5,1", + "status": "deleted", + "gene_id_type": 8, + "attribution": null, + "created": "2007-09-18", + "updated": "2017-04-14T17:25:51.769164", + "publication_authors": "Carr LG, Kimpel MW, Liang T, McClintick JN, McCall K, Morse M, Edenberg HJ", + "publication_title": "Identification of candidate genes for alcohol preference by expression profiling of congenic rat strains.", + "publication_abstract": "BACKGROUND: A highly significant quantitative trait locus (QTL) on chromosome 4 that influenced alcohol preference was identified by analyzing crosses between the iP and iNP rats. Congenic strains in which the iP chromosome 4 QTL interval was transferred to the iNP (NP.P) exhibited the expected increase in alcohol consumption compared with the iNP background strain. This study was undertaken to identify genes in the chromosome 4 QTL interval that might contribute to the differences in alcohol consumption between the alcohol-naïve congenic and background strains. METHODS: RNA from 5 brain regions from each of 6 NP.P and 6 iNP rats was labeled and analyzed separately on an Affymetrix Rat Genome 230 2.0 microarray to look for both cis-regulated and trans-regulated genes. Expression levels were normalized using robust multi-chip average (RMA). Differential gene expression was validated using quantitative real-time polymerase chain reaction. Five individual brain regions (nucleus accumbens, frontal cortex, amygdala, hippocampus, and striatum) were analyzed to detect differential expression of genes within the introgressed QTL interval, as well as genes outside that region. To increase the power to detect differentially expressed genes, combined analyses (averaging data from the 5 discrete brain regions of each animal) were also carried out. RESULTS: Analyses within individual brain regions that focused on genes within the QTL interval detected differential expression in all 5 brain regions; a total of 35 genes were detected in at least 1 region, ranging from 6 genes in the nucleus accumbens to 22 in the frontal cortex. Analysis of the whole genome detected very few differentially expressed genes outside the QTL. Combined analysis across brain regions was more powerful. Analysis focused on the genes within the QTL interval confirmed 19 of the genes detected in individual regions and detected 15 additional genes. Whole genome analysis detected 1 differentially expressed gene outside the interval. CONCLUSIONS: Cis-regulated candidate genes for alcohol consumption were identified using microarray profiling of gene expression differences in congenic animals carrying a QTL for alcohol preference.", + "publication_journal": "Alcoholism, clinical and experimental research", + "publication_volume": "31", + "publication_pages": "1089-98", + "publication_month": "Jul", + "publication_year": "2007", + "publication_pubmed_id": "17451403" + }, + { + "id": 441, + "user_id": 40, + "file_id": 118046, + "curation_id": 3, + "species_id": 1, + "name": "abc1233333", + "abbreviation": "abc1233333", + "publication_id": null, + "description": "abc33333", + "count": 42, + "score_type": 5, + "threshold": "0,2", + "status": "deleted", + "gene_id_type": 8, + "attribution": null, + "created": "2007-03-26", + "updated": "2016-11-17T10:47:30.357827", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 219395, + "user_id": 6375003, + "file_id": 272802, + "curation_id": null, + "species_id": 1, + "name": "Sample gene list", + "abbreviation": "artificial", + "publication_id": null, + "description": "This is an image file", + "count": 60, + "score_type": 5, + "threshold": "0.556,1.868", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": null, + "updated": "2020-05-06T09:19:44.883323", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 83599, + "user_id": 667, + "file_id": 86515, + "curation_id": 3, + "species_id": 1, + "name": "abba geneset", + "abbreviation": "abba geneset", + "publication_id": null, + "description": "abba geneset", + "count": 18, + "score_type": 3, + "threshold": "0.5", + "status": "deleted", + "gene_id_type": -7, + "attribution": null, + "created": "2010-08-03", + "updated": "2016-11-17T10:55:07.989610", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 751, + "user_id": 40, + "file_id": 1100, + "curation_id": 3, + "species_id": 1, + "name": "Error Recreate", + "abbreviation": "Error Recreate", + "publication_id": null, + "description": "Test", + "count": 399, + "score_type": 4, + "threshold": "-0.5,0.5", + "status": "deleted", + "gene_id_type": 19, + "attribution": null, + "created": "2007-09-18", + "updated": "2016-11-17T10:49:56.400684", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 30671, + "user_id": 538, + "file_id": 33355, + "curation_id": 1, + "species_id": 1, + "name": "GO:0007416 synaptogenesis", + "abbreviation": "GO:0007416", + "publication_id": null, + "description": "Biological Process: synaptogenesis. Data from MGI: gene_association.mgi retrieved 2009-06-04.", + "count": 12, + "score_type": 3, + "threshold": "0.5", + "status": "deprecated:185374", + "gene_id_type": -10, + "attribution": null, + "created": "2009-06-04", + "updated": "2015-07-15T20:43:04.532024", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 221473, + "user_id": 6408081, + "file_id": 274964, + "curation_id": null, + "species_id": 2, + "name": "http://www.broadinstitute.org/gsea/msigdb/cards/ST_ADRENERGIC", + "abbreviation": "ST_ADRENERGIC", + "publication_id": null, + "description": "ST_ADRENERGIC", + "count": 27, + "score_type": 3, + "threshold": "0.5", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": null, + "updated": "2020-05-06T09:19:44.883323", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + }, + { + "id": 10149, + "user_id": 51, + "file_id": 12614, + "curation_id": 3, + "species_id": 1, + "name": "temp", + "abbreviation": "temp", + "publication_id": null, + "description": "temp", + "count": 12, + "score_type": 3, + "threshold": "0.5", + "status": "deleted", + "gene_id_type": -7, + "attribution": null, + "created": "2008-12-09", + "updated": "2015-07-15T20:43:04.532024", + "publication_authors": null, + "publication_title": null, + "publication_abstract": null, + "publication_journal": null, + "publication_volume": null, + "publication_pages": null, + "publication_month": null, + "publication_year": null, + "publication_pubmed_id": null + } + ] +} \ No newline at end of file diff --git a/tests/data/response_geneset_1234.json b/tests/data/response_geneset_1234.json index 7a30026..a01f442 100644 --- a/tests/data/response_geneset_1234.json +++ b/tests/data/response_geneset_1234.json @@ -1,32 +1,22 @@ { "geneset": { - "gs_id": 1234, - "usr_id": 51, + "id": 1234, + "user_id": 51, "file_id": 1715, - "gs_name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", - "gs_abbreviation": "UpRegHeroinDwnRegCocaine", - "pub_id": 6, - "res_id": null, - "cur_id": 3, - "gs_description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", - "sp_id": 2, - "gs_count": 3, - "gs_threshold_type": 3, - "gs_threshold": "0.5", - "gs_groups": "0", - "gs_attribution_old": null, - "gs_uri": null, - "gs_gene_id_type": -7, - "_searchtext": "'abus':8A,34B,42B,47B 'abusers-down-regul':7A 'accumben':28B 'chronic':30B 'cocain':6A,11A,33B,41B 'contain':37B 'differenti':1A,21B 'downregul':44B 'express':2A,22B 'gene':23B,38B 'heroin':4A,15A,31B,46B 'initi':18B 'mortum':26B 'nucleus':27B 'post':25B 'regul':10A,14A 'set':19B,36B 'up-regul':12A 'upregul':39B", - "gs_created": "2008-04-22", - "admin_flag": null, - "gs_updated": "2020-05-06T09:19:44.883323", - "gs_status": "normal", - "gsv_qual": "{}", - "_comments_author": null, - "_comments_curator": null, - "gs_attribution": null, - "gs_is_edgelist": false + "curation_id": 3, + "species_id": 2, + "name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", + "abbreviation": "UpRegHeroinDwnRegCocaine", + "publication_id": 6, + "description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", + "count": 3, + "score_type": 3, + "threshold": "0.5", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": "2008-04-22", + "updated": "2020-05-06T09:19:44.883323" }, "geneset_values": [ { @@ -42,7 +32,7 @@ ], "gsv_in_threshold": true, "gsv_date": "2020-05-05", - "ode_ref_id": "Hs.456585" + "ode_ref_id": "Hs.629744" }, { "gs_id": 1234, @@ -57,7 +47,7 @@ ], "gsv_in_threshold": true, "gsv_date": "2020-05-05", - "ode_ref_id": "HGNC:14107" + "ode_ref_id": "Hs.517155" }, { "gs_id": 1234, @@ -72,39 +62,37 @@ ], "gsv_in_threshold": true, "gsv_date": "2020-05-05", - "ode_ref_id": "Hs.541341" + "ode_ref_id": "Hs.356063" } ], "geneset_with_publication_info": { - "geneset": { - "id": 1234, - "user_id": 51, - "file_id": 1715, - "curation_id": 3, - "species_id": 2, - "name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", - "abbreviation": "UpRegHeroinDwnRegCocaine", - "pub_id": 6, - "description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", - "count": 3, - "threshold_type": 3, - "threshold": "0.5", - "groups": "0", - "status": "normal", - "gene_id_type": -7, - "attribution": null, - "created": "2008-04-22", - "updated": "2020-05-06T09:19:44.883323", - "publication_id": 6, - "publication_authors": "Albertson DN, Schmidt CJ, Kapatos G, Bannon MJ", - "publication_title": "Distinctive profiles of gene expression in the human nucleus accumbens associated with cocaine and heroin abuse.", - "publication_abstract": "Drug abuse is thought to induce long-term cellular and behavioral adaptations as a result of alterations in gene expression. Understanding the molecular consequences of addiction may contribute to the development of better treatment strategies. This study utilized high-throughput Affymetrix microarrays to identify gene expression changes in the post-mortem nucleus accumbens of chronic heroin abusers. These data were analyzed independently and in relation to our previously reported data involving human cocaine abusers, in order to determine which expression changes were drug specific and which may be common to the phenomenon of addiction. A significant decrease in the expression of numerous genes encoding proteins involved in presynaptic release of neurotransmitter was seen in heroin abusers, a finding not seen in the cocaine-abusing cohort. Conversely, the striking decrease in myelin-related genes observed in cocaine abusers was not evident in our cohort of heroin subjects. Overall, little overlap in gene expression profiles was seen between the two drug-abusing cohorts: out of the approximately 39,000 transcripts investigated, the abundance of only 25 was significantly changed in both cocaine and heroin abusers, with nearly one-half of these being altered in opposite directions. These data suggest that the profiles of nucleus accumbens gene expression associated with chronic heroin or cocaine abuse are largely unique, despite what are thought to be common effects of these drugs on dopamine neurotransmission in this brain region. A re-examination of our current assumptions about the commonality of molecular mechanisms associated with substance abuse seems warranted.", - "publication_journal": "Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology", - "publication_volume": "31", - "publication_pages": "2304-12", - "publication_month": "Oct", - "publication_year": "2006", - "publication_pubmed_id": "16710320" - } + "geneset": { + "id": 1234, + "user_id": 51, + "file_id": 1715, + "curation_id": 3, + "species_id": 2, + "name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", + "abbreviation": "UpRegHeroinDwnRegCocaine", + "publication_id": 6, + "description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", + "count": 3, + "score_type": 3, + "threshold": "0.5", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": "2008-04-22", + "updated": "2020-05-06T09:19:44.883323", + "publication_authors": "Albertson DN, Schmidt CJ, Kapatos G, Bannon MJ", + "publication_title": "Distinctive profiles of gene expression in the human nucleus accumbens associated with cocaine and heroin abuse.", + "publication_abstract": "Drug abuse is thought to induce long-term cellular and behavioral adaptations as a result of alterations in gene expression. Understanding the molecular consequences of addiction may contribute to the development of better treatment strategies. This study utilized high-throughput Affymetrix microarrays to identify gene expression changes in the post-mortem nucleus accumbens of chronic heroin abusers. These data were analyzed independently and in relation to our previously reported data involving human cocaine abusers, in order to determine which expression changes were drug specific and which may be common to the phenomenon of addiction. A significant decrease in the expression of numerous genes encoding proteins involved in presynaptic release of neurotransmitter was seen in heroin abusers, a finding not seen in the cocaine-abusing cohort. Conversely, the striking decrease in myelin-related genes observed in cocaine abusers was not evident in our cohort of heroin subjects. Overall, little overlap in gene expression profiles was seen between the two drug-abusing cohorts: out of the approximately 39,000 transcripts investigated, the abundance of only 25 was significantly changed in both cocaine and heroin abusers, with nearly one-half of these being altered in opposite directions. These data suggest that the profiles of nucleus accumbens gene expression associated with chronic heroin or cocaine abuse are largely unique, despite what are thought to be common effects of these drugs on dopamine neurotransmission in this brain region. A re-examination of our current assumptions about the commonality of molecular mechanisms associated with substance abuse seems warranted.", + "publication_journal": "Neuropsychopharmacology : official publication of the American College of Neuropsychopharmacology", + "publication_volume": "31", + "publication_pages": "2304-12", + "publication_month": "Oct", + "publication_year": "2006", + "publication_pubmed_id": "16710320" + } } } diff --git a/tests/data/response_geneset_w_gene_id_type.json b/tests/data/response_geneset_w_gene_id_type.json index a667041..e65ed45 100644 --- a/tests/data/response_geneset_w_gene_id_type.json +++ b/tests/data/response_geneset_w_gene_id_type.json @@ -1,33 +1,23 @@ { "gene_identifier_type": "ENSEMBLE_GENE", "geneset": { - "gs_id": 1234, - "usr_id": 51, + "id": 1234, + "user_id": 51, "file_id": 1715, - "gs_name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", - "gs_abbreviation": "UpRegHeroinDwnRegCocaine", - "pub_id": 6, - "res_id": null, - "cur_id": 3, - "gs_description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", - "sp_id": 2, - "gs_count": 3, - "gs_threshold_type": 3, - "gs_threshold": "0.5", - "gs_groups": "0", - "gs_attribution_old": null, - "gs_uri": null, - "gs_gene_id_type": -7, - "_searchtext": "'abus':8A,34B,42B,47B 'abusers-down-regul':7A 'accumben':28B 'chronic':30B 'cocain':6A,11A,33B,41B 'contain':37B 'differenti':1A,21B 'downregul':44B 'express':2A,22B 'gene':23B,38B 'heroin':4A,15A,31B,46B 'initi':18B 'mortum':26B 'nucleus':27B 'post':25B 'regul':10A,14A 'set':19B,36B 'up-regul':12A 'upregul':39B", - "gs_created": "2008-04-22", - "admin_flag": null, - "gs_updated": "2020-05-06T09:19:44.883323", - "gs_status": "normal", - "gsv_qual": "{}", - "_comments_author": null, - "_comments_curator": null, - "gs_attribution": null, - "gs_is_edgelist": false + "curation_id": 3, + "species_id": 2, + "name": "Differential expression in heroin and cocaine abusers-Down-regulated Cocaine, Up-regulated Heroin", + "abbreviation": "UpRegHeroinDwnRegCocaine", + "publication_id": 6, + "description": "From the initial set of differentially expressed genes in post mortum nucleus accumbens of chronic heroin and cocaine abusers, this set contains genes upregulated in cocaine abusers but downregulated in heroin abusers.", + "count": 3, + "score_type": 3, + "threshold": "0.5", + "status": "normal", + "gene_id_type": -7, + "attribution": null, + "created": "2008-04-22", + "updated": "2020-05-06T09:19:44.883323" }, "geneset_values": [ { @@ -139,5 +129,4 @@ "gdb_id": 2 } ] -} - +} \ No newline at end of file diff --git a/tests/services/test_genset.py b/tests/services/test_genset.py index d22bd9a..5ef116b 100644 --- a/tests/services/test_genset.py +++ b/tests/services/test_genset.py @@ -4,32 +4,32 @@ import pytest from geneweaver.api.controller import message +from geneweaver.api.schemas.auth import User from geneweaver.api.services import geneset -from geneweaver.core.enum import GeneIdentifier +from geneweaver.core.enum import GeneIdentifier, GenesetTier, Species from tests.data import test_geneset_data geneset_by_id_resp = test_geneset_data.get("geneset_by_id_resp") +geneset_list_resp = test_geneset_data.get("geneset_list_resp") geneset_w_gene_id_type_resp = test_geneset_data.get("geneset_w_gene_id_type_resp") geneset_metadata_w_pub_info = test_geneset_data.get("geneset_metadata_w_pub_info") +mock_user = User() +mock_user.id = 1 @patch("geneweaver.api.services.geneset.db_geneset") @patch("geneweaver.api.services.geneset.db_geneset_value") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset(mock_genset_readable_func, mock_db_geneset, mock_db_genset_value): +def test_get_geneset(mock_db_geneset, mock_db_genset_value): """Test basic get geneset by ID.""" - mock_genset_readable_func.return_value = True - mock_db_geneset.by_id.return_value = {} - mock_db_genset_value.by_id.return_value = {} - response = geneset.get_geneset(None, 1234, None) + mock_db_geneset.get.return_value = {} + mock_db_genset_value.get.return_value = [{}] + response = geneset.get_geneset(None, 1234, mock_user) assert response.get("error") is None -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_no_user_access(mock_genset_readable_func): +def test_get_geneset_no_user_access(): """Test get geneset by ID with no user access.""" - mock_genset_readable_func.return_value = False response = geneset.get_geneset(None, 1234, None) assert response.get("error") is True assert response.get("message") == message.ACCESS_FORBIDDEN @@ -37,57 +37,74 @@ def test_get_geneset_no_user_access(mock_genset_readable_func): @patch("geneweaver.api.services.geneset.db_geneset") @patch("geneweaver.api.services.geneset.db_geneset_value") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_returned_values( - mock_genset_readable_func, mock_db_genset_value, mock_db_geneset -): +def test_get_geneset_returned_values(mock_db_genset_value, mock_db_geneset): """Test get geneset by ID data response structure.""" - mock_genset_readable_func.return_value = True - mock_db_geneset.by_id.return_value = geneset_by_id_resp.get("geneset") + mock_db_geneset.get.return_value = [geneset_by_id_resp.get("geneset")] mock_db_genset_value.by_geneset_id.return_value = geneset_by_id_resp.get( "geneset_values" ) - response = geneset.get_geneset(None, 1234, None) + response = geneset.get_geneset(None, 1234, mock_user) assert response.get("geneset") == geneset_by_id_resp["geneset"] assert response.get("geneset_values") == geneset_by_id_resp["geneset_values"] -@patch("geneweaver.api.services.geneset.db_is_readable") -@patch("geneweaver.api.services.geneset.User") -def test_is_redable_by_user(mock_user, mock_genset_is_readable): - """Test is geneset ID readable by passed user.""" - mock_genset_is_readable.return_value = True - response = geneset.is_geneset_readable_by_user(None, 1234, mock_user) - assert response is True - - -@patch("geneweaver.db.geneset.is_readable") -@patch("geneweaver.api.services.geneset.User") -def test_is_redable_by_user_error(mock_user, mock_genset_is_readable): - """Test is geneset ID readable with server error.""" - mock_genset_is_readable.sideEffect = Exception +@patch("geneweaver.api.services.geneset.db_geneset") +def test_get_geneset_db_call_error(mock_db_geneset): + """Test error in get DB call.""" + mock_db_geneset.get.side_effect = Exception("ERROR") with pytest.raises(expected_exception=Exception): - geneset.is_geneset_readable_by_user(None, 1234, mock_user) + geneset.get_geneset(None, 1234, mock_user) @patch("geneweaver.api.services.geneset.db_gene") @patch("geneweaver.api.services.geneset.db_geneset") @patch("geneweaver.api.services.geneset.db_geneset_value") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_w_gene_id_type_reponse( - mock_genset_readable_func, mock_db_genset_value, mock_db_geneset, mock_db_gene +def test_get_geneset_w_gene_id_type_response( + mock_db_genset_value, + mock_db_geneset, + mock_db_gene, ): """Test get geneset by ID with gene identifier type data response.""" - mock_genset_readable_func.return_value = True - mock_db_geneset.by_id.return_value = geneset_w_gene_id_type_resp.get("geneset") + mock_db_geneset.get.return_value = [geneset_w_gene_id_type_resp.get("geneset")] mock_db_genset_value.by_geneset_id.return_value = geneset_w_gene_id_type_resp.get( "geneset_values" ) mock_db_gene.gene_database_by_id.return_value = [{"sp_id": 0}] - response = geneset.get_geneset_w_gene_id_type(None, 1234, None, GeneIdentifier(2)) + response = geneset.get_geneset_w_gene_id_type( + None, 1234, mock_user, GeneIdentifier(2) + ) + + assert response.get("geneset") == geneset_w_gene_id_type_resp["geneset"] + assert ( + response.get("gene_identifier_type") + == geneset_w_gene_id_type_resp["gene_identifier_type"] + ) + assert ( + response.get("geneset_values") == geneset_w_gene_id_type_resp["geneset_values"] + ) + + +@patch("geneweaver.api.services.geneset.db_gene") +@patch("geneweaver.api.services.geneset.db_geneset") +@patch("geneweaver.api.services.geneset.db_geneset_value") +def test_get_geneset_w_gene_id_type_2_response( + mock_db_genset_value, + mock_db_geneset, + mock_db_gene, +): + """Test get geneset by ID with gene identifier type data response.""" + mock_db_geneset.get.return_value = [geneset_w_gene_id_type_resp.get("geneset")] + mock_db_genset_value.by_geneset_id.return_value = geneset_w_gene_id_type_resp.get( + "geneset_values" + ) + mock_db_gene.gene_database_by_id.return_value = [{"sp_id": 1}] + + response = geneset.get_geneset_w_gene_id_type( + None, 1234, mock_user, GeneIdentifier(2) + ) assert response.get("geneset") == geneset_w_gene_id_type_resp["geneset"] assert ( @@ -99,23 +116,136 @@ def test_get_geneset_w_gene_id_type_reponse( ) +def test_get_geneset_w_gene_id_type_no_user(): + """Test get_geneset_w_gene_id_type with invalid user.""" + response = geneset.get_geneset_w_gene_id_type(None, 1234, None, GeneIdentifier(2)) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + + response = geneset.get_geneset_w_gene_id_type( + None, 1234, User(id=None), GeneIdentifier(2) + ) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + + @patch("geneweaver.api.services.geneset.db_geneset") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_metadata(mock_genset_readable_func, mock_db_geneset): +def test_geneset_w_gene_id_type_db_call_error(mock_db_geneset): + """Test error in get DB call.""" + mock_db_geneset.get.side_effect = Exception("ERROR") + + with pytest.raises(expected_exception=Exception): + geneset.get_geneset_w_gene_id_type(None, 1234, mock_user, GeneIdentifier(2)) + + +@patch("geneweaver.api.services.geneset.db_geneset") +def test_get_geneset_metadata(mock_db_geneset): """Test get geneset metadata by geneset id.""" - mock_genset_readable_func.return_value = True - mock_db_geneset.by_id.return_value = geneset_by_id_resp.get("geneset") - response = geneset.get_geneset_metadata(None, 1234, None) + mock_db_geneset.get.return_value = [geneset_by_id_resp.get("geneset")] + response = geneset.get_geneset_metadata(None, 1234, mock_user) assert response.get("geneset") == geneset_by_id_resp["geneset"] + response = geneset.get_geneset_metadata(None, 1234, None) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + + response = geneset.get_geneset_metadata(None, 1234, User(id=None)) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + @patch("geneweaver.api.services.geneset.db_geneset") -@patch("geneweaver.api.services.geneset.is_geneset_readable_by_user") -def test_get_geneset_metadata_w_pub_info(mock_genset_readable_func, mock_db_geneset): +def test_get_geneset_metadata_w_pub_info(mock_db_geneset): """Test get geneset metadata by geneset id with publication info.""" - mock_genset_readable_func.return_value = True - mock_db_geneset.by_id.return_value = geneset_metadata_w_pub_info - response = geneset.get_geneset_metadata(None, 1234, None, True) + mock_db_geneset.get.return_value = [geneset_metadata_w_pub_info] + response = geneset.get_geneset_metadata(None, 1234, mock_user, True) assert response.get("geneset") == geneset_metadata_w_pub_info + + +@patch("geneweaver.api.services.geneset.db_geneset") +def test_geneset_metadata_db_call_error(mock_db_geneset): + """Test error in get DB call.""" + mock_db_geneset.get.side_effect = Exception("ERROR") + + with pytest.raises(expected_exception=Exception): + geneset.get_geneset_metadata(None, 1234, mock_user, True) + + +@patch("geneweaver.api.services.geneset.db_geneset") +def test_visible_geneset_response(mock_db_geneset): + """Test general get geneset data no parameters -- default limit.""" + mock_db_geneset.get.return_value = geneset_list_resp.get("geneset_resp_1_list_10") + + response = geneset.get_visible_genesets(None, mock_user) + assert response.get("data") == geneset_list_resp.get("geneset_resp_1_list_10") + + +def test_visible_geneset_no_user(): + """Test general get geneset data invalid user.""" + response = geneset.get_visible_genesets(None, None) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + + response = geneset.get_visible_genesets(None, User(id=None)) + assert response.get("error") is True + assert response.get("message") == message.ACCESS_FORBIDDEN + + +@patch("geneweaver.api.services.geneset.db_geneset") +def test_visible_geneset_all_expected_parameters(mock_db_geneset): + """Test general get geneset data no parameters -- default limit.""" + mock_db_geneset.get.return_value = geneset_list_resp.get("geneset_resp_1_list_10") + + response = geneset.get_visible_genesets( + cursor=None, + user=mock_user, + gs_id=1, + only_my_genesets=False, + curation_tier=GenesetTier("Tier I"), + species=Species(2), + name="test Name", + abbreviation="test", + publication_id=123, + pubmed_id="p123", + gene_id_type=GeneIdentifier(5), + limit=10, + offset=0, + with_publication_info=True, + ) + + assert response.get("data") == geneset_list_resp.get("geneset_resp_1_list_10") + + +@patch("geneweaver.api.services.geneset.db_geneset") +def test_visible_geneset_db_call_error(mock_db_geneset): + """Test error in get DB call.""" + mock_db_geneset.get.side_effect = Exception("ERROR") + + with pytest.raises(expected_exception=Exception): + geneset.get_visible_genesets(None, mock_user) + + +@patch("geneweaver.api.services.geneset.db_gene") +def test_map_geneset_homology(mock_db_gene): + """Test map_geneset_homology call.""" + mock_db_gene.get_homolog_ids_by_ode_id.return_value = geneset_by_id_resp[ + "geneset_values" + ] + + response = geneset.map_geneset_homology( + None, geneset_by_id_resp["geneset_values"], GeneIdentifier(2) + ) + assert response == geneset_by_id_resp["geneset_values"] + + +@patch("geneweaver.api.services.geneset.db_gene") +def test_map_geneset_homology_db_call_error(mock_db_gene): + """Test error in get DB call.""" + mock_db_gene.get_homolog_ids_by_ode_id.side_effect = Exception("ERROR") + + with pytest.raises(expected_exception=Exception): + geneset.map_geneset_homology( + None, geneset_by_id_resp["geneset_values"], GeneIdentifier(2) + )