diff --git a/conservancy_beancount/reports/core.py b/conservancy_beancount/reports/core.py index cac844cb902556133c06bc18ab9743f39f646322..39438f4e4d93581ff74aebb1de36c3047eeb4d03 100644 --- a/conservancy_beancount/reports/core.py +++ b/conservancy_beancount/reports/core.py @@ -1172,7 +1172,7 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta): # '..' pops the ODS filename off the link path. In other words, # make the link relative to the directory the ODS is in. href_path = Path('..', href) - href = str(href_path) + href = urlparse.quote(str(href_path)) text = href_path.name else: rt_path = urlparse.urlparse(rt_href).path diff --git a/tests/test_reports_spreadsheet.py b/tests/test_reports_spreadsheet.py index 99342ababe84b3736ed4052118e7c20c030aa24c..648ebe9f1c8b341588d379b8fbedf13142647107 100644 --- a/tests/test_reports_spreadsheet.py +++ b/tests/test_reports_spreadsheet.py @@ -617,6 +617,7 @@ def test_ods_writer_meta_links_cell(ods_writer): 'rt://ticket/2/attachments/9', 'rt:1/5', 'Invoices/0123.pdf', + 'Invoice #789.pdf', ] cell = ods_writer.meta_links_cell(meta_links, stylename='meta1') assert cell.getAttribute('valuetype') == 'string' @@ -642,6 +643,10 @@ def test_ods_writer_meta_links_cell(ods_writer): expect_url = f'../{meta_links[3]}' assert child.getAttribute('href') == expect_url assert get_text(child) == '0123.pdf' + child = next(children) + assert child.getAttribute('type') == 'simple' + assert child.getAttribute('href') == '../Invoice%20%23789.pdf' + assert get_text(child) == 'Invoice #789.pdf' def test_ods_writer_multiline_cell(ods_writer): cell = ods_writer.multiline_cell(iter(STRING_CELL_DATA))