def test_homepage_section_custom_html(self): frappe.get_doc({ 'doctype': 'Homepage Section', 'name': 'Custom HTML Section', 'section_based_on': 'Custom HTML', 'section_html': '<div class="custom-section">My custom html</div>', }).insert() set_request(method='GET', path='home') response = render() self.assertEquals(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, 'html.parser') sections = soup.find('main').find_all(class_='custom-section') self.assertEqual(len(sections), 1) homepage_section = sections[0] self.assertEqual(homepage_section.text, 'My custom html') # cleanup frappe.db.rollback()
def test_category_link(self): # Make a temporary Blog Post (and a Blog Category) blog = make_test_blog() # Visit the blog post page set_request(path=blog.route) blog_page_response = render() blog_page_html = frappe.safe_decode(blog_page_response.get_data()) # On blog post page find link to the category page soup = BeautifulSoup(blog_page_html, "lxml") category_page_link = list( soup.find_all('a', href=re.compile(blog.blog_category)))[0] category_page_url = category_page_link["href"] # Visit the category page (by following the link found in above stage) set_request(path=category_page_url) category_page_response = render() category_page_html = frappe.safe_decode( category_page_response.get_data()) # Category page should contain the blog post title self.assertIn(blog.title, category_page_html) # Cleanup afterwords frappe.delete_doc("Blog Post", blog.name) frappe.delete_doc("Blog Category", blog.blog_category)
def test_homepage_section_custom_html(self): frappe.get_doc({ "doctype": "Homepage Section", "name": "Custom HTML Section", "section_based_on": "Custom HTML", "section_html": '<div class="custom-section">My custom html</div>', }).insert() set_request(method="GET", path="home") response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, "html.parser") sections = soup.find("main").find_all(class_="custom-section") self.assertEqual(len(sections), 1) homepage_section = sections[0] self.assertEqual(homepage_section.text, "My custom html") # cleanup frappe.db.rollback()
def test_meta_tag_generation(self): blogs = frappe.get_all("Blog Post", fields=["name", "route"], filters={ "published": 1, "route": ("!=", "") }, limit=1) blog = blogs[0] # create meta tags for this route doc = frappe.new_doc("Website Route Meta") doc.append("meta_tags", {"key": "type", "value": "blog_post"}) doc.append("meta_tags", {"key": "og:title", "value": "My Blog"}) doc.name = blog.route doc.insert() # set request on this route set_request(path=blog.route) response = render() self.assertTrue(response.status_code, 200) html = response.get_data().decode() self.assertTrue("""<meta name="type" content="blog_post">""" in html) self.assertTrue( """<meta property="og:title" content="My Blog">""" in html)
def add_route_to_global_search(route): from frappe.website.render import render_page from frappe.utils import set_request frappe.set_user('Guest') frappe.local.no_cache = True try: set_request(method='GET', path=route) content = render_page(route) soup = BeautifulSoup(content, 'html.parser') page_content = soup.find(class_='page_content') text_content = page_content.text if page_content else '' title = soup.title.text.strip() if soup.title else route value = dict(doctype='Static Web Page', name=route, content=text_content, published=1, title=title, route=route) sync_value_in_queue(value) except (frappe.PermissionError, frappe.DoesNotExistError, frappe.ValidationError, Exception): pass frappe.set_user('Administrator')
def get_document_to_index(self, route): """Render a page and parse it using BeautifulSoup Args: path (str): route of the page to be parsed Returns: document (_dict): A dictionary with title, path and content """ frappe.set_user("Guest") frappe.local.no_cache = True try: set_request(method="GET", path=route) content = get_response_content(route) soup = BeautifulSoup(content, "html.parser") page_content = soup.find(class_="page_content") text_content = page_content.text if page_content else "" title = soup.title.text.strip() if soup.title else route return frappe._dict(title=title, content=text_content, path=route) except Exception: pass finally: frappe.set_user("Administrator")
def add_route_to_global_search(route): from bs4 import BeautifulSoup from frappe.website.serve import get_response_content from frappe.utils import set_request frappe.set_user('Guest') frappe.local.no_cache = True try: set_request(method='GET', path=route) content = get_response_content(route) soup = BeautifulSoup(content, 'html.parser') page_content = soup.find(class_='page_content') text_content = page_content.text if page_content else '' title = soup.title.text.strip() if soup.title else route value = dict(doctype='Static Web Page', name=route, content=text_content, published=1, title=title, route=route) sync_value_in_queue(value) except Exception: pass frappe.set_user('Administrator')
def test_meta_tag_generation(self): blogs = frappe.get_all('Blog Post', fields=['name', 'route'], filters={'published': 1, 'route': ('!=', '')}, limit=1) blog = blogs[0] # create meta tags for this route doc = frappe.new_doc('Website Route Meta') doc.append('meta_tags', { 'key': 'type', 'value': 'blog_post' }) doc.append('meta_tags', { 'key': 'og:title', 'value': 'My Blog' }) doc.name = blog.route doc.insert() # set request on this route set_request(path=blog.route) response = render() self.assertTrue(response.status_code, 200) html = response.get_data().decode() self.assertTrue('''<meta name="type" content="blog_post">''' in html) self.assertTrue('''<meta property="og:title" content="My Blog">''' in html)
def test_caching(self): # to enable caching frappe.flags.force_website_cache = True print(frappe.session.user) clear_website_cache() # first response no-cache pages = frappe.get_all('Blog Post', fields=['name', 'route'], filters={ 'published': 1, 'title': "_Test Blog Post" }, limit=1) route = pages[0].route set_request(path=route) # response = get_response() response = get_response() # TODO: enable this assert # self.assertIn(('X-From-Cache', 'False'), list(response.headers)) set_request(path=route) response = get_response() self.assertIn(('X-From-Cache', 'True'), list(response.headers)) frappe.flags.force_website_cache = True
def test_homepage_load(self): set_request(method="GET", path="home") response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue('<section class="hero-section' in html)
def test_homepage_load(self): set_request(method='GET', path='home') response = render() self.assertEquals(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue('<section class="hero-section' in html)
def test_app(self): frappe.set_user('Administrator') set_request(method='GET', path='/app') response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue('window.app = true;' in html) frappe.local.session_obj = None
def create_http_request(): """Get http request object.""" set_request(method="POST", path="login") enable_2fa() frappe.form_dict["usr"] = "******" frappe.form_dict["pwd"] = "Eastern_43A1W" frappe.local.form_dict["cmd"] = "login" http_requests = HTTPRequest() return http_requests
def test_request_language_resolution_with_request_header(self): """Test for frappe.translate.get_language Case 5: frappe.form_dict._lang & preferred_language cookie is not set, but Accept-Language header is """ set_request(method="POST", path="/", headers=[("Accept-Language", third_lang)]) return_val = get_language() self.assertNotIn(return_val, [third_lang, get_parent_language(third_lang)])
def test_login(self): set_request(method='GET', path='/login') response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue('// login.js' in html) self.assertTrue('<!-- login.html -->' in html)
def create_http_request(): '''Get http request object.''' set_request(method='POST', path='login') enable_2fa() frappe.form_dict['usr'] = '******' frappe.form_dict['pwd'] = 'Eastern_43A1W' frappe.local.form_dict['cmd'] = 'login' http_requests = HTTPRequest() return http_requests
def test_guest_request_language_resolution_with_cookie(self): """Test for frappe.translate.get_language Case 3: frappe.form_dict._lang is not set, but preferred_language cookie is [Guest User] """ with patch.object(frappe.translate, "get_preferred_language_cookie", return_value=second_lang): set_request(method="POST", path="/", headers=[("Accept-Language", third_lang)]) return_val = get_language() self.assertIn(return_val, [second_lang, get_parent_language(second_lang)])
def test_homepage_section_card(self): try: frappe.get_doc({ "doctype": "Homepage Section", "name": "Card Section", "section_based_on": "Cards", "section_cards": [ { "title": "Card 1", "subtitle": "Subtitle 1", "content": "This is test card 1", "route": "/card-1", }, { "title": "Card 2", "subtitle": "Subtitle 2", "content": "This is test card 2", "image": "test.jpg", }, ], "no_of_columns": 3, }).insert(ignore_if_duplicate=True) except frappe.DuplicateEntryError: pass set_request(method="GET", path="home") response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, "html.parser") sections = soup.find("main").find_all("section") self.assertEqual(len(sections), 3) homepage_section = sections[2] self.assertEqual(homepage_section.h3.text, "Card Section") cards = homepage_section.find_all(class_="card") self.assertEqual(len(cards), 2) self.assertEqual(cards[0].h5.text, "Card 1") self.assertEqual(cards[0].a["href"], "/card-1") self.assertEqual(cards[1].p.text, "Subtitle 2") self.assertEqual( cards[1].find(class_="website-image-lazy")["data-src"], "test.jpg") # cleanup frappe.db.rollback()
def test_homepage_section_card(self): try: frappe.get_doc({ 'doctype': 'Homepage Section', 'name': 'Card Section', 'section_based_on': 'Cards', 'section_cards': [ { 'title': 'Card 1', 'subtitle': 'Subtitle 1', 'content': 'This is test card 1', 'route': '/card-1' }, { 'title': 'Card 2', 'subtitle': 'Subtitle 2', 'content': 'This is test card 2', 'image': 'test.jpg' }, ], 'no_of_columns': 3 }).insert() except frappe.DuplicateEntryError: pass set_request(method='GET', path='home') response = render() self.assertEquals(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, 'html.parser') sections = soup.find('main').find_all('section') self.assertEqual(len(sections), 3) homepage_section = sections[2] self.assertEqual(homepage_section.h3.text, 'Card Section') cards = homepage_section.find_all(class_="card") self.assertEqual(len(cards), 2) self.assertEqual(cards[0].h5.text, 'Card 1') self.assertEqual(cards[0].a['href'], '/card-1') self.assertEqual(cards[1].p.text, 'Subtitle 2') self.assertEqual( cards[1].find(class_='website-image-lazy')['data-src'], 'test.jpg') # cleanup frappe.db.rollback()
def test_page_load(self): frappe.set_user('Guest') set_request(method='POST', path='login') response = render.render() self.assertEquals(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue('// login.js' in html) self.assertTrue('<!-- login.html -->' in html) frappe.set_user('Administrator')
def test_page_load(self): frappe.set_user("Guest") set_request(method="POST", path="login") response = render.render() self.assertEquals(response.status_code, 200) html = frappe.safe_decode(response.get_data()) self.assertTrue("// login.js" in html) self.assertTrue("<!-- login.html -->" in html) frappe.set_user("Administrator")
def test_request_language_resolution_with_cookie(self): """Test for frappe.translate.get_language Case 2: frappe.form_dict._lang is not set, but preferred_language cookie is """ with patch.object(frappe.translate, "get_preferred_language_cookie", return_value="fr"): set_request(method="POST", path="/", headers=[("Accept-Language", "hr")]) return_val = get_language() # system default language self.assertEqual(return_val, "en") self.assertNotIn(return_val, [second_lang, get_parent_language(second_lang)])
def test_generator_not_found(self): pages = frappe.get_all("Blog Post", fields=["name", "route"], filters={"published": 0}, limit=1) frappe.db.set_value("Blog Post", pages[0].name, "route", "test-route-000") set_request(path="test-route-000") response = render() self.assertTrue(response.status_code, 404)
def test_generator_not_found(self): pages = frappe.get_all('Blog Post', fields=['name', 'route'], filters={'published': 0}, limit=1) frappe.db.set_value('Blog Post', pages[0].name, 'route', 'test-route-000') set_request(path='test-route-000') response = render() self.assertTrue(response.status_code, 404)
def test_generator_not_found(self): pages = frappe.get_all('Blog Post', fields=['name', 'route'], filters={'published': 0}, limit=1) route = f'test-route-{frappe.generate_hash(length=5)}' frappe.db.set_value('Blog Post', pages[0].name, 'route', route) set_request(path=route) response = get_response() self.assertTrue(response.status_code, 404)
def test_flush(self): set_request(method="GET", path="/api/method/frappe.ping") response = build_response("json") frappe.monitor.start() frappe.monitor.stop(response) open(frappe.monitor.log_file(), "w").close() frappe.monitor.flush() with open(frappe.monitor.log_file()) as f: logs = f.readlines() self.assertEqual(len(logs), 1) log = frappe.parse_json(logs[0]) self.assertEqual(log.transaction_type, "request")
def test_web_page_with_page_builder(self): self.create_web_page() set_request(method="GET", path="test-web-template") response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, "html.parser") sections = soup.find("main").find_all("section") self.assertEqual(len(sections), 2) self.assertEqual(sections[0].find("h2").text, "Test Title") self.assertEqual(sections[0].find("p").text, "test lorem ipsum") self.assertEqual(len(sections[1].find_all("a")), 3)
def test_redirect(self): import frappe.hooks frappe.hooks.website_redirects = [ dict(source=r"/testfrom", target=r"://testto1"), dict(source=r"/testfromregex.*", target=r"://testto2"), dict(source=r"/testsub/(.*)", target=r"://testto3/\1"), ] website_settings = frappe.get_doc("Website Settings") website_settings.append("route_redirects", { "source": "/testsource", "target": "/testtarget" }) website_settings.save() frappe.cache().delete_key("app_hooks") frappe.cache().delete_key("website_redirects") set_request(method="GET", path="/testfrom") response = render.render() self.assertEquals(response.status_code, 301) self.assertEquals(response.headers.get("Location"), r"://testto1") set_request(method="GET", path="/testfromregex/test") response = render.render() self.assertEquals(response.status_code, 301) self.assertEquals(response.headers.get("Location"), r"://testto2") set_request(method="GET", path="/testsub/me") response = render.render() self.assertEquals(response.status_code, 301) self.assertEquals(response.headers.get("Location"), r"://testto3/me") set_request(method="GET", path="/test404") response = render.render() self.assertEquals(response.status_code, 404) set_request(method="GET", path="/testsource") response = render.render() self.assertEquals(response.status_code, 301) self.assertEquals(response.headers.get("Location"), "/testtarget") delattr(frappe.hooks, "website_redirects") frappe.cache().delete_key("app_hooks")
def test_custom_stylesheet(self): self.create_web_page() theme = self.create_website_theme() theme.set_as_default() frappe.conf.developer_mode = 1 set_request(method="GET", path="test-web-template") response = get_response() self.assertEqual(response.status_code, 200) html = frappe.safe_decode(response.get_data()) soup = BeautifulSoup(html, "html.parser") stylesheet = soup.select_one('link[rel="stylesheet"]') self.assertEqual(stylesheet.attrs["href"], theme.theme_url) frappe.get_doc("Website Theme", "Standard").set_as_default()
def test_generator_view(self): pages = frappe.get_all('Blog Post', fields=['name', 'route'], filters={ 'published': 1, 'route': ('!=', '') }, limit=1) set_request(path=pages[0].route) response = render() self.assertTrue(response.status_code, 200) html = response.get_data().decode() self.assertTrue( '<article class="blog-content mb-3" itemscope itemtype="http://schema.org/BlogPosting">' in html)