sahil-12kumar/IL_CMS_Tools
1
1"""Route tests for the Custom Deck builder (/deckbuilder, /deckbuilder/build)."""2import importlib3import io4import json5import sys6 7import pytest8 9 10@pytest.fixture11def client_for(monkeypatch):12 def build(login=True):13 sys.modules.pop('app', None)14 app_mod = importlib.import_module('app')15 app_mod.app.config['TESTING'] = True16 c = app_mod.app.test_client()17 if login:18 with c.session_transaction() as s:19 s['app_authed'] = True20 return app_mod, c21 yield build22 sys.modules.pop('app', None)23 24 25@pytest.fixture26def png_bytes():27 from PIL import Image28 buf = io.BytesIO()29 Image.new('RGB', (160, 90), 'white').save(buf, 'PNG')30 return buf.getvalue()31 32 33def test_page_renders_when_logged_in(client_for):34 app_mod, c = client_for()35 r = c.get('/deckbuilder')36 assert r.status_code == 20037 assert b'Custom PPT Builder' in r.data38 39 40def test_page_requires_login(client_for):41 _, c = client_for(login=False)42 assert c.get('/deckbuilder').status_code == 302 # redirect to login43 44 45def test_build_simple_deck(client_for):46 _, c = client_for()47 deck = {'title': 'Test Deck', 'text_style': 'auto',48 'cover': {'enabled': True, 'title': 'Test Deck', 'subtitle': ''},49 'slides': [{'title': 'Slide one', 'body': ['Hello'], 'table': '',50 'notes': '', 'images': []}]}51 r = c.post('/deckbuilder/build',52 data={'deck': json.dumps(deck)},53 content_type='multipart/form-data')54 assert r.status_code == 20055 assert r.data[:2] == b'PK' # valid .pptx (zip)56 assert 'presentationml.presentation' in (r.content_type or '')57 58 59def test_build_with_image_and_caption(client_for, png_bytes):60 _, c = client_for()61 deck = {'title': 'Imaged', 'text_style': 'light-bg',62 'cover': {'enabled': False},63 'slides': [{'title': '', 'body': [], 'table': '', 'notes': '',64 'images': [{'caption': 'Radiograph'}]}]}65 r = c.post('/deckbuilder/build',66 data={'deck': json.dumps(deck),67 'img_0_0.png': (io.BytesIO(png_bytes), 'img_0_0.png')},68 content_type='multipart/form-data')69 assert r.status_code == 20070 assert r.data[:2] == b'PK'71 72 73def test_build_rejects_no_slides(client_for):74 _, c = client_for()75 r = c.post('/deckbuilder/build',76 data={'deck': json.dumps({'title': 'x', 'slides': []})},77 content_type='multipart/form-data')78 assert r.status_code == 40079 assert 'slide' in r.get_json()['error'].lower()80 81 82def test_build_rejects_caption_without_file(client_for, png_bytes):83 _, c = client_for()84 deck = {'title': 'x', 'slides': [{'title': 's', 'body': [], 'table': '',85 'notes': '', 'images': [{'caption': 'orphan'}]}]}86 r = c.post('/deckbuilder/build',87 data={'deck': json.dumps(deck)},88 content_type='multipart/form-data')89 assert r.status_code == 40090 assert 'caption but no uploaded file' in r.get_json()['error']91 92 93def test_build_rejects_garbage_image(client_for):94 _, c = client_for()95 deck = {'title': 'x', 'slides': [{'title': 's', 'body': [], 'table': '',96 'notes': '', 'images': [{'caption': ''}]}]}97 r = c.post('/deckbuilder/build',98 data={'deck': json.dumps(deck),99 'img_0_0.png': (io.BytesIO(b'not an image'), 'img_0_0.png')},100 content_type='multipart/form-data')101 assert r.status_code == 400102 assert 'not a readable image' in r.get_json()['error']103 104 105def test_build_rejects_wrong_image_field_name(client_for, png_bytes):106 _, c = client_for()107 deck = {'title': 'x', 'slides': [{'title': 's', 'images': []}]}108 r = c.post('/deckbuilder/build',109 data={'deck': json.dumps(deck),110 'something_else.png': (io.BytesIO(png_bytes), 'something_else.png')},111 content_type='multipart/form-data')112 assert r.status_code == 400113 assert 'Unrecognised image field' in r.get_json()['error']