File size: 4,948 Bytes
898ed62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Tests pour app.py — routes Flask."""

from io import BytesIO
from unittest.mock import patch, MagicMock


def test_index_returns_html(client):
    """GET / doit retourner une page HTML."""
    response = client.get("/")
    assert response.status_code == 200
    assert "text/html" in response.content_type


def test_upload_no_files(client):
    """POST /upload sans fichier doit retourner 400."""
    response = client.post("/upload", content_type="multipart/form-data")
    assert response.status_code == 400
    data = response.get_json()
    assert data["success"] is False
    assert "Aucun fichier" in data["error"]


def test_upload_single_file_success(client):
    """POST /upload avec un fichier valide doit retourner le markdown."""
    with patch("app.convert") as mock_convert, \
         patch("app.add_entry") as mock_add_entry:
        mock_convert.return_value = "# markdown converti"
        mock_add_entry.return_value = {
            "id": "1",
            "filename": "test.pdf",
            "markdown": "# markdown converti",
            "size": 18,
            "date": "12/05/2026 14:30",
        }

        data = {"files": (BytesIO(b"fake content"), "test.pdf")}
        response = client.post(
            "/upload",
            data=data,
            content_type="multipart/form-data",
        )

        assert response.status_code == 200
        json_data = response.get_json()
        assert json_data["success"] is True
        assert len(json_data["results"]) == 1
        assert json_data["results"][0]["filename"] == "test.pdf"
        assert json_data["results"][0]["markdown"] == "# markdown converti"
        assert json_data["errors"] == []


def test_upload_conversion_error(client):
    """POST /upload doit gérer les erreurs de conversion par fichier."""
    with patch("app.convert") as mock_convert:
        mock_convert.side_effect = Exception("Erreur de conversion pour test.xlsx : fichier corrompu")

        data = {"files": (BytesIO(b"fake xlsx"), "test.xlsx")}
        response = client.post(
            "/upload",
            data=data,
            content_type="multipart/form-data",
        )

        assert response.status_code == 200
        json_data = response.get_json()
        assert json_data["results"] == []
        assert len(json_data["errors"]) == 1
        assert json_data["errors"][0]["filename"] == "test.xlsx"
        assert "fichier corrompu" in json_data["errors"][0]["error"]


def test_history_route(client):
    """GET /history doit retourner la liste de l'historique."""
    mock_data = [{"id": "1", "filename": "doc.pdf"}]
    with patch("app.get_all", return_value=mock_data):
        response = client.get("/history")
        assert response.status_code == 200
        data = response.get_json()
        assert data["success"] is True
        assert data["data"] == mock_data


def test_download_not_found(client):
    """GET /download/<id> avec un id inexistant doit retourner 404."""
    with patch("app.get_entry", return_value=None):
        response = client.get("/download/999")
        assert response.status_code == 404
        data = response.get_json()
        assert data["success"] is False
        assert "introuvable" in data["error"]


def test_download_found(client):
    """GET /download/<id> doit retourner un fichier .md."""
    mock_entry = {
        "id": "1",
        "filename": "rapport.pdf",
        "markdown": "# Rapport\n\nContenu du rapport.",
    }
    with patch("app.get_entry", return_value=mock_entry), \
         patch("app.os.remove"):  # évite PermissionError Windows sur send_file
        response = client.get("/download/1")
        assert response.status_code == 200
        assert "text/markdown" in response.content_type
        assert "rapport.md" in response.headers["Content-Disposition"]
        assert b"# Rapport" in response.data


def test_copy_found(client):
    """GET /copy/<id> doit retourner le markdown dans le JSON."""
    mock_entry = {"id": "1", "markdown": "# Test copy"}
    with patch("app.get_entry", return_value=mock_entry):
        response = client.get("/copy/1")
        assert response.status_code == 200
        data = response.get_json()
        assert data["success"] is True
        assert data["markdown"] == "# Test copy"


def test_copy_not_found(client):
    """GET /copy/<id> avec id inexistant doit retourner 404."""
    with patch("app.get_entry", return_value=None):
        response = client.get("/copy/999")
        assert response.status_code == 404
        data = response.get_json()
        assert data["success"] is False


def test_clear_history(client):
    """POST /clear-history doit vider l'historique avec succès."""
    with patch("app.clear") as mock_clear:
        response = client.post("/clear-history")
        assert response.status_code == 200
        data = response.get_json()
        assert data["success"] is True
        mock_clear.assert_called_once()