about summary refs log tree commit diff
path: root/tests/test_gn2_smoke.py
blob: 7c236426e69fda1aeeb6ace1b907b264636411a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
"""
Smoke tests for the genenetwork2 web frontend.

These tests make HTTP requests to gn2 and assert on status codes and key
page content.  They do not require authentication and do not parse full
HTML — just enough to confirm the page rendered without error and the
expected structural marker is present.

Run with:

    pytest -m "gn2 and smoke"
"""

import pytest


pytestmark = [pytest.mark.gn2, pytest.mark.smoke]

# ---------------------------------------------------------------------------
# Known-good test data
# ---------------------------------------------------------------------------
_DATASET = "HC_M2_0606_P"
_TRAIT_ID = "1435395_s_at"
_SEARCH_SPECIES = "mouse"
_SEARCH_GROUP = "BXD"
_SEARCH_TYPE = "Hippocampus mRNA"


# ---------------------------------------------------------------------------
# Home page
# ---------------------------------------------------------------------------

class TestHomePage:
    def test_returns_200(self, gn2_url, http):
        resp = http.get(gn2_url + "/", timeout=30)
        assert resp.status_code == 200

    def test_content_type_is_html(self, gn2_url, http):
        resp = http.get(gn2_url + "/", timeout=30)
        assert "text/html" in resp.headers.get("Content-Type", "")

    def test_search_form_present(self, gn2_url, http):
        resp = http.get(gn2_url + "/", timeout=30)
        # The search button has id="btsearch" (from existing gn2 test suite).
        assert "btsearch" in resp.text, (
            "Search button element (#btsearch) not found on home page"
        )


# ---------------------------------------------------------------------------
# Dataset search
# ---------------------------------------------------------------------------

class TestSearch:
    def test_search_returns_200(self, gn2_url, http):
        params = {
            "species": _SEARCH_SPECIES,
            "group": _SEARCH_GROUP,
            "type": _SEARCH_TYPE,
            "dataset": _DATASET,
            "search_terms_or": "",
            "search_terms_and": "MEAN=(15 16) LRS=(23 46)",
        }
        resp = http.get(gn2_url + "/search", params=params, timeout=60)
        assert resp.status_code == 200

    def test_search_shows_results_found(self, gn2_url, http):
        params = {
            "species": _SEARCH_SPECIES,
            "group": _SEARCH_GROUP,
            "type": _SEARCH_TYPE,
            "dataset": _DATASET,
            "search_terms_or": "",
            "search_terms_and": "MEAN=(15 16) LRS=(23 46)",
        }
        resp = http.get(gn2_url + "/search", params=params, timeout=60)
        assert "records found" in resp.text, (
            "Search results page does not contain 'records found'"
        )


# ---------------------------------------------------------------------------
# Trait page
# ---------------------------------------------------------------------------

class TestTraitPage:
    def test_known_trait_returns_200(self, gn2_url, http):
        resp = http.get(
            gn2_url + "/show_trait",
            params={"trait_id": _TRAIT_ID, "dataset": _DATASET},
            timeout=60,
        )
        assert resp.status_code == 200, (
            f"Expected 200 for show_trait?trait_id={_TRAIT_ID}&dataset={_DATASET}, "
            f"got {resp.status_code}"
        )

    def test_trait_page_has_data_form(self, gn2_url, http):
        resp = http.get(
            gn2_url + "/show_trait",
            params={"trait_id": _TRAIT_ID, "dataset": _DATASET},
            timeout=60,
        )
        assert 'id="trait_data_form"' in resp.text, (
            "Trait page is missing the #trait_data_form element"
        )

    def test_trait_page_references_dataset(self, gn2_url, http):
        resp = http.get(
            gn2_url + "/show_trait",
            params={"trait_id": _TRAIT_ID, "dataset": _DATASET},
            timeout=60,
        )
        assert _DATASET in resp.text, (
            f"Dataset name '{_DATASET}' not found in trait page"
        )

    def test_unknown_trait_does_not_500(self, gn2_url, http):
        resp = http.get(
            gn2_url + "/show_trait",
            params={"trait_id": "nonexistent_00000", "dataset": "NONEXISTENT_XYZ"},
            timeout=60,
        )
        assert resp.status_code != 500, (
            f"Unknown trait/dataset caused 500: {resp.text[:500]}"
        )


# ---------------------------------------------------------------------------
# gn2 → gn-auth authorization call-through
#
# When gn2 renders the trait page for a public trait, it calls gn-auth's
# POST /auth/data/authorisation internally.  A 200 response with the data
# form present confirms that the gn2 → gn-auth auth call succeeded.
# ---------------------------------------------------------------------------

class TestGn2ToGnAuthAuthFlow:
    def test_public_trait_page_renders_without_auth(self, gn2_url, http):
        """
        The trait page for a known public trait must render fully without
        the user being logged in.  A 200 response with the data form confirms
        that gn2 successfully called gn-auth's data/authorisation endpoint
        and got a public-access response.
        """
        resp = http.get(
            gn2_url + "/show_trait",
            params={"trait_id": _TRAIT_ID, "dataset": _DATASET},
            timeout=60,
        )
        assert resp.status_code == 200
        assert 'id="trait_data_form"' in resp.text


# ---------------------------------------------------------------------------
# gn2 OAuth2 endpoints — basic reachability
# ---------------------------------------------------------------------------

class TestOAuth2Endpoints:
    def test_login_page_reachable(self, gn2_url, http):
        """The OAuth2 authorise redirect must be reachable (not 500)."""
        resp = http.get(gn2_url + "/login", timeout=30, allow_redirects=True)
        assert resp.status_code != 500

    def test_oauth2_code_endpoint_without_code_does_not_500(self, gn2_url, http):
        """The callback endpoint without a code param should 400/redirect, not 500."""
        resp = http.get(gn2_url + "/oauth2/code", timeout=30, allow_redirects=False)
        assert resp.status_code != 500