"""Regression checks for the critical access-control hardening."""
import os
import unittest


os.environ.setdefault('DB_HOST', 'localhost')
os.environ.setdefault('DB_PORT', '3306')
os.environ.setdefault('DB_USER', 'test')
os.environ.setdefault('DB_PASS', 'test')
os.environ.setdefault('DB_NAME', 'test')
os.environ.setdefault('SECRET_KEY', 'test-only-secret-key-012345678901234567890123')

import app as application


class SecurityRegressionTests(unittest.TestCase):
    def setUp(self):
        application.app.config['TESTING'] = True
        self.client = application.app.test_client()

    def test_sensitive_api_rules_cover_all_non_public_api_routes(self):
        public = {'proses_pendaftaran', 'api_login_siswa', 'api_admin_login'}
        api_endpoints = {
            rule.endpoint for rule in application.app.url_map.iter_rules()
            if rule.rule.startswith('/api/')
        }
        self.assertEqual(api_endpoints - public, set(application.API_ROLE_RULES))

    def test_anonymous_sensitive_apis_are_rejected(self):
        checks = [
            ('post', '/api/update_status'),
            ('post', '/api/proses_pembayaran_custom'),
            ('post', '/api/hapus_transaksi/test'),
            ('get', '/api/print_formulir/test'),
            ('get', '/api/cek_riwayat_pembayaran/test'),
            ('get', '/api/get_pengeluaran/test'),
            ('post', '/api/simpan_setoran'),
        ]
        for method, path in checks:
            response = getattr(self.client, method)(path, json={} if method == 'post' else None)
            self.assertEqual(response.status_code, 401, path)

    def test_csrf_is_injected_and_enforced(self):
        page = self.client.get('/admin_login')
        self.assertEqual(page.status_code, 200)
        self.assertIn(b'name="csrf-token"', page.data)
        self.assertIn(b'name="csrf_token"', page.data)
        response = self.client.post('/admin_login', data={'username': 'x', 'password': 'x'})
        self.assertEqual(response.status_code, 400)


if __name__ == '__main__':
    unittest.main()
