File size: 8,215 Bytes
a5784e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
"""
Tests for Auth Files API Router

Covers: GET /api/auth/files, GET /api/auth/active,
        POST /api/auth/activate, DELETE /api/auth/deactivate
"""

import json
from pathlib import Path
from unittest.mock import patch

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

from api_utils.routers.auth_files import (
    ActivateRequest,
    AuthFileInfo,
    AuthFilesResponse,
    router,
)


@pytest.fixture
def app() -> FastAPI:
    """Create test FastAPI app with auth_files router."""
    app = FastAPI()
    app.include_router(router)
    return app


@pytest.fixture
def client(app: FastAPI) -> TestClient:
    """Create test client."""
    return TestClient(app)


@pytest.fixture
def mock_auth_dirs(tmp_path: Path) -> tuple[Path, Path]:
    """Create mock auth directories with test files."""
    active_dir = tmp_path / "active"
    saved_dir = tmp_path / "saved"
    active_dir.mkdir()
    saved_dir.mkdir()

    # Create test auth files
    test_auth = {"token": "test123", "expires": "2025-12-31"}
    (saved_dir / "user1.json").write_text(json.dumps(test_auth))
    (saved_dir / "user2.json").write_text(json.dumps(test_auth))

    return active_dir, saved_dir


class TestAuthFileModels:
    """Tests for auth file models."""

    def test_auth_file_info_model(self) -> None:
        """Test AuthFileInfo model."""
        info = AuthFileInfo(
            name="test.json",
            path="/path/to/test.json",
            size_bytes=1024,
            is_active=True,
        )
        assert info.name == "test.json"
        assert info.is_active is True

    def test_auth_files_response_model(self) -> None:
        """Test AuthFilesResponse model."""
        response = AuthFilesResponse(
            saved_files=[
                AuthFileInfo(name="a.json", path="/a.json", size_bytes=100),
            ],
            active_file="a.json",
        )
        assert len(response.saved_files) == 1
        assert response.active_file == "a.json"

    def test_activate_request_model(self) -> None:
        """Test ActivateRequest model."""
        req = ActivateRequest(filename="test.json")
        assert req.filename == "test.json"


class TestListAuthFiles:
    """Tests for GET /api/auth/files endpoint."""

    def test_list_auth_files_empty(self, client: TestClient, tmp_path: Path) -> None:
        """Test listing files when directories are empty."""
        active_dir = tmp_path / "active"
        saved_dir = tmp_path / "saved"
        active_dir.mkdir()
        saved_dir.mkdir()

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.get("/api/auth/files")
            assert response.status_code == 200
            data = response.json()
            assert data["saved_files"] == []
            assert data["active_file"] is None

    def test_list_auth_files_with_files(
        self, client: TestClient, mock_auth_dirs: tuple[Path, Path]
    ) -> None:
        """Test listing files when files exist."""
        active_dir, saved_dir = mock_auth_dirs

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.get("/api/auth/files")
            assert response.status_code == 200
            data = response.json()
            assert len(data["saved_files"]) == 2
            names = [f["name"] for f in data["saved_files"]]
            assert "user1.json" in names
            assert "user2.json" in names


class TestGetActiveAuth:
    """Tests for GET /api/auth/active endpoint."""

    def test_get_active_auth_none(self, client: TestClient, tmp_path: Path) -> None:
        """Test getting active auth when none is active."""
        active_dir = tmp_path / "active"
        saved_dir = tmp_path / "saved"
        active_dir.mkdir()
        saved_dir.mkdir()

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.get("/api/auth/active")
            assert response.status_code == 200
            assert response.json()["active_file"] is None

    def test_get_active_auth_exists(self, client: TestClient, tmp_path: Path) -> None:
        """Test getting active auth when one is active."""
        active_dir = tmp_path / "active"
        saved_dir = tmp_path / "saved"
        active_dir.mkdir()
        saved_dir.mkdir()
        (active_dir / "current.json").write_text("{}")

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.get("/api/auth/active")
            assert response.status_code == 200
            assert response.json()["active_file"] == "current.json"


class TestActivateAuth:
    """Tests for POST /api/auth/activate endpoint."""

    def test_activate_auth_file(
        self, client: TestClient, mock_auth_dirs: tuple[Path, Path]
    ) -> None:
        """Test activating an auth file."""
        active_dir, saved_dir = mock_auth_dirs

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.post(
                "/api/auth/activate",
                json={"filename": "user1.json"},
            )
            assert response.status_code == 200
            data = response.json()
            assert data["success"] is True
            assert data["active_file"] == "user1.json"

            # Verify file was copied
            assert (active_dir / "user1.json").exists()

    def test_activate_auth_file_not_found(
        self, client: TestClient, mock_auth_dirs: tuple[Path, Path]
    ) -> None:
        """Test activating non-existent file returns 404."""
        active_dir, saved_dir = mock_auth_dirs

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.post(
                "/api/auth/activate",
                json={"filename": "nonexistent.json"},
            )
            assert response.status_code == 404


class TestDeactivateAuth:
    """Tests for DELETE /api/auth/deactivate endpoint."""

    def test_deactivate_auth(self, client: TestClient, tmp_path: Path) -> None:
        """Test deactivating current auth."""
        active_dir = tmp_path / "active"
        saved_dir = tmp_path / "saved"
        active_dir.mkdir()
        saved_dir.mkdir()
        (active_dir / "current.json").write_text("{}")

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.delete("/api/auth/deactivate")
            assert response.status_code == 200
            data = response.json()
            assert data["success"] is True

            # Verify file was removed
            assert not (active_dir / "current.json").exists()

    def test_deactivate_auth_none_active(
        self, client: TestClient, tmp_path: Path
    ) -> None:
        """Test deactivating when no auth is active."""
        active_dir = tmp_path / "active"
        saved_dir = tmp_path / "saved"
        active_dir.mkdir()
        saved_dir.mkdir()

        with (
            patch("api_utils.routers.auth_files.ACTIVE_AUTH_DIR", str(active_dir)),
            patch("api_utils.routers.auth_files.SAVED_AUTH_DIR", str(saved_dir)),
        ):
            response = client.delete("/api/auth/deactivate")
            assert response.status_code == 200
            # Should succeed even if nothing to remove
            assert response.json()["success"] is True