Skip to content

Commit 5f924d1

Browse files
committed
fix issues in existing code
1 parent 980a908 commit 5f924d1

3 files changed

Lines changed: 61 additions & 95 deletions

File tree

reflex/app.py

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,7 @@
8989
replace_brackets_with_keywords,
9090
verify_route_validity,
9191
)
92-
from reflex.sitemap import (
93-
check_sitemap_file_exists,
94-
generate_links_for_sitemap,
95-
generate_static_sitemap,
96-
read_sitemap_file,
97-
)
92+
from reflex.sitemap import generate_sitemaps, read_sitemap_file
9893
from reflex.state import (
9994
BaseState,
10095
RouterData,
@@ -470,12 +465,6 @@ def __post_init__(self):
470465
# Set up the admin dash.
471466
self._setup_admin_dash()
472467

473-
# sitemap generation
474-
links = generate_links_for_sitemap(
475-
pages=self.get_pages(), sitemap_properties=self.get_sitemap_properties()
476-
)
477-
generate_static_sitemap(links)
478-
479468
if sys.platform == "win32" and not is_prod_mode():
480469
# Hack to fix Windows hot reload issue.
481470
from reflex.utils.compat import windows_hot_reload_lifespan_hack
@@ -611,14 +600,7 @@ async def serve_sitemap(self) -> Response:
611600
Returns:
612601
Response: An HTTP response with the XML sitemap content and the media type set to "application/xml".
613602
"""
614-
if not check_sitemap_file_exists():
615-
links_sitemaps = generate_links_for_sitemap(
616-
pages=self.get_pages(), sitemap_properties=self.get_sitemap_properties()
617-
)
618-
generate_static_sitemap(links_sitemaps)
619-
620603
sitemaps = read_sitemap_file()
621-
622604
return Response(content=sitemaps, media_type="application/xml")
623605

624606
def _add_optional_endpoints(self):
@@ -766,7 +748,7 @@ def add_page(
766748
)
767749

768750
# Setup dynamic args for the route.
769-
# this state assignment is only required for tests using the deprecated state kwarg for App
751+
# This state assignment is only required for tests using the deprecated state kwarg for App
770752
state = self._state if self._state else State
771753
state.setup_dynamic_args(get_route_args(route))
772754

@@ -815,14 +797,6 @@ def _compile_page(self, route: str, save_page: bool = True):
815797
if save_page:
816798
self._pages[route] = component
817799

818-
def get_pages(self) -> dict[str, Component]:
819-
"""Get the pages of the app.
820-
821-
Returns:
822-
The pages of the app.
823-
"""
824-
return self._pages
825-
826800
def get_sitemap_properties(self) -> Dict[str, Dict]:
827801
"""Get the sitemap properties."""
828802
return self._sitemap_properties
@@ -1108,6 +1082,9 @@ def _compile(self, export: bool = False):
11081082

11091083
self._pages = {}
11101084

1085+
# generate sitemaps from sitemap properties
1086+
generate_sitemaps(self._sitemap_properties)
1087+
11111088
def get_compilation_time() -> str:
11121089
return str(datetime.now().time()).split(".")[0]
11131090

reflex/sitemap.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from xml.dom import minidom
66
from xml.etree.ElementTree import Element, SubElement, tostring
77

8-
from reflex import Component, constants
8+
from reflex import constants
99
from reflex.config import get_config
1010
from reflex.utils import prerequisites
1111

@@ -61,46 +61,54 @@ def generate_xml(links: List[Dict[str, str]]) -> str:
6161
return reparsed.toprettyxml(indent=" ")
6262

6363

64+
def generate_sitemaps(sitemap_config: Dict[str, Dict[str, str]]) -> None:
65+
"""Generate the sitemap.xml file.
66+
67+
This function generates the sitemap.xml file by crawling through the available pages in the app and generating a list
68+
of links with their respective sitemap properties such as location (URL), change frequency, and priority. Dynamic
69+
routes and the 404 page are excluded from the sitemap.
70+
71+
Args:
72+
sitemap_config: A dictionary containing the sitemap properties for each route.
73+
"""
74+
links = generate_links_for_sitemap(sitemap_config)
75+
generate_static_sitemap(links)
76+
77+
6478
def generate_links_for_sitemap(
65-
pages: Dict[str, Component], sitemap_properties: Dict[str, Dict]
79+
sitemap_config: Dict[str, Dict[str, str]],
6680
) -> List[dict[str, str]]:
6781
"""Generate a list of links for which sitemaps are generated.
6882
69-
This function loops through the registered routes in the app and generates a list of
70-
links with their respective sitemap properties such as location (URL), change frequency,
71-
and priority. Dynamic routes and the 404 page are excluded from the sitemap.
83+
This function loops through sitemap_config and generates a list of links with their respective sitemap properties
84+
such as location (URL), change frequency, and priority. Dynamic routes and the 404 page are excluded from the
85+
sitemap.
7286
7387
Args:
74-
pages: dictionary contains the components for each registered route in the app.
75-
sitemap_properties: dictionary containing the sitemap properties for each route.
88+
sitemap_config: A dictionary containing the sitemap properties for each route.
7689
7790
Returns:
78-
List: A list of dictionaries where each dictionary contains the 'loc' (URL of the page), 'priority' and
91+
List: A list of dictionaries where each dictionary contains the 'loc' (URL of the page), 'priority' and
7992
'changefreq' of each route.
8093
"""
8194
links = []
8295

8396
# find link of pages that are not dynamicaly created.
84-
for route in pages:
97+
for route in sitemap_config:
8598
# Ignore dynamic routes and 404
8699
if ("[" in route and "]" in route) or route == "404":
87100
continue
88101

102+
sitemap_changefreq = sitemap_config[route]["changefreq"]
103+
sitemap_priority = sitemap_config[route]["priority"]
104+
89105
# Handle the index route
90106
if route == "index":
91107
route = "/"
92108

93109
if not route.startswith("/"):
94110
route = f"/{route}"
95111

96-
sitemap_changefreq = constants.DefaultPage.SITEMAP_CHANGEFREQ # default value
97-
sitemap_priority = constants.DefaultPage.SITEMAP_PRIORITY # default value
98-
99-
# extract sitemap properties from the app's property, route exist in the compiled pages.
100-
if route in sitemap_properties:
101-
sitemap_priority = sitemap_properties[route]["priority"]
102-
sitemap_changefreq = sitemap_properties[route]["changefreq"]
103-
104112
if (
105113
sitemap_priority == constants.DefaultPage.SITEMAP_PRIORITY
106114
): # indicates that user didn't set priority
@@ -136,13 +144,3 @@ def generate_static_sitemap(links: List[Dict[str, str]]) -> None:
136144
# file.
137145
with _sitemap_file_path.open("w") as f:
138146
f.write(sitemap)
139-
140-
141-
def remove_sitemap_file() -> None:
142-
"""Remove the sitemap file, if a regeneration is needed.
143-
144-
Generally for testing the generation of sitemap.xml file, we need to remove the automatically generated file
145-
when the app is initialized.
146-
"""
147-
if _sitemap_file_path.exists():
148-
_sitemap_file_path.unlink()

tests/units/test_sitemap.py

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import unittest.mock
22
from pathlib import Path
33

4-
import fastapi
54
import pytest
65
import reflex as rx
76
from reflex import Component, constants
@@ -10,7 +9,6 @@
109
generate_links_for_sitemap,
1110
generate_static_sitemap,
1211
generate_xml,
13-
remove_sitemap_file,
1412
)
1513
from reflex.utils import prerequisites
1614

@@ -90,7 +88,7 @@ def test_generate_xml():
9088

9189

9290
def test_generate_static_sitemaps(app_instance, index_page, about_page):
93-
"""Test the creation of sitemap.xml through generate_static_sitemaps function."""
91+
"""Test if the generated sitemap file is currently stored in static website or not."""
9492
pages = {"index": index_page, "about": about_page}
9593
# remove the sitemap.xml file if it exists.
9694
sitemap_file_path.unlink(missing_ok=True)
@@ -104,49 +102,17 @@ def test_generate_static_sitemaps(app_instance, index_page, about_page):
104102
assert sitemap_file_path.exists() # check if the sitemap.xml file exists.
105103

106104

107-
# Unit test for `serve_sitemap`
108-
@pytest.mark.asyncio
109-
async def test_serve_sitemap(app_instance, index_page, about_page):
110-
"""Test if the correct response is returned when the `serve_sitemap` method is called."""
111-
pages = {"index": index_page, "about": about_page}
112-
113-
# because app_instance automatically generates sitemap.xml from empty _pages dictionary, we need to remove this file.
114-
remove_sitemap_file()
115-
116-
# mock self._pages to return the dictionary pages.
117-
with unittest.mock.patch.object(app_instance, "_pages", pages):
118-
# Call the `serve_sitemap` method
119-
response: fastapi.Response = await app_instance.serve_sitemap()
120-
121-
# Assert that the response is of type `Response`
122-
assert isinstance(response, fastapi.Response)
123-
# Assert the content type is 'application/xml'
124-
assert response.media_type == "application/xml"
125-
126-
# Convert memoryview to bytes explicitly (if it's a memoryview)
127-
if isinstance(response.body, memoryview):
128-
response_body = response.body.tobytes().decode("utf-8")
129-
else:
130-
# If it's already bytes, decode directly
131-
response_body = response.body.decode("utf-8")
132-
133-
# Assert that the XML content is correct (mocked value)
134-
assert response_body == mock_xml
135-
136-
137-
def test_generate_links_for_sitemap(app_instance, index_page, about_page):
138-
# Add pages to the app
139-
140-
pages = {"index": index_page, "about": index_page}
105+
def test_generate_links_for_sitemap():
106+
"""Test if the links are generated correctly for the sitemap from the sitemap config file when no deploy url is
107+
given.
108+
"""
141109
sitemap_properties = {
142110
"index": {"priority": 0.9, "changefreq": "weekly"},
143111
"about": {"priority": 0.9, "changefreq": "weekly"},
144112
}
145113

146-
# mock self._pages to return the dictionary pages.
147-
# with unittest.mock.patch.object(app_instance, "get_pages", pages) and unittest.mock.patch.object(app_instance, "_sitemap_properties", sitemap_properties):
114+
links = generate_links_for_sitemap(sitemap_properties)
148115

149-
links = generate_links_for_sitemap(pages, sitemap_properties)
150116
# Assert that the links are generated correctly
151117
assert links == [
152118
{"loc": "http://localhost:3000/", "changefreq": "weekly", "priority": 0.9},
@@ -156,3 +122,28 @@ def test_generate_links_for_sitemap(app_instance, index_page, about_page):
156122
"priority": 0.9,
157123
},
158124
]
125+
126+
127+
def test_generate_links_for_sitemap_deploy_url():
128+
"""Test if the links are generated correctly for the sitemap from the sitemap config file when a deploy url is
129+
given.
130+
"""
131+
sitemap_properties = {
132+
"index": {"priority": 0.9, "changefreq": "weekly"},
133+
"about": {"priority": 0.9, "changefreq": "weekly"},
134+
}
135+
136+
with unittest.mock.patch("reflex.sitemap.get_config") as mock_get_config:
137+
mock_get_config().deploy_url = "http://www.google.com"
138+
139+
links = generate_links_for_sitemap(sitemap_properties)
140+
141+
# Assert that the links are generated correctly
142+
assert links == [
143+
{"loc": "http://www.google.com/", "changefreq": "weekly", "priority": 0.9},
144+
{
145+
"loc": "http://www.google.com/about",
146+
"changefreq": "weekly",
147+
"priority": 0.9,
148+
},
149+
]

0 commit comments

Comments
 (0)