File size: 4,706 Bytes
6bed18e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import pytest
from fastapi.testclient import TestClient
from backend.src.main import app
from backend.src.auth.security import create_access_token


def test_unauthorized_access_without_token():
    """Test that requests without tokens return 401 Unauthorized"""
    client = TestClient(app)

    # Try to access a protected endpoint without a token
    response = client.get("/api/v1/tasks/test_user")

    assert response.status_code == 401
    assert "WWW-Authenticate" in response.headers
    assert response.json()["detail"] == "No authorization token provided"


def test_unauthorized_access_with_invalid_token():
    """Test that requests with invalid tokens return 401 Unauthorized"""
    client = TestClient(app)

    # Try to access a protected endpoint with an invalid token
    response = client.get(
        "/api/v1/tasks/test_user",
        headers={"Authorization": "Bearer invalid_token_here"}
    )

    assert response.status_code == 401
    assert "WWW-Authenticate" in response.headers
    assert response.json()["detail"] == "Invalid authentication credentials"


def test_unauthorized_access_with_malformed_token():
    """Test that requests with malformed tokens return 401 Unauthorized"""
    client = TestClient(app)

    # Try to access a protected endpoint with a malformed token
    response = client.get(
        "/api/v1/tasks/test_user",
        headers={"Authorization": "Bearer malformed.token.format"}
    )

    assert response.status_code == 401
    assert "WWW-Authenticate" in response.headers
    assert response.json()["detail"] == "Invalid authentication credentials"


def test_unauthorized_access_to_protected_endpoints():
    """Test that all protected endpoints return 401 when accessed without tokens"""
    client = TestClient(app)

    # Test GET tasks for user
    response_get = client.get("/api/v1/tasks/test_user")
    assert response_get.status_code == 401

    # Test POST to create task
    response_post = client.post(
        "/api/v1/tasks/",
        json={"title": "Test", "user_id": "test_user"}
    )
    assert response_post.status_code == 401

    # Test PUT to update task
    response_put = client.put(
        "/api/v1/tasks/1",
        json={"title": "Updated Test"}
    )
    assert response_put.status_code == 401

    # Test PATCH to toggle task
    response_patch = client.patch("/api/v1/tasks/1/toggle")
    assert response_patch.status_code == 401

    # Test DELETE task
    response_delete = client.delete("/api/v1/tasks/1")
    assert response_delete.status_code == 401


def test_authorized_access_with_valid_token():
    """Test that requests with valid tokens are allowed"""
    client = TestClient(app)

    # Create a valid token
    user_data = {"user_id": "valid_user", "role": "user"}
    token = create_access_token(data=user_data)

    # Access endpoint with valid token (should succeed or return 404 if no tasks exist)
    response = client.get(
        "/api/v1/tasks/valid_user",
        headers={"Authorization": f"Bearer {token}"}
    )

    # Should be authorized (might return 200 or 404 depending on if tasks exist)
    assert response.status_code in [200, 404]


def test_token_format_validation():
    """Test that various invalid token formats return 401"""
    client = TestClient(app)

    invalid_formats = [
        "",  # Empty token
        "Bearer",  # Missing token
        "Bearer ",  # Space instead of token
        "Basic token",  # Wrong scheme
        "Bearer token with spaces",  # Token with spaces
    ]

    for auth_header in invalid_formats:
        response = client.get(
            "/api/v1/tasks/test_user",
            headers={"Authorization": auth_header} if auth_header else {}
        )

        # If no header at all, it should return 401 for missing token
        # If invalid format, it should return 401 for invalid token
        assert response.status_code == 401, f"Failed for format: '{auth_header}'"


def test_expired_token_handling():
    """Test that expired tokens return 401"""
    from backend.src.auth.security import create_access_token
    from datetime import timedelta

    client = TestClient(app)

    # Create an expired token
    user_data = {"user_id": "expired_user", "role": "user"}
    expired_token = create_access_token(data=user_data, expires_delta=timedelta(seconds=-1))

    # Try to access with expired token
    response = client.get(
        "/api/v1/tasks/expired_user",
        headers={"Authorization": f"Bearer {expired_token}"}
    )

    # Should return 401 for expired token
    assert response.status_code == 401
    assert response.json()["detail"] == "Invalid or expired token"


if __name__ == "__main__":
    pytest.main([__file__])