def test_text_input(request_context): with output_funnel.plugged(): html.text_input("tralala") written_text = "".join(output_funnel.drain()) assert compare_html( written_text, '<input style="" name="tralala" type="text" class="text" value=\'\' />' ) with output_funnel.plugged(): html.text_input("blabla", cssclass="blubb") written_text = "".join(output_funnel.drain()) assert compare_html( written_text, '<input style="" name="tralala" type="text" class="blubb" value=\'\' />' ) with output_funnel.plugged(): html.text_input("blabla", autocomplete="yep") written_text = "".join(output_funnel.drain()) assert compare_html( written_text, '<input style="" name="blabla" autocomplete="yep" type="text" class="text" value=\'\' />', ) with output_funnel.plugged(): html.text_input("blabla", placeholder="placido", data_world="welt", data_max_labels=42) written_text = "".join(output_funnel.drain()) assert compare_html( written_text, '<input style="" name="tralala" type="text" class="text" value=\'\' />' )
def page(self): check_csrf_token() if not user.may("general.configure_sidebar"): raise MKGeneralException( _("You are not allowed to change the sidebar.")) addname = request.var("name") if addname is None or addname not in snapin_registry: raise MKUserError(None, _("Invalid sidebar element %s") % addname) if addname in _used_snapins(): raise MKUserError(None, _("Element %s is already enabled") % addname) user_config = UserSidebarConfig(user, active_config.sidebar) snapin = UserSidebarSnapin.from_snapin_type_id(addname) user_config.add_snapin(snapin) user_config.save() with output_funnel.plugged(): try: url = SidebarRenderer().render_snapin(snapin) finally: snapin_code = output_funnel.drain() return { "name": addname, "url": url, "content": snapin_code, "refresh": snapin.snapin_type.refresh_regularly(), "restart": snapin.snapin_type.refresh_on_restart(), }
def test_table_cubical(request_context, monkeypatch, sortable, searchable, limit, output_format): monkeypatch.setattr(LoggedInNobody, "save_tableoptions", lambda s: None) # Test data rows = [(i, i**3) for i in range(10)] header = ["Number", "Cubical"] # Table options table_id = 0 title = " TEST " separator = ";" html.request.set_var("_%s_sort" % table_id, "1,0") html.request.set_var("_%s_actions" % table_id, "1") def _render_table(): with table_element( table_id="%d" % table_id, title=title, sortable=sortable, searchable=searchable, limit=limit, output_format=output_format, ) as table: for row in rows: table.row() for h, r in zip(header, row): table.cell(h, r) # Data assertions assert output_format in ["html", "csv"], "Fetch is not yet implemented" if output_format == "html": with output_funnel.plugged(): _render_table() written_text = "".join(output_funnel.drain()) data = read_out_simple_table(written_text) assert data.pop(0) == header, "Wrong header" elif output_format == "csv": _render_table() data = read_out_csv(response.get_data(as_text=True), separator) limit = len(data) assert data.pop(0) == header, "Wrong header" else: raise Exception("Not yet implemented") # Reconstruct table data data = [tuple(map(int, row)) for row in data if row and row[0]] if limit is None: limit = len(rows) # Assert data correctness assert len( data) <= limit, "Wrong number of rows: Got %s, should be <= %s" % ( len(data), limit) assert data == rows[:limit], "Incorrect data: %s\n\nVS\n%s" % ( data, rows[:limit])
def test_show_user_errors(request_context): assert not user_errors user_errors.add(MKUserError(None, "asd <script>alert(1)</script> <br> <b>")) assert user_errors with output_funnel.plugged(): html.show_user_errors() c = output_funnel.drain() assert c == '<div class="error">asd <script>alert(1)</script> <br> <b></div>'
def _get_mega_menu_content(self, menu_item: MainMenuItem) -> str: with output_funnel.plugged(): menu = mega_menu_registry[menu_item.name] html.open_div( id_="popup_menu_%s" % menu_item.name, class_=(["popup_menu", "main_menu_popup"] + (["min"] if user.get_attribute("nav_hide_icons_title") else [])), ) MegaMenuRenderer().show(menu) html.close_div() return output_funnel.drain()
def test_cell_title_escaping(request_context): with output_funnel.plugged(): with table_element("ding", "TITLE", searchable=False, sortable=False) as table: table.row() table.cell("<script>alert('A')</script>") table.cell(HTML("<script>alert('B')</script>")) table.cell("<b>C</b>") written_text = output_funnel.drain() assert "<script>alert('A')</script>" in written_text assert "<script>alert('B')</script>" in written_text assert "<b>C</b>" in written_text
def ajax_snapin(): """Renders and returns the contents of the requested sidebar snapin(s) in JSON format""" response.set_content_type("application/json") user_config = UserSidebarConfig(user, active_config.sidebar) snapin_id = request.var("name") snapin_ids = ([snapin_id] if snapin_id else request.get_str_input_mandatory("names", "").split(",")) snapin_code: List[str] = [] for snapin_id in snapin_ids: try: snapin_instance = user_config.get_snapin(snapin_id).snapin_type() except KeyError: continue # Skip not existing snapins if not snapin_instance.may_see(): continue # When restart snapins are about to be refreshed, only render # them, when the core has been restarted after their initial # rendering if not snapin_instance.refresh_regularly( ) and snapin_instance.refresh_on_restart(): since = request.get_float_input_mandatory("since", 0) newest = since for site in sites.states().values(): prog_start = site.get("program_start", 0) if prog_start > newest: newest = prog_start if newest <= since: # no restart snapin_code.append("") continue with output_funnel.plugged(): try: snapin_instance.show() except Exception as e: write_snapin_exception(e) e_message = ( _("Exception during element refresh (element '%s')") % snapin_instance.type_name()) logger.error("%s %s: %s", request.requested_url, e_message, traceback.format_exc()) finally: snapin_code.append(output_funnel.drain()) response.set_data(json.dumps(snapin_code))
def test_foldable_container(request_context) -> None: with output_funnel.plugged(): with foldable_container(treename="name", id_="id", isopen=False, title="Title") as is_open: assert is_open is False code = output_funnel.drain() assert compare_html( code, """<div class="foldable closed"><div onclick="cmk.foldable_container.toggle("name", "id", "")" class="foldable_header"><b class="treeangle title">Title</b><img id="treeimg.name.id" src="themes/facelift/images/tree_closed.svg" class="treeangle closed" /></div><ul id="tree.name.id" style="padding-left: 15px; " class="treeangle closed"></ul></div>""", )
def render_werk_description(werk) -> HTML: with output_funnel.plugged(): html.open_p() in_list = False in_code = False for line in werk["body"]: if line.startswith("LI:"): if not in_list: html.open_ul() in_list = True html.li(line[3:]) else: if in_list: html.close_ul() in_list = False if line.startswith("H2:"): html.h3(line[3:]) elif line.startswith("C+:"): html.open_pre(class_="code") in_code = True elif line.startswith("F+:"): file_name = line[3:] if file_name: html.div(file_name, class_="filename") html.open_pre(class_="file") in_code = True elif line.startswith("C-:") or line.startswith("F-:"): html.close_pre() in_code = False elif line.startswith("OM:"): html.write_text("OMD[mysite]:~$ ") html.b(line[3:]) elif line.startswith("RP:"): html.write_text("root@myhost:~# ") html.b(line[3:]) elif not line.strip() and not in_code: html.p("") else: html.write_text(line + "\n") if in_list: html.close_ul() html.close_p() return HTML(output_funnel.drain())
def _gen_node(self, tree, height, show_host): leaves: List[Any] = [] for node in tree[3]: if not node[2].get("hidden"): leaves += self._gen_table(node, height - 1, show_host) with output_funnel.plugged(): html.open_div(class_="aggr_tree") with self._show_node(tree, show_host): html.write_text(tree[2]["title"]) html.close_div() content = HTML(output_funnel.drain()) if leaves: leaves[0][2].append((len(leaves), content)) return leaves
def test_context(request_context): table_id = 0 rows = [(i, i**3) for i in range(10)] header = ["Number", "Cubical"] with output_funnel.plugged(): with table_element(table_id="%d" % table_id, searchable=False, sortable=False) as table: for row in rows: table.row() for h, r in zip(header, row): table.cell(h, r) written_text = "".join(output_funnel.drain()) data = read_out_simple_table(written_text) assert data.pop(0) == header data = [tuple(map(int, row)) for row in data if row and row[0]] assert data == rows
def test_basic(request_context): table_id = 0 title = " TEST " with output_funnel.plugged(): with table_element("%d" % table_id, title, searchable=False, sortable=False) as table: table.row() table.cell("A", "1") table.cell("B", "2") table.row() table.cell("A", "1") table.cell("C", "4") written_text = "".join(output_funnel.drain()) assert read_out_simple_table(written_text) == [["A", "B"], ["1", "2"], ["1", "4"]]
def test_HTMLWriter(request_context): with output_funnel.plugged(): with output_funnel.plugged(): html.open_div() text = output_funnel.drain() assert text.rstrip("\n").rstrip(" ") == "<div>" with output_funnel.plugged(): # html.open_div().write("test").close_div() html.open_div() html.write_text("test") html.close_div() assert compare_html(output_funnel.drain(), "<div>test</div>") with output_funnel.plugged(): # html.open_table().open_tr().td("1").td("2").close_tr().close_table() html.open_table() html.open_tr() html.td("1") html.td("2") html.close_tr() html.close_table() assert compare_html( output_funnel.drain(), "<table><tr><td>1</td><td>2</td></tr></table>") with output_funnel.plugged(): html.div("test", **{"</div>malicious_code<div>": "trends"}) assert compare_html( output_funnel.drain(), "<div </div>malicious_code<div>=trends>test</div>", ) a = "\u2665" with output_funnel.plugged(): assert HTMLWriter.render_a("test", href="www.test.case") HTMLWriter.render_a("test", href="www.test.case") HTMLWriter.render_a("test", href="www.test.case") HTMLWriter.render_a("test", href="www.test.case") try: assert HTMLWriter.render_a( "test", href=str("www.test.case"), id_=str("something"), class_=str("test_%s") % a, ) except Exception as e: traceback.print_exc() print(e)
def table_element( table_id: Optional[str] = None, title: Optional[HTMLContent] = None, searchable: bool = True, sortable: bool = True, foldable: Foldable = Foldable.NOT_FOLDABLE, limit: Union[None, int, Literal[False]] = None, output_format: str = "html", omit_if_empty: bool = False, omit_empty_columns: bool = False, omit_headers: bool = False, omit_update_header: bool = False, empty_text: Optional[str] = None, help: Optional[str] = None, # pylint: disable=redefined-builtin css: Optional[str] = None, isopen: bool = True, ) -> Iterator["Table"]: with output_funnel.plugged(): table = Table( table_id=table_id, title=title, searchable=searchable, sortable=sortable, foldable=foldable, limit=limit, output_format=output_format, omit_if_empty=omit_if_empty, omit_empty_columns=omit_empty_columns, omit_headers=omit_headers, omit_update_header=omit_update_header, empty_text=empty_text, help=help, css=css, isopen=isopen, ) try: yield table finally: table._finish_previous() table._end()
def _render_werk_options_form(werk_table_options: Dict[str, Any]) -> HTML: with output_funnel.plugged(): html.begin_form("werks") html.hidden_field("wo_set", "set") _show_werk_options_controls() html.open_div(class_="side_popup_content") for name, height, vs, _default_value in _werk_table_option_entries(): def renderer(name=name, vs=vs, werk_table_options=werk_table_options) -> None: vs.render_input("wo_" + name, werk_table_options[name]) html.render_floating_option(name, height, vs.title(), renderer) html.close_div() html.hidden_fields() html.end_form() return HTML(output_funnel.drain())
def test_nesting_context(request_context): table_id = 0 title = " TEST " with output_funnel.plugged(): with table_element(table_id="%d" % table_id, title=title, searchable=False, sortable=False) as table1: table1.row() table1.cell("A", "1") table1.cell("B", "") with table_element("%d" % (table_id + 1), title + "2", searchable=False, sortable=False) as table2: table2.row() table2.cell("_", "+") table2.cell("|", "-") written_text = "".join(output_funnel.drain()) assert compare_html( written_text, """<h3 class="table"> TEST </h3> <script type="text/javascript">\ncmk.utils.update_row_info(\'1 row\');\n</script> <table class="data oddeven"> <tr> <th> A </th> <th> B </th> </tr> <tr class="data even0"> <td> 1 </td> <td> <h3 class="table"> TEST 2</h3> <script type="text/javascript">\ncmk.utils.update_row_info(\'1 row\');\n</script> <table class="data oddeven"> <tr><th>_</th><th>|</th></tr> <tr class="data even0"><td>+</td><td>-</td></tr> </table> </td> </tr> </table>""", ), written_text
def render(self, row: Row, cell: Cell) -> CellSpec: single_url = "view.py?" + urlencode_vars( [("view_name", "aggr_single"), ("aggr_name", row["aggr_name"])] ) avail_url = single_url + "&mode=availability" bi_map_url = "bi_map.py?" + urlencode_vars( [ ("aggr_name", row["aggr_name"]), ] ) with output_funnel.plugged(): html.icon_button(bi_map_url, _("Visualize this aggregation"), "aggr") html.icon_button(single_url, _("Show only this aggregation"), "showbi") html.icon_button( avail_url, _("Analyse availability of this aggregation"), "availability" ) if row["aggr_effective_state"]["in_downtime"] != 0: html.icon( "derived_downtime", _("A service or host in this aggregation is in downtime.") ) if row["aggr_effective_state"]["acknowledged"]: html.icon( "ack", _( "The critical problems that make this aggregation non-OK have been acknowledged." ), ) if not row["aggr_effective_state"]["in_service_period"]: html.icon( "outof_serviceperiod", _("This aggregation is currently out of its service period."), ) code = HTML(output_funnel.drain()) return "buttons", code
def render(self) -> HTML: with output_funnel.plugged(): self._show_tree() return HTML(output_funnel.drain())
def test_multiclass_call(request_context): with output_funnel.plugged(): html.div("", class_="1", css="3", cssclass="4", **{"class": "2"}) written_text = "".join(output_funnel.drain()) assert compare_html(written_text, '<div class="1 3 4 2"></div>')
def _render_filter_form(self) -> HTML: with output_funnel.plugged(): self._display_audit_log_options() return HTML(output_funnel.drain())
def _try_page(file_name: str) -> None: page_handler = get_page_handler(file_name) if page_handler: with output_funnel.plugged(): page_handler() output_funnel.drain()
def _rename_tags_after_confirmation( breadcrumb: Breadcrumb, operation: ABCOperation) -> Union[bool, str]: """Handle renaming and deletion of tags Find affected hosts, folders and rules. Remove or fix those rules according the users' wishes. Returns: True: Proceed, no "question" dialog shown False: "Question dialog" shown str: Action done after "question" dialog """ repair_mode = request.var("_repair") if repair_mode is not None: try: mode = TagCleanupMode(repair_mode) except ValueError: raise MKUserError("_repair", "Invalid mode") if mode == TagCleanupMode.ABORT: raise MKUserError("id_0", _("Aborting change.")) # make attribute unknown to system, important for save() operations if isinstance(operation, OperationRemoveTagGroup): undeclare_host_tag_attribute(operation.tag_group_id) affected_folders, affected_hosts, affected_rulesets = change_host_tags_in_folders( operation, mode, Folder.root_folder()) return _( "Modified folders: %d, modified hosts: %d, modified rulesets: %d" ) % ( len(affected_folders), len(affected_hosts), len(affected_rulesets), ) message = HTML() affected_folders, affected_hosts, affected_rulesets = change_host_tags_in_folders( operation, TagCleanupMode.CHECK, Folder.root_folder()) if affected_folders: with output_funnel.plugged(): html.write_text( _("Affected folders with an explicit reference to this tag " "group and that are affected by the change") + ":") _show_affected_folders(affected_folders) message += HTML(output_funnel.drain()) if affected_hosts: with output_funnel.plugged(): html.write_text( _("Hosts where this tag group is explicitely set " "and that are effected by the change") + ":") _show_affected_hosts(affected_hosts) message += HTML(output_funnel.drain()) if affected_rulesets: with output_funnel.plugged(): html.write_text( _("Rulesets that contain rules with references to the changed tags" ) + ":") _show_affected_rulesets(affected_rulesets) message += HTML(output_funnel.drain()) if message: wato_html_head(title=operation.confirm_title(), breadcrumb=breadcrumb) html.open_div(class_="really") html.h3(_("Your modifications affect some objects")) html.write_text(message) html.br() html.write_text( _("Setup can repair things for you. It can rename tags in folders, host and rules. " "Removed tag groups will be removed from hosts and folders, removed tags will be " "replaced with the default value for the tag group (for hosts and folders). What " "rules concern, you have to decide how to proceed.")) html.begin_form("confirm", method="POST") if affected_rulesets and _is_removing_tags(operation): html.br() html.b( _("Some tags that are used in rules have been removed by you. What " "shall we do with that rules?")) html.open_ul() html.radiobutton( "_repair", "remove", True, _("Just remove the affected tags from the rules.")) html.br() html.radiobutton( "_repair", "delete", False, _("Delete rules containing tags that have been removed, if tag is used in a positive sense. Just remove that tag if it's used negated." ), ) else: html.open_ul() html.radiobutton("_repair", "repair", True, _("Fix affected folders, hosts and rules.")) html.br() html.radiobutton("_repair", "abort", False, _("Abort your modifications.")) html.close_ul() html.button("_do_confirm", _("Proceed"), "") html.hidden_fields(add_action_vars=True) html.end_form() html.close_div() return False return True
def _gen_leaf(self, tree, height, show_host): with output_funnel.plugged(): self._show_leaf(tree, show_host) content = HTML(output_funnel.drain()) return [(content, height, [])]
def test_filters_display_with_empty_request(request_context, live): with live: for filt in cmk.gui.plugins.visuals.utils.filter_registry.values(): with output_funnel.plugged(): _set_expected_queries(filt.ident, live) filt.display({k: "" for k in filt.htmlvars})
def _render_dropdown_area(self, dropdown: PageMenuDropdown) -> str: with output_funnel.plugged(): self._show_dropdown_area(dropdown) return output_funnel.drain()