simplefe

Log | Files | Refs

test_app.py (7517B)


      1 import os
      2 
      3 import simplefe.app as app_module
      4 
      5 
      6 class ImmediateThread:
      7     def __init__(self, target=None, kwargs=None, daemon=None):
      8         self._target = target
      9         self._kwargs = kwargs or {}
     10 
     11     def start(self):
     12         self._target(**self._kwargs)
     13 
     14 
     15 def test_rip_index_shows_disc_info(client, auth_headers, monkeypatch):
     16     monkeypatch.setattr(
     17         app_module.makemkv,
     18         "query_disc",
     19         lambda: app_module.makemkv.DiscInfo(
     20             raw_id="ARRIVAL_2016", guessed_name="Arrival 2016", main_title=1
     21         ),
     22     )
     23     monkeypatch.setattr(
     24         app_module.makemkv, "find_existing_rip", lambda db, raw_id: None
     25     )
     26 
     27     response = client.get("/rip", headers=auth_headers)
     28     assert response.status_code == 200
     29     assert b"Arrival 2016" in response.data
     30     assert b"already been ripped" not in response.data
     31 
     32 
     33 def test_rip_index_skips_disc_query_while_job_running(client, auth_headers, monkeypatch):
     34     def fail_if_called():
     35         raise AssertionError("query_disc should not be called while a job is running")
     36 
     37     monkeypatch.setattr(app_module.makemkv, "query_disc", fail_if_called)
     38     client.application.config["JOB"]["running"] = True
     39 
     40     response = client.get("/rip", headers=auth_headers)
     41     assert response.status_code == 200
     42     assert b"already in progress" in response.data
     43 
     44 
     45 def test_rip_index_shows_duplicate_warning(client, auth_headers, monkeypatch):
     46     monkeypatch.setattr(
     47         app_module.makemkv,
     48         "query_disc",
     49         lambda: app_module.makemkv.DiscInfo(
     50             raw_id="ARRIVAL_2016", guessed_name="Arrival 2016", main_title=1
     51         ),
     52     )
     53     monkeypatch.setattr(
     54         app_module.makemkv,
     55         "find_existing_rip",
     56         lambda db, raw_id: {
     57             "title": "Arrival 2016",
     58             "output_file": "/x.mkv",
     59             "ripped_at": "now",
     60         },
     61     )
     62 
     63     response = client.get("/rip", headers=auth_headers)
     64     assert response.status_code == 200
     65     assert b"already been ripped" in response.data
     66 
     67 
     68 def test_rip_start_requires_movie_name(client, auth_headers, monkeypatch):
     69     monkeypatch.setattr(
     70         app_module.makemkv, "find_existing_rip", lambda db, raw_id: None
     71     )
     72     response = client.post(
     73         "/rip/start",
     74         data={"movie_name": "", "raw_id": "X", "title": "1"},
     75         headers=auth_headers,
     76     )
     77     assert response.status_code == 200
     78     assert b"Movie name is required" in response.data
     79 
     80 
     81 def test_rip_start_blocks_duplicate_without_override(client, auth_headers, monkeypatch):
     82     monkeypatch.setattr(
     83         app_module.makemkv,
     84         "find_existing_rip",
     85         lambda db, raw_id: {"title": "X", "output_file": "/x.mkv", "ripped_at": "now"},
     86     )
     87     response = client.post(
     88         "/rip/start",
     89         data={"movie_name": "Arrival 2016", "raw_id": "X", "title": "1"},
     90         headers=auth_headers,
     91     )
     92     assert response.status_code == 200
     93     assert b"already been ripped" in response.data
     94 
     95 
     96 def test_rip_start_allows_duplicate_with_override(client, auth_headers, monkeypatch):
     97     calls = []
     98     monkeypatch.setattr(
     99         app_module.makemkv,
    100         "find_existing_rip",
    101         lambda db, raw_id: {"title": "X", "output_file": "/x.mkv", "ripped_at": "now"},
    102     )
    103     monkeypatch.setattr(app_module.pipeline, "run", lambda **kwargs: calls.append(kwargs))
    104     monkeypatch.setattr(app_module.threading, "Thread", ImmediateThread)
    105 
    106     response = client.post(
    107         "/rip/start",
    108         data={
    109             "movie_name": "Arrival 2016",
    110             "raw_id": "X",
    111             "title": "1",
    112             "override_duplicate": "on",
    113         },
    114         headers=auth_headers,
    115     )
    116     assert response.status_code == 302
    117     assert len(calls) == 1
    118     assert calls[0]["movie_name"] == "Arrival 2016"
    119 
    120 
    121 def test_rip_start_rejects_when_already_running(client, auth_headers):
    122     client.application.config["JOB"]["running"] = True
    123     response = client.post(
    124         "/rip/start",
    125         data={"movie_name": "X", "raw_id": "Y", "title": "0"},
    126         headers=auth_headers,
    127     )
    128     assert response.status_code == 409
    129 
    130 
    131 def test_rip_status_shows_idle_message(client, auth_headers):
    132     response = client.get("/rip/status", headers=auth_headers)
    133     assert response.status_code == 200
    134     assert b"No rip has been started" in response.data
    135 
    136 
    137 def test_rip_status_shows_progress(client, auth_headers):
    138     client.application.config["JOB"].update(
    139         {
    140             "running": True,
    141             "stage": "encoding",
    142             "detail": "Encoding movie.mkv...",
    143             "error": None,
    144         }
    145     )
    146     response = client.get("/rip/status", headers=auth_headers)
    147     assert b"encoding" in response.data
    148     assert b"Encoding movie.mkv" in response.data
    149 
    150 
    151 def test_routes_require_auth(client):
    152     response = client.get("/rip")
    153     assert response.status_code == 401
    154 
    155 
    156 def _clear_setup_keys(monkeypatch):
    157     for key in app_module.SETUP_KEYS:
    158         monkeypatch.delenv(key, raising=False)
    159 
    160 
    161 def test_rip_index_shows_setup_banner_when_unconfigured(client, auth_headers, monkeypatch):
    162     _clear_setup_keys(monkeypatch)
    163     monkeypatch.setattr(
    164         app_module.makemkv,
    165         "query_disc",
    166         lambda: app_module.makemkv.DiscInfo(raw_id="", guessed_name="", main_title=0),
    167     )
    168     monkeypatch.setattr(
    169         app_module.makemkv, "find_existing_rip", lambda db, raw_id: None
    170     )
    171 
    172     response = client.get("/rip", headers=auth_headers)
    173     assert b"Set up now" in response.data
    174 
    175 
    176 def test_rip_index_hides_setup_banner_when_configured(client, auth_headers, monkeypatch):
    177     _clear_setup_keys(monkeypatch)
    178     monkeypatch.setenv("JELLYFIN_TOKEN", "jtok")
    179     monkeypatch.setenv("PUSHOVER_TOKEN", "ptok")
    180     monkeypatch.setenv("PUSHOVER_USER", "puser")
    181     monkeypatch.setattr(
    182         app_module.makemkv,
    183         "query_disc",
    184         lambda: app_module.makemkv.DiscInfo(raw_id="", guessed_name="", main_title=0),
    185     )
    186     monkeypatch.setattr(
    187         app_module.makemkv, "find_existing_rip", lambda db, raw_id: None
    188     )
    189 
    190     response = client.get("/rip", headers=auth_headers)
    191     assert b"Set up now" not in response.data
    192 
    193 
    194 def test_setup_get_shows_current_values(client, auth_headers, monkeypatch):
    195     _clear_setup_keys(monkeypatch)
    196     monkeypatch.setenv("JELLYFIN_TOKEN", "existing-jtok")
    197 
    198     response = client.get("/setup", headers=auth_headers)
    199     assert response.status_code == 200
    200     assert b"existing-jtok" in response.data
    201 
    202 
    203 def test_setup_post_saves_values_and_applies_immediately(client, auth_headers, monkeypatch):
    204     _clear_setup_keys(monkeypatch)
    205 
    206     response = client.post(
    207         "/setup",
    208         data={
    209             "JELLYFIN_TOKEN": "new-jtok",
    210             "PUSHOVER_TOKEN": "new-ptok",
    211             "PUSHOVER_USER": "new-puser",
    212         },
    213         headers=auth_headers,
    214     )
    215     assert response.status_code == 302
    216 
    217     assert os.environ["JELLYFIN_TOKEN"] == "new-jtok"
    218     assert os.environ["PUSHOVER_TOKEN"] == "new-ptok"
    219     assert os.environ["PUSHOVER_USER"] == "new-puser"
    220 
    221     dotenv_path = client.application.config["DOTENV_PATH"]
    222     content = open(dotenv_path).read()
    223     assert "new-jtok" in content
    224 
    225 
    226 def test_setup_post_blank_field_does_not_overwrite_existing_value(
    227     client, auth_headers, monkeypatch
    228 ):
    229     _clear_setup_keys(monkeypatch)
    230     monkeypatch.setenv("JELLYFIN_TOKEN", "keep-me")
    231 
    232     client.post(
    233         "/setup",
    234         data={"JELLYFIN_TOKEN": "", "PUSHOVER_TOKEN": "ptok", "PUSHOVER_USER": "puser"},
    235         headers=auth_headers,
    236     )
    237 
    238     assert os.environ["JELLYFIN_TOKEN"] == "keep-me"