From df3439351d60f1ba6abcb4df3c66784c7a9a02c8 Mon Sep 17 00:00:00 2001 From: Place Jean-Marie Date: Tue, 9 Nov 2021 08:21:52 +0100 Subject: [PATCH] ajout tests logos --- app/scodoc/sco_logos.py | 41 +++- tests/ressources/test_logos/logo_A.jpg | Bin 0 -> 39157 bytes tests/ressources/test_logos/logo_C.jpg | Bin 0 -> 2417 bytes tests/ressources/test_logos/logo_D.png | Bin 0 -> 15701 bytes tests/ressources/test_logos/logo_E.jpg | Bin 0 -> 2935 bytes tests/ressources/test_logos/logo_F.jpeg | Bin 0 -> 2882 bytes .../ressources/test_logos/logos_1/logo_A.jpg | Bin 0 -> 2730 bytes .../ressources/test_logos/logos_1/logo_B.jpg | Bin 0 -> 2832 bytes .../ressources/test_logos/logos_2/logo_A.jpg | Bin 0 -> 2703 bytes tests/unit/test_logos.py | 183 ++++++++++++++++++ 10 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 tests/ressources/test_logos/logo_A.jpg create mode 100644 tests/ressources/test_logos/logo_C.jpg create mode 100644 tests/ressources/test_logos/logo_D.png create mode 100644 tests/ressources/test_logos/logo_E.jpg create mode 100644 tests/ressources/test_logos/logo_F.jpeg create mode 100644 tests/ressources/test_logos/logos_1/logo_A.jpg create mode 100644 tests/ressources/test_logos/logos_1/logo_B.jpg create mode 100644 tests/ressources/test_logos/logos_2/logo_A.jpg create mode 100644 tests/unit/test_logos.py diff --git a/app/scodoc/sco_logos.py b/app/scodoc/sco_logos.py index 0737e7f0..dba5dc61 100644 --- a/app/scodoc/sco_logos.py +++ b/app/scodoc/sco_logos.py @@ -137,8 +137,6 @@ class Logo: self.logoname = secure_filename(logoname) self.scodoc_dept_id = dept_id self.prefix = prefix or "" - self.suffix = None - self.dimensions = None if self.scodoc_dept_id: self.dirpath = os.path.sep.join( [ @@ -151,8 +149,16 @@ class Logo: self.basepath = os.path.sep.join( [self.dirpath, self.prefix + secure_filename(self.logoname)] ) - self.filepath = None - self.filename = None + # next attributes are computer by the select function + self.suffix = "Not inited: call the select or create function before access" + self.filepath = "Not inited: call the select or create function before access" + self.filename = "Not inited: call the select or create function before access" + self.size = "Not inited: call the select or create function before access" + self.aspect_ratio = ( + "Not inited: call the select or create function before access" + ) + self.density = "Not inited: call the select or create function before access" + self.cm = "Not inited: call the select or create function before access" def _set_format(self, fmt): self.suffix = fmt @@ -182,6 +188,31 @@ class Logo: except IOError: pass + def _read_info(self, img): + """computes some properties from the real image + aspect_ratio assumes that x_density and y_density are equals + """ + x_size, y_size = img.size + self.density = img.info.get("dpi", None) + unit = 1 + if self.density is None: # no dpi found try jfif infos + self.density = img.info.get("jfif_density", None) + unit = img.info.get("jfif_unit", 0) # 0 = no unit ; 1 = inch ; 2 = cm + if self.density is not None: + x_density, y_density = self.density + if unit != 0: + unit2cm = [0, 1 / 2.54, 1][unit] + x_cm = round(x_size * unit2cm / x_density, 2) + y_cm = round(y_size * unit2cm / y_density, 2) + self.cm = (x_cm, y_cm) + else: + self.cm = None + else: + self.cm = None + + self.size = (x_size, y_size) + self.aspect_ratio = float(x_size) / y_size + def select(self): """ Récupération des données pour un logo existant @@ -195,7 +226,7 @@ class Logo: self._set_format(suffix) with open(self.filepath, "rb") as f: img = PILImage.open(f) - self.dimensions = img.size + self._read_info(img) return self return None diff --git a/tests/ressources/test_logos/logo_A.jpg b/tests/ressources/test_logos/logo_A.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f107a05b6075d40551a7f7e695b06ec9f0763bf GIT binary patch literal 39157 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

N>>8#`X%9MS21@~^ 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 Hu0mjfEZ>RB literal 0 HcmV?d00001 diff --git a/tests/ressources/test_logos/logo_E.jpg b/tests/ressources/test_logos/logo_E.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e97b78d07f6c1aa25929af8eaf478fcef68a2e5a GIT binary patch literal 2935 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 F{{>~3qf!6> literal 0 HcmV?d00001 diff --git a/tests/ressources/test_logos/logo_F.jpeg b/tests/ressources/test_logos/logo_F.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..c3750e29f2e44516d028f96c0a1a3ce181a42f63 GIT binary patch literal 2882 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 literal 0 HcmV?d00001 diff --git a/tests/ressources/test_logos/logos_1/logo_B.jpg b/tests/ressources/test_logos/logos_1/logo_B.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2ebb82823e3db7f757b5d29322b1e9efb0db2c94 GIT binary patch literal 2832 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 Xrl?*&eLha9q*r$u@mGi+S9|{lD=b$E literal 0 HcmV?d00001 diff --git a/tests/unit/test_logos.py b/tests/unit/test_logos.py new file mode 100644 index 00000000..8cf2e275 --- /dev/null +++ b/tests/unit/test_logos.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- + +"""Test Logos + + +Utiliser comme: + pytest tests/unit/test_logos.py + +""" +from io import BytesIO +from pathlib import Path +from shutil import copytree, copy, rmtree + +import pytest as pytest +from _pytest.python_api import approx + +import app +from app import db +from app.models import Departement +import app.scodoc.sco_utils as scu +from app.scodoc.sco_logos import find_logo, Logo, list_logos + +RESOURCES_DIR = "/opt/scodoc/tests/ressources/test_logos" + + +@pytest.fixture +def create_dept(test_client): + """Crée 2 départements: + return departements object + """ + dept1 = Departement(acronym="RT") + dept2 = Departement(acronym="INFO") + db.session.add(dept1) + db.session.add(dept2) + db.session.commit() + yield dept1, dept2 + db.session.delete(dept1) + db.session.delete(dept2) + db.session.commit() + + +@pytest.fixture +def create_logos(create_dept): + """Crée les logos: + ...logos --+-- logo_A.jpg + +-- logo_C.jpg + +-- logo_D.png + +-- logo_E.jpg + +-- logo_F.jpeg + +-- logos_{d1} --+-- logo_A.jpg + | +-- logo_B.jpg + +-- logos_{d2} --+-- logo_A.jpg + + """ + dept1, dept2 = create_dept + d1 = dept1.id + d2 = dept2.id + FILE_LIST = ["logo_A.jpg", "logo_C.jpg", "logo_D.png", "logo_E.jpg", "logo_F.jpeg"] + for fn in FILE_LIST: + from_path = Path(RESOURCES_DIR).joinpath(fn) + to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(fn) + copy(from_path.absolute(), to_path.absolute()) + copytree( + f"{RESOURCES_DIR}/logos_1", + f"{scu.SCODOC_LOGOS_DIR}/logos_{d1}", + ) + copytree( + f"{RESOURCES_DIR}/logos_2", + f"{scu.SCODOC_LOGOS_DIR}/logos_{d2}", + ) + yield None + rmtree(f"{scu.SCODOC_LOGOS_DIR}/logos_{d1}") + rmtree(f"{scu.SCODOC_LOGOS_DIR}/logos_{d2}") + # rm files + for fn in FILE_LIST: + to_path = Path(scu.SCODOC_LOGOS_DIR).joinpath(fn) + to_path.unlink() + + +def test_select_global_only(create_logos): + C_logo = app.scodoc.sco_logos.find_logo(logoname="C") + assert C_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logo_C.jpg" + + +def test_select_local_only(create_dept, create_logos): + dept1, dept2 = create_dept + B_logo = app.scodoc.sco_logos.find_logo(logoname="B", dept_id=dept1.id) + assert B_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_B.jpg" + + +def test_select_local_override_global(create_dept, create_logos): + dept1, dept2 = create_dept + A1_logo = app.scodoc.sco_logos.find_logo(logoname="A", dept_id=dept1.id) + assert A1_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_A.jpg" + + +def test_select_global_with_strict(create_dept, create_logos): + dept1, dept2 = create_dept + A_logo = app.scodoc.sco_logos.find_logo(logoname="A", dept_id=dept1.id, strict=True) + assert A_logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logos_{dept1.id}/logo_A.jpg" + + +def test_looks_for_non_existant_should_give_none(create_dept, create_logos): + # search for a local non-existant logo returns None + dept1, dept2 = create_dept + no_logo = app.scodoc.sco_logos.find_logo(logoname="Z", dept_id=dept1.id) + assert no_logo is None + + +def test_looks_localy_for_a_global_should_give_none(create_dept, create_logos): + # search for a local non-existant logo returns None + dept1, dept2 = create_dept + no_logo = app.scodoc.sco_logos.find_logo( + logoname="C", dept_id=dept1.id, strict=True + ) + assert no_logo is None + + +def test_get_jpg_data(create_dept, create_logos): + logo = find_logo("A", dept_id=None) + assert logo is not None + logo.select() + assert logo.logoname == "A" + assert logo.suffix == "jpg" + assert logo.filename == "A.jpg" + assert logo.size == (1200, 600) + assert logo.cm == approx((4.0, 3.0), 0.01) + + +def test_get_png_without_data(create_dept, create_logos): + logo = find_logo("D", dept_id=None) + assert logo is not None + logo.select() + assert logo.logoname == "D" + assert logo.suffix == "png" + assert logo.filename == "D.png" + assert logo.size == (121, 121) + assert logo.density is None + assert logo.cm is None + + +def test_create_globale_jpg_logo(create_dept, create_logos): + path = Path(f"{RESOURCES_DIR}/logo_C.jpg") + logo = Logo("X") # create global logo + stream = path.open("rb") + + +def test_create_jpg_instead_of_png_logo(create_dept, create_logos): + # action + logo = Logo("D") # create global logo (replace logo_D.png) + path = Path(f"{RESOURCES_DIR}/logo_C.jpg") + stream = path.open("rb") + logo.create(stream) + # test + created = Path(f"{scu.SCODOC_LOGOS_DIR}/logo_D.jpg") + removed = Path(f"{scu.SCODOC_LOGOS_DIR}/logo_D.png") + # file system check + assert created.exists() + assert not removed.exists() + # logo check + logo = find_logo("D") + assert logo is not None + assert logo.filepath == f"{scu.SCODOC_LOGOS_DIR}/logo_D.jpg" # created.absolute() + # restore initial state + original = Path(f"{RESOURCES_DIR}/logo_D.png") + copy(original, removed) + created.unlink(missing_ok=True) + + +def test_list_logo(create_dept, create_logos): + # test only existence of copied logos. We assumes that they are OK + dept1, dept2 = create_dept + logos = list_logos() + assert logos.keys() == {"_GLOBAL", "RT", "INFO"} + assert {"A", "C", "D", "E", "F", "header", "footer"}.issubset( + set(logos["_GLOBAL"].keys()) + ) + rt = logos.get("RT", None) + assert rt is not None + assert {"A", "B"}.issubset(set(rt.keys())) + info = logos.get("INFO", None) + assert info is not None + assert {"A"}.issubset(set(rt.keys()))