def test_category_link(self):
        # Make a temporary Blog Post (and a Blog Category)
        blog = make_test_blog('Test Category Link')

        # Visit the blog post page
        set_request(path=blog.route)
        blog_page_response = get_response()
        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 = get_response()
        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
        frappe.delete_doc("Blog Post", blog.name)
        frappe.delete_doc("Blog Category", blog.blog_category)
    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
Exemple #3
0
	def test_caching(self):
		# to enable caching
		frappe.flags.force_website_cache = True

		clear_website_cache()
		# first response no-cache
		response = get_response('/_test/_test_folder/_test_page')
		self.assertIn(('X-From-Cache', 'False'), list(response.headers))

		# first response returned from cache
		response = get_response('/_test/_test_folder/_test_page')
		self.assertIn(('X-From-Cache', 'True'), list(response.headers))

		frappe.flags.force_website_cache = False
    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()
Exemple #5
0
def application(request):
    response = None

    try:
        rollback = True

        init_request(request)

        frappe.recorder.record()
        frappe.monitor.start()
        frappe.rate_limiter.apply()
        frappe.api.validate_auth()

        if request.method == "OPTIONS":
            response = Response()

        elif frappe.form_dict.cmd:
            response = frappe.handler.handle()

        elif request.path.startswith("/api/"):
            response = frappe.api.handle()

        elif request.path.startswith('/backups'):
            response = frappe.utils.response.download_backup(request.path)

        elif request.path.startswith('/private/files/'):
            response = frappe.utils.response.download_private_file(
                request.path)

        elif request.method in ('GET', 'HEAD', 'POST'):
            response = get_response()

        else:
            raise NotFound

    except HTTPException as e:
        return e

    except frappe.SessionStopped as e:
        response = frappe.utils.response.handle_session_stopped()

    except Exception as e:
        response = handle_exception(e)

    else:
        rollback = after_request(rollback)

    finally:
        if request.method in ("POST", "PUT") and frappe.db and rollback:
            frappe.db.rollback()

        frappe.rate_limiter.update()
        frappe.monitor.stop(response)
        frappe.recorder.dump()

        log_request(request, response)
        process_response(response)
        frappe.destroy()

    return response
    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 = get_response()

        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)
Exemple #7
0
    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)
Exemple #8
0
	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)
Exemple #9
0
	def test_custom_page_renderer(self):
		import frappe.hooks
		frappe.hooks.page_renderer = ['frappe.tests.test_website.CustomPageRenderer']
		frappe.cache().delete_key('app_hooks')
		set_request(method='GET', path='/custom')
		response = get_response()
		self.assertEqual(response.status_code, 3984)

		set_request(method='GET', path='/new')
		content = get_response_content()
		self.assertIn("<div>Custom Page Response</div>", content)

		set_request(method='GET', path='/random')
		response = get_response()
		self.assertEqual(response.status_code, 404)

		delattr(frappe.hooks, 'page_renderer')
		frappe.cache().delete_key('app_hooks')
Exemple #10
0
	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 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()
Exemple #12
0
def handle_session_stopped():
    from frappe.website.serve import get_response
    frappe.respond_as_web_page(
        _("Updating"),
        _("Your system is being updated. Please refresh again after a few moments."
          ),
        http_status_code=503,
        indicator_color='orange',
        fullpage=True,
        primary_action=None)
    return get_response("message", http_status_code=503)
    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_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_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 = get_response()

        self.assertTrue(response.status_code, 200)

        html = response.get_data().decode()
        self.assertTrue(
            '<article class="blog-content" itemscope itemtype="http://schema.org/BlogPosting">'
            in html)
