ajout tests logos

This commit is contained in:
Jean-Marie Place 2021-11-09 08:21:52 +01:00
parent b336a1c1a2
commit df3439351d
10 changed files with 219 additions and 5 deletions

View File

@ -137,8 +137,6 @@ class Logo:
self.logoname = secure_filename(logoname) self.logoname = secure_filename(logoname)
self.scodoc_dept_id = dept_id self.scodoc_dept_id = dept_id
self.prefix = prefix or "" self.prefix = prefix or ""
self.suffix = None
self.dimensions = None
if self.scodoc_dept_id: if self.scodoc_dept_id:
self.dirpath = os.path.sep.join( self.dirpath = os.path.sep.join(
[ [
@ -151,8 +149,16 @@ class Logo:
self.basepath = os.path.sep.join( self.basepath = os.path.sep.join(
[self.dirpath, self.prefix + secure_filename(self.logoname)] [self.dirpath, self.prefix + secure_filename(self.logoname)]
) )
self.filepath = None # next attributes are computer by the select function
self.filename = None 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): def _set_format(self, fmt):
self.suffix = fmt self.suffix = fmt
@ -182,6 +188,31 @@ class Logo:
except IOError: except IOError:
pass 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): def select(self):
""" """
Récupération des données pour un logo existant Récupération des données pour un logo existant
@ -195,7 +226,7 @@ class Logo:
self._set_format(suffix) self._set_format(suffix)
with open(self.filepath, "rb") as f: with open(self.filepath, "rb") as f:
img = PILImage.open(f) img = PILImage.open(f)
self.dimensions = img.size self._read_info(img)
return self return self
return None return None

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

183
tests/unit/test_logos.py Normal file
View File

@ -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()))