44"""
55from __future__ import annotations
66
7+ import os # <-- DITAMBAHKAN
78import pytest
89from flask import Flask
910from api .api_server import app as flask_app
@@ -17,28 +18,37 @@ def client(self):
1718 """Flask test client for making API requests."""
1819 return flask_app .test_client ()
1920
20- def test_global_emissions_basic_response (self , client ):
21+ @pytest .fixture
22+ def auth_headers (self ):
23+ """Fixture to create authentication headers from environment variable."""
24+ api_key = os .getenv ('API_KEY' )
25+ if not api_key :
26+ pytest .fail ("API_KEY environment variable not set. Please set it in GitHub Secrets." )
27+ # PENTING: Ganti 'X-API-KEY' jika nama header Anda berbeda
28+ return {'X-API-KEY' : api_key }
29+
30+ def test_global_emissions_basic_response (self , client , auth_headers ):
2131 """Test /global/emissions returns 200 and proper structure."""
22- resp = client .get ("/global/emissions?limit=5" )
32+ resp = client .get ("/global/emissions?limit=5" , headers = auth_headers ) # <-- DITAMBAHKAN headers
2333 assert resp .status_code == 200
2434 data = resp .get_json ()
2535 assert data ["status" ] == "success"
2636 assert "data" in data
2737 assert "pagination" in data
2838 assert isinstance (data ["data" ], list )
2939
30- def test_global_emissions_with_filters (self , client ):
40+ def test_global_emissions_with_filters (self , client , auth_headers ):
3141 """Test /global/emissions with state and year filters."""
32- resp = client .get ("/global/emissions?state=TX&year=2023&limit=3" )
42+ resp = client .get ("/global/emissions?state=TX&year=2023&limit=3" , headers = auth_headers ) # <-- DITAMBAHKAN headers
3343 assert resp .status_code == 200
3444 data = resp .get_json ()
3545 assert data ["status" ] == "success"
3646 assert data ["filters" ]["state" ] == "TX"
3747 assert data ["filters" ]["year" ] == 2023
3848
39- def test_global_emissions_stats (self , client ):
49+ def test_global_emissions_stats (self , client , auth_headers ):
4050 """Test /global/emissions/stats returns aggregated statistics."""
41- resp = client .get ("/global/emissions/stats" )
51+ resp = client .get ("/global/emissions/stats" , headers = auth_headers ) # <-- DITAMBAHKAN headers
4252 assert resp .status_code == 200
4353 data = resp .get_json ()
4454 assert data ["status" ] == "success"
@@ -49,35 +59,35 @@ def test_global_emissions_stats(self, client):
4959 assert "by_year" in stats
5060 assert "total_records" in stats
5161
52- def test_global_iso_basic_response (self , client ):
62+ def test_global_iso_basic_response (self , client , auth_headers ):
5363 """Test /global/iso returns 200 and proper structure."""
54- resp = client .get ("/global/iso?limit=10" )
64+ resp = client .get ("/global/iso?limit=10" , headers = auth_headers ) # <-- DITAMBAHKAN headers
5565 assert resp .status_code == 200
5666 data = resp .get_json ()
5767 assert data ["status" ] == "success"
5868 assert "data" in data
5969 assert isinstance (data ["data" ], list )
6070
61- def test_global_iso_with_country_filter (self , client ):
71+ def test_global_iso_with_country_filter (self , client , auth_headers ):
6272 """Test /global/iso with country filter."""
63- resp = client .get ("/global/iso?country=Germany&limit=5" )
73+ resp = client .get ("/global/iso?country=Germany&limit=5" , headers = auth_headers ) # <-- DITAMBAHKAN headers
6474 assert resp .status_code == 200
6575 data = resp .get_json ()
6676 assert data ["status" ] == "success"
6777 assert data ["filters" ]["country" ] == "Germany"
6878
69- def test_global_eea_basic_response (self , client ):
79+ def test_global_eea_basic_response (self , client , auth_headers ):
7080 """Test /global/eea returns 200 and proper structure."""
71- resp = client .get ("/global/eea?limit=10" )
81+ resp = client .get ("/global/eea?limit=10" , headers = auth_headers ) # <-- DITAMBAHKAN headers
7282 assert resp .status_code == 200
7383 data = resp .get_json ()
7484 assert data ["status" ] == "success"
7585 assert "data" in data
7686 assert isinstance (data ["data" ], list )
7787
78- def test_global_eea_with_filters (self , client ):
88+ def test_global_eea_with_filters (self , client , auth_headers ):
7989 """Test /global/eea with indicator, country, and year filters."""
80- resp = client .get ("/global/eea?country=Sweden&indicator=GHG&year=2023&limit=5" )
90+ resp = client .get ("/global/eea?country=Sweden&indicator=GHG&year=2023&limit=5" , headers = auth_headers ) # <-- DITAMBAHKAN headers
8191 assert resp .status_code == 200
8292 data = resp .get_json ()
8393 assert data ["status" ] == "success"
@@ -86,44 +96,38 @@ def test_global_eea_with_filters(self, client):
8696 assert filters ["indicator" ] == "GHG"
8797 assert filters ["year" ] == 2023
8898
89- def test_global_cevs_basic_company (self , client ):
99+ def test_global_cevs_basic_company (self , client , auth_headers ):
90100 """Test /global/cevs/{company} returns proper CEVS score structure."""
91- resp = client .get ("/global/cevs/Green%20Energy%20Corp" )
101+ resp = client .get ("/global/cevs/Green%20Energy%20Corp" , headers = auth_headers ) # <-- DITAMBAHKAN headers
92102 assert resp .status_code == 200
93103 data = resp .get_json ()
94104 assert data ["status" ] == "success"
95105 assert "score" in data
96106 assert "components" in data
97107 assert "sources" in data
98108 assert "details" in data
99-
100- # Validate score is within expected range
101109 assert 0 <= data ["score" ] <= 100
102-
103- # Validate components structure
104110 components = data ["components" ]
105111 expected_components = ["base" , "iso_bonus" , "epa_penalty" , "renewables_bonus" , "pollution_penalty" , "policy_bonus" ]
106112 for comp in expected_components :
107113 assert comp in components
108114
109- def test_global_cevs_with_country (self , client ):
115+ def test_global_cevs_with_country (self , client , auth_headers ):
110116 """Test /global/cevs/{company} with country parameter for enhanced scoring."""
111- resp = client .get ("/global/cevs/Swedish%20Wind%20Power?country=Sweden" )
117+ resp = client .get ("/global/cevs/Swedish%20Wind%20Power?country=Sweden" , headers = auth_headers ) # <-- DITAMBAHKAN headers
112118 assert resp .status_code == 200
113119 data = resp .get_json ()
114120 assert data ["status" ] == "success"
115121 assert data ["country" ] == "Sweden"
116-
117- # Should have renewable energy data for Sweden
118122 details = data ["details" ]
119123 assert "renewables" in details
120124 if details ["renewables" ]["country_row" ]:
121125 assert details ["renewables" ]["country_row" ]["country" ].lower () == "sweden"
122126
123- def test_global_edgar_basic_response (self , client ):
127+ def test_global_edgar_basic_response (self , client , auth_headers ):
124128 """Test /global/edgar returns proper structure (may have empty data if file missing)."""
125- resp = client .get ("/global/edgar?country=United%20States&pollutant=PM2.5" )
126- assert resp .status_code == 200 # Should not fail even if EDGAR file missing
129+ resp = client .get ("/global/edgar?country=United%20States&pollutant=PM2.5" , headers = auth_headers ) # <-- DITAMBAHKAN headers
130+ assert resp .status_code == 200
127131 data = resp .get_json ()
128132 assert data ["status" ] == "success"
129133 assert "country" in data
@@ -133,21 +137,21 @@ def test_global_edgar_basic_response(self, client):
133137 assert data ["country" ] == "United States"
134138 assert data ["pollutant" ] == "PM2.5"
135139
136- def test_global_edgar_missing_country (self , client ):
140+ def test_global_edgar_missing_country (self , client , auth_headers ):
137141 """Test /global/edgar returns 400 when country parameter is missing."""
138- resp = client .get ("/global/edgar?pollutant=NOx" )
142+ resp = client .get ("/global/edgar?pollutant=NOx" , headers = auth_headers ) # <-- DITAMBAHKAN headers
143+ # API Key valid, jadi errornya bukan 401, melainkan 400 karena parameter tidak lengkap
139144 assert resp .status_code == 400
140145 data = resp .get_json ()
141146 assert data ["status" ] == "error"
142147 assert "country is required" in data ["message" ]
143148
144- def test_global_edgar_with_window_parameter (self , client ):
149+ def test_global_edgar_with_window_parameter (self , client , auth_headers ):
145150 """Test /global/edgar with custom trend window parameter."""
146- resp = client .get ("/global/edgar?country=Germany&pollutant=NOx&window=5" )
151+ resp = client .get ("/global/edgar?country=Germany&pollutant=NOx&window=5" , headers = auth_headers ) # <-- DITAMBAHKAN headers
147152 assert resp .status_code == 200
148153 data = resp .get_json ()
149154 assert data ["status" ] == "success"
150- # Trend should reflect the window parameter in its calculation
151155 trend = data ["trend" ]
152156 assert "pollutant" in trend
153157 assert trend ["pollutant" ] == "NOx"
0 commit comments