Exemple #17
0
	def test_redirect(self):
		import frappe.hooks
		frappe.set_user('Administrator')

		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'),
			dict(source=r'/courses/course\?course=(.*)', target=r'/courses/\1', match_with_query_string=True),
		]

		website_settings = frappe.get_doc('Website Settings')
		website_settings.append('route_redirects', {
			'source': '/testsource',
			'target': '/testtarget'
		})
		website_settings.save()

		set_request(method='GET', path='/testfrom')
		response = get_response()
		self.assertEqual(response.status_code, 301)
		self.assertEqual(response.headers.get('Location'), r'://testto1')

		set_request(method='GET', path='/testfromregex/test')
		response = get_response()
		self.assertEqual(response.status_code, 301)
		self.assertEqual(response.headers.get('Location'), r'://testto2')

		set_request(method='GET', path='/testsub/me')
		response = get_response()
		self.assertEqual(response.status_code, 301)
		self.assertEqual(response.headers.get('Location'), r'://testto3/me')

		set_request(method='GET', path='/test404')
		response = get_response()
		self.assertEqual(response.status_code, 404)

		set_request(method='GET', path='/testsource')
		response = get_response()
		self.assertEqual(response.status_code, 301)
		self.assertEqual(response.headers.get('Location'), '/testtarget')

		set_request(method='GET', path='/courses/course?course=data')
		response = get_response()
		self.assertEqual(response.status_code, 301)
		self.assertEqual(response.headers.get('Location'), '/courses/data')

		delattr(frappe.hooks, 'website_redirects')
		frappe.cache().delete_key('app_hooks')
Exemple #18
0
def handle_exception(e):
    response = None
    http_status_code = getattr(e, "http_status_code", 500)
    return_as_message = False
    accept_header = frappe.get_request_header("Accept") or ""
    respond_as_json = (
        frappe.get_request_header('Accept') and
        (frappe.local.is_ajax or 'application/json' in accept_header)
        or (frappe.local.request.path.startswith("/api/")
            and not accept_header.startswith("text")))

    if frappe.conf.get('developer_mode'):
        # don't fail silently
        print(frappe.get_traceback())

    if respond_as_json:
        # handle ajax responses first
        # if the request is ajax, send back the trace or error message
        response = frappe.utils.response.report_error(http_status_code)

    elif (http_status_code == 500
          and (frappe.db and isinstance(e, frappe.db.InternalError))
          and (frappe.db and
               (frappe.db.is_deadlocked(e) or frappe.db.is_timedout(e)))):
        http_status_code = 508

    elif http_status_code == 401:
        frappe.respond_as_web_page(
            _("Session Expired"),
            _("Your session has expired, please login again to continue."),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 403:
        frappe.respond_as_web_page(
            _("Not Permitted"),
            _("You do not have enough permissions to complete the action"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 404:
        frappe.respond_as_web_page(
            _("Not Found"),
            _("The resource you are looking for is not available"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 429:
        response = frappe.rate_limiter.respond()

    else:
        traceback = "<pre>" + sanitize_html(frappe.get_traceback()) + "</pre>"
        # disable traceback in production if flag is set
        if frappe.local.flags.disable_traceback and not frappe.local.dev_server:
            traceback = ""

        frappe.respond_as_web_page("Server Error",
                                   traceback,
                                   http_status_code=http_status_code,
                                   indicator_color='red',
                                   width=640)
        return_as_message = True

    if e.__class__ == frappe.AuthenticationError:
        if hasattr(frappe.local, "login_manager"):
            frappe.local.login_manager.clear_cookies()

    if http_status_code >= 500:
        make_error_snapshot(e)

    if return_as_message:
        response = get_response("message", http_status_code=http_status_code)

    return response
Exemple #19
0
	def test_error_page(self):
		set_request(method='GET', path='/_test/problematic_page')
		response = get_response()
		self.assertEqual(response.status_code, 500)
Exemple #20
0
	def test_static_page(self):
		set_request(method='GET', path='/_test/static-file-test.png')
		response = get_response()
		self.assertEqual(response.status_code, 200)
Exemple #21
0
	def test_not_found(self):
		set_request(method='GET', path='/_test/missing')
		response = get_response()
		self.assertEqual(response.status_code, 404)
Exemple #22
0
def get_html_for_route(route):
    from frappe.website.serve import get_response
    set_request(method='GET', path=route)
    response = get_response()
    html = frappe.safe_decode(response.get_data())
    return html
Exemple #23
0
def as_page():
    """print web page"""
    from frappe.website.serve import get_response
    return get_response(
        frappe.response['route'],
        http_status_code=frappe.response.get("http_status_code"))