Skip to content

Commit 96911c4

Browse files
committed
test
1 parent 67e7db8 commit 96911c4

File tree

4 files changed

+158
-13
lines changed

4 files changed

+158
-13
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from iosanita.contenttypes.interfaces import IoSanitaViewExtraData
2+
from iosanita.contenttypes.restapi.services.view_extra_data.extractor import (
3+
ViewExtraDataExtractor,
4+
)
5+
from irst.policy.content.at import IAT
6+
from zope.component import adapter
7+
from zope.interface import implementer
8+
from zope.interface import Interface
9+
10+
11+
@implementer(IoSanitaViewExtraData)
12+
@adapter(IAT, Interface)
13+
class ViewExtraDataExtractorAT(ViewExtraDataExtractor):
14+
def __call__(self):
15+
bando_view = self.context.restrictedTraverse("bando_view")
16+
return {
17+
# "approfondimenti": self.get_approfondimenti(),
18+
"stato_bando": bando_view.getBandoState(),
19+
}

src/iosanita/contenttypes/browser/export_view.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,30 @@
22
from io import BytesIO
33
from io import StringIO
44
from iosanita.contenttypes import _
5+
from PIL import Image
56
from plone import api
7+
from plone.memoize import forever
68
from Products.Five.browser import BrowserView
79
from weasyprint import HTML
810
from zExceptions import NotFound
911
from zope.interface import implementer
1012
from zope.publisher.interfaces import IPublishTraverse
11-
from plone.memoize import forever
13+
14+
import base64
1215
import csv
16+
import imghdr
1317
import importlib.resources
1418
import logging
1519
import re
16-
from PIL import Image
17-
import base64
18-
import imghdr
20+
1921

2022
logger = logging.getLogger(__name__)
2123

2224
fontools_logger = logging.getLogger("fontTools.subset")
2325
fontools_logger.setLevel(logging.WARNING)
2426

2527

26-
# @forever.memoize
28+
@forever.memoize
2729
def image_to_html(input_string):
2830
"""
2931
Convert image data to a base64 string formatted for HTML.

src/iosanita/contenttypes/browser/searchblock.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ def get_data(self):
138138
# 4. fare la ricerca
139139
# 5. fare export in csv/pdf a seconda del formato
140140
"""
141-
142141
# 2. Get columns, base filters and sorting
143142
columns = self.block_data.get("columns", [])
144143

@@ -195,13 +194,14 @@ def get_data(self):
195194
# XXX: consideriamo però che senza usare il serializzatore un utente potrebbe
196195
# chiedere qualsiasi atttributo degli oggetti, senza un controllo fine
197196
# sullo schema
198-
fullobjects = True
199-
self.request.form["b_size"] = 9999
200-
results = getMultiAdapter((results, self.request), ISerializeToJson)(
201-
fullobjects=fullobjects
202-
)
203-
for obj in results["items"]:
204-
yield [obj["title"]] + [obj.get(c["field"]) for c in columns]
197+
if results:
198+
fullobjects = True
199+
self.request.form["b_size"] = 9999
200+
results = getMultiAdapter((results, self.request), ISerializeToJson)(
201+
fullobjects=fullobjects
202+
)
203+
for obj in results["items"]:
204+
yield [obj["title"]] + [obj.get(c["field"]) for c in columns]
205205

206206
def get_columns(self, data):
207207
# Il titolo va aggiunto di default come prima colonna ?
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from ..testing import INTEGRATION_TESTING
2+
from plone import api
3+
from plone.app.testing import login
4+
from plone.app.testing import logout
5+
from plone.app.testing import setRoles
6+
from plone.app.testing import TEST_USER_ID
7+
from plone.app.testing import TEST_USER_NAME
8+
from plone.testing.z2 import Browser
9+
from transaction import commit
10+
from zope.component import getMultiAdapter
11+
12+
import csv
13+
import unittest
14+
import uuid
15+
16+
17+
class TestExport(unittest.TestCase):
18+
"""Test PDF export functionality"""
19+
20+
layer = INTEGRATION_TESTING
21+
22+
def setUp(self):
23+
self.app = self.layer["app"]
24+
self.portal = self.layer["portal"]
25+
self.request = self.layer["request"]
26+
self.portal_url = self.portal.absolute_url()
27+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
28+
login(self.portal, TEST_USER_NAME)
29+
30+
self.doc = api.content.create(
31+
container=self.portal,
32+
type="Document",
33+
id="test-document",
34+
title="Test Document",
35+
description="This is a test document",
36+
)
37+
api.content.transition(self.doc, to_state="published")
38+
commit()
39+
40+
self.browser = Browser(self.app)
41+
42+
def tearDown(self):
43+
api.content.delete(self.doc)
44+
commit()
45+
logout()
46+
47+
def test_pdf_export_view_exists(self):
48+
"""Test that the PDF export view is registered and accessible
49+
50+
TODO: view must be accessible only for IExportViewDownload context
51+
"""
52+
view = getMultiAdapter((self.doc, self.request), name="export_pdf")
53+
self.assertTrue(view is not None)
54+
55+
def test_searchblock_pdf(self):
56+
block_id = uuid.uuid4().hex
57+
self.doc.blocks = {
58+
block_id: {
59+
"@type": "search",
60+
"query": {
61+
"query": [
62+
{
63+
"i": "portal_type",
64+
"o": "plone.app.querystring.operation.selection.is",
65+
"v": "Document",
66+
}
67+
]
68+
},
69+
}
70+
}
71+
self.doc.blocks_layout = {"items": [block_id]}
72+
commit()
73+
74+
self.browser.open(
75+
f"{self.doc.absolute_url()}/searchblock/@@download/{block_id}.pdf"
76+
)
77+
78+
# Check response headers
79+
self.assertEqual(self.browser.headers["Content-Type"], "application/pdf")
80+
self.assertIn(
81+
"attachment;filename=", self.browser.headers["Content-Disposition"]
82+
)
83+
# Check that the response is not empty and looks like a PDF
84+
self.assertTrue(b"%PDF-" in self.browser.contents[:10])
85+
86+
# TODO
87+
# api.portal.get_tool("portal_transforms").convertTo("plain/text", self.browser.contents, mimetype="application/pdf")
88+
# oppure con pypdf
89+
90+
def test_searchblock_csv(self):
91+
block_id = uuid.uuid4().hex
92+
self.doc.blocks = {
93+
block_id: {
94+
"@type": "search",
95+
"query": {
96+
"query": [
97+
{
98+
"i": "portal_type",
99+
"o": "plone.app.querystring.operation.selection.is",
100+
"v": "Document",
101+
}
102+
]
103+
},
104+
}
105+
}
106+
self.doc.blocks_layout = {"items": [block_id]}
107+
commit()
108+
109+
self.browser.open(
110+
f"{self.doc.absolute_url()}/searchblock/@@download/{block_id}.csv"
111+
)
112+
113+
# Check response headers
114+
self.assertEqual(
115+
self.browser.headers["Content-Type"], "text/csv; charset=utf-8-sig"
116+
)
117+
self.assertIn(
118+
"attachment;filename=", self.browser.headers["Content-Disposition"]
119+
)
120+
121+
# Check that the response is a CSV with expected data
122+
reader = csv.DictReader(self.browser.contents)
123+
self.assertEqual(reader.fieldnames, ["Titolo"])
124+
self.assertEqual([row for row in reader], [{"Titolo": "Test Document"}])

0 commit comments

Comments
 (0)