def test_resolve_control_to_list(self):
		id = "AU-3"
		c = SecControl(id)
		cv = SecControlViz(id)
		cv.dep_resolve(cv.dep_dict, id, cv.resolved)
		# print "precursors: ", cv.resolved
		self.assertTrue(cv.resolved == ['RA-3', 'AU-2', 'AU-3'])
	def test_create_node_options_tuples(self):
		# To Do: Make shape and attributes passed in variables
		id = "AU-3"
		cv = SecControlViz(id)
		# Find precursor nodes
		cv.precursor_list(cv.dep_dict, id, cv.nodes)
		# print "cv.nodes: ", cv.nodes
		# print cv.node_options_tuples(cv.nodes)
		self.assertTrue(cv.node_options_tuples(cv.nodes) == [('AU-3', {'fontname': 'arial', 'URL': '/control?id=AU-3', 'tooltip': u'(AU-3) Content Of Audit Records', 'label': u'AU-3\nContent Of Audit Records', 'color': 'palevioletred', 'shape': 'egg', 'fontsize': '12', 'fontcolor': 'palevioletred'}), ('AU-2', {'fontname': 'arial', 'URL': '/control?id=AU-2', 'tooltip': u'(AU-2) Audit Events', 'label': u'AU-2\nAudit Events', 'color': 'cornflowerblue', 'shape': 'egg', 'fontsize': '12', 'fontcolor': 'cornflowerblue'}), ('RA-3', {'fontname': 'arial', 'URL': '/control?id=RA-3', 'tooltip': u'(RA-3) Risk Assessment', 'label': u'RA-3\nRisk Assessment', 'color': 'cornflowerblue', 'shape': 'egg', 'fontsize': '12', 'fontcolor': 'cornflowerblue'}), ('PM-9', {'fontname': 'arial', 'URL': '/control?id=PM-9', 'tooltip': u'(PM-9) Risk Management Strategy', 'label': u'PM-9\nRisk Management Strategy', 'color': 'cornflowerblue', 'shape': 'egg', 'fontsize': '12', 'fontcolor': 'cornflowerblue'})])
	def test_edges(self):
		id = "AU-3"
		cv = SecControlViz(id)
		cv.precursor_list(cv.dep_dict, id, cv.nodes)
		for node in cv.nodes:
			cv.precursor_edges(cv.dep_dict, node, cv.edges)
		# print "edges: ", cv.edges
		self.assertTrue(cv.edges == [(('AU-2', 'AU-3'), {'color': 'darkkhaki', 'arrowhead': 'open'}), (('RA-3', 'AU-2'), {'color': 'darkkhaki', 'arrowhead': 'open'}), (('PM-9', 'RA-3'), {'color': 'darkkhaki', 'arrowhead': 'open'})])
	def test_set_graph_size(self):
		id = "SA-2"
		cv = SecControlViz(id)
		self.assertTrue(cv.width == 2.5)
		self.assertTrue(cv.height == 2.5)
		pl = cv.precursor_list(cv.dep_dict, id, cv.nodes)
		# print "precursor list: ", len(cv.nodes)
		node_count = len(cv.nodes)
		self.assertTrue(len(cv.nodes) == 8)
		# print "node_count..", node_count
		if node_count <= 5: cv.width,cv.height = 2.5,2.5
		if node_count <= 2: cv.width,cv.height = 2.5,2.5
		if node_count >= 6: cv.width,cv.height = 2.75,2.75
		if node_count >= 10: cv.width,cv.height = 3,3
		if node_count >= 20: cv.width,cv.height = 3,3
		if node_count >= 40: cv.width,cv.height = 4,4
		if node_count >= 100: cv.width,cv.height = 12,10
		self.assertTrue(cv.width == 2.75)
		self.assertTrue(cv.height == 2.75)
	def test_add_nodes(self):
		# To Do: Make shape and attributes passed in variables
		id = "AU-3"
		cv = SecControlViz(id)
		cv.precursor_list(cv.dep_dict, id, cv.nodes)
		digraph = cv.add_nodes(cv.digraph(), cv.node_options_tuples(cv.nodes))
		# print "<%s>" % digraph
		# print cv.nodes
		self.assertTrue("%s" % digraph == """digraph {
	"AU-3" [label="AU-3
Content Of Audit Records" URL="/control?id=AU-3" color=palevioletred fontcolor=palevioletred fontname=arial fontsize=12 shape=egg tooltip="(AU-3) Content Of Audit Records"]
	"AU-2" [label="AU-2
Audit Events" URL="/control?id=AU-2" color=cornflowerblue fontcolor=cornflowerblue fontname=arial fontsize=12 shape=egg tooltip="(AU-2) Audit Events"]
	"RA-3" [label="RA-3
Risk Assessment" URL="/control?id=RA-3" color=cornflowerblue fontcolor=cornflowerblue fontname=arial fontsize=12 shape=egg tooltip="(RA-3) Risk Assessment"]
	"PM-9" [label="PM-9
Risk Management Strategy" URL="/control?id=PM-9" color=cornflowerblue fontcolor=cornflowerblue fontname=arial fontsize=12 shape=egg tooltip="(PM-9) Risk Management Strategy"]
}"""
)
	def test_add_edges(self):
		id = "AU-3"
		cv = SecControlViz(id)
		cv.precursor_list(cv.dep_dict, id, cv.nodes)
		# create edges
		for node in cv.nodes:
			cv.precursor_edges(cv.dep_dict, node, cv.edges)
		digraph = cv.add_nodes(cv.digraph(), cv.node_options_tuples(cv.nodes))
		# print "<%s>" % digraph

		# weak test, first delete file if exists
		try:
		    os.remove("output/img/%s-precursors" % id)
		    os.remove("output/img/%s-precursors.%s" % (id, cv.vizformat))
		except OSError:
		    pass
		# generate graphviz file
		cv.add_edges(cv.add_nodes(cv.digraph(), cv.node_options_tuples(cv.nodes)),
			cv.edges
		).render("output/img/%s-precursors" % id)
		# print "image: output/img/%s-precursors.%s" % (id, cv.vizformat)
		# now see if image file created?
		self.assertTrue(os.path.exists("output/img/%s-precursors.%s" % (id, cv.vizformat)))
	def test_node_options_by_id(self):
		id = "AU-3"
		cv = SecControlViz(id)
		node_options = cv.node_options_by_id(id)
		# print "node_options: ", node_options
		self.assertTrue(node_options == {'fontname': 'arial', 'URL': '/control?id=AU-3', 'tooltip': u'(AU-3) Content Of Audit Records', 'label': u'AU-3\nContent Of Audit Records', 'color': 'palevioletred', 'shape': 'egg', 'fontsize': '12', 'fontcolor': 'palevioletred'})
	def test_precursor_list(self):
		id = "AU-3"
		cv = SecControlViz(id)
		cv.precursor_list(cv.dep_dict, id, cv.nodes)
		# print "nodes: ", cv.nodes
		self.assertTrue(cv.nodes == ['AU-3', 'AU-2', 'RA-3', 'PM-9'])
	def test_get_title(self):
		id = "CA-5"
		c = SecControl(id)
		cv = SecControlViz(id)
		self.assertTrue("PLAN OF ACTION AND MILESTONES" == c.title)
	def test_loading_graph(self):
		id = "AT-3"
		cv = SecControlViz(id)
		self.assertTrue(id == cv.id)
		dict = cv._load_graph_from_dependency_files()
		self.assertTrue(dict['AT-4'] == ['AT-2', 'AT-3'])
	def test_id(self):
		id = "AT-3"
		cv = SecControlViz(id)
		self.assertTrue(id == cv.id)
	def test_node_count_in_dependency_graph(self):
		id = "AU-3"
		cv = SecControlViz(id)
		pl = cv.precursor_list(cv.dep_dict, id, cv.nodes)
		# print "precursor list: ", len(cv.nodes)
		self.assertTrue(len(cv.nodes) == 4)
    def control(self, id="AU-4", format="html"):
        id = id.upper()
        sc = SecControl(id)
        if sc.title is None and sc.description is None and format == "html":
            # control does not exist, return 404
            print "\n*** control does not exist"
            raise cherrypy.HTTPRedirect("/error404")
        cv = SecControlViz(id)

        # create graphviz file
        cv.precursor_list(cv.dep_dict, id, cv.nodes)
        # create edges
        for node in cv.nodes:
            cv.precursor_edges(cv.dep_dict, node, cv.edges)
        digraph = cv.add_nodes(cv.digraph(), cv.node_options_tuples(cv.nodes))
        # print "<%s>" % digraph

        # determine graph image size
        node_count = len(cv.nodes)
        if node_count <= 5:
            cv.width, cv.height = 2.5, 2.5
        if node_count <= 2:
            cv.width, cv.height = 2.5, 2.5
        if node_count >= 6:
            cv.width, cv.height = 2.75, 2.75
        if node_count >= 10:
            cv.width, cv.height = 3, 3
        if node_count >= 20:
            cv.width, cv.height = 3, 3
        if node_count >= 40:
            cv.width, cv.height = 4, 4
        if node_count >= 100:
            cv.width, cv.height = 12, 10
        print "node_count", node_count
        print "w, h", cv.width, cv.height

        # weak test, first delete file if exists
        try:
            os.remove("output/img/%s-precursors" % id)
            os.remove("output/img/%s-precursors.%s" % (id, cv.vizformat))
        except OSError:
            pass
        # generate graphviz file
        graph_label = "%s Control Chain" % (id)
        cv.add_edges(
            cv.add_nodes(
                cv.digraph(
                    engine="dot",
                    body={'size ="%d,%d";' % (cv.width, cv.height)},
                    graph_attr={
                        "label": graph_label,
                        "labelloc": "bottom",
                        "labeljust": "center",
                        "fontcolor": "slategray",
                        "fontname": "Arial",
                        "fontsize": "14",
                        "K": "4.6",
                    },
                ),
                cv.node_options_tuples(cv.nodes),
            ),
            cv.edges,
        ).render("output/img/%s-precursors" % id)

        # read contents of svg file into variable
        with open("output/img/%s-precursors.svg" % id, "r") as svg_file:
            svg_content = svg_file.read()

        # render json
        if format == "json":
            cherrypy.response.headers["Content-Type"] = "application/json"
            if sc.title is None and sc.description is None:
                raise cherrypy.HTTPError("404 Not Found", "The requested resource does not exist")
            return json.dumps(sc.get_control_json())

        # render html page
        return """<html>
          <head>
            <title>800-53 Control {sc_id}</title>
            <link rel="stylesheet" type="text/css" href="/assets/css/main.css">
            <style>
                svg {{
                    height: {sc_graph_height};
                    width: 1800px;
                }}
            </style>
          </head>
      <body>

        <form id="form_lookup" method="get" action="control">
          800-53 control id: <input type="text" value="" name="id" />
              <button type="submit">Show me!</button>
              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
              <a href="/">families</a>
        </form>
        

        <h2>({sc_id}) {sc_title}</h2>

        <!-- Graph image by adding svg block into html page -->
        <!--h4>Control Dependency Chain</h4-->
        <div id="graph">
            {sc_svg}
        </div>
        <div id="graphkey">
            key: 
            <div style="color: cornflowerblue">blue is organization responsibility</div>
            <div style="color: palevioletred">light red is information system responsibility</div>
        </div>
        
        <h3>Control Description</h3>
        <p style="width:800;">{sc_desc}</p>

        <h3>Supplemental Guidance</h3>
        <p>{sc_suppl}</p>

        <h3>Control Enhancements</h3>
        <p>{sc_enhance}</p>
 
      </body>
    </html>""".format(
            sc_id=id,
            sc_title=sc.title,
            sc_desc=replace_line_breaks(
                replace_line_breaks(sc.description.encode("utf-8"), "\n", "<br /><br />"),
                "\t",
                "&nbsp;&nbsp;&nbsp;&nbsp;",
            ),
            sc_svg=svg_content,
            sc_graph_height=cv.height * 96,
            sc_enhance=replace_line_breaks(replace_unicodes(sc.control_enhancements)),
            sc_suppl=replace_line_breaks(replace_unicodes(sc.supplemental_guidance)),
            path=os.path.abspath(os.getcwd()),
        )
    def control(self, id="AU-4", format="html"):
        id = id.upper()
        sc = SecControl(id)
        if sc.title is None and sc.description is None and format == "html":
            # control does not exist, return 404
            print "\n*** control does not exist"
            raise cherrypy.HTTPRedirect("/error404")
        cv = SecControlViz(id)

        # create graphviz file
        cv.precursor_list(cv.dep_dict, id, cv.nodes)
        # create edges
        for node in cv.nodes:
            cv.precursor_edges(cv.dep_dict, node, cv.edges)
        digraph = cv.add_nodes(cv.digraph(), cv.node_options_tuples(cv.nodes))
        # print "<%s>" % digraph

        # determine graph image size
        node_count = len(cv.nodes)
        if node_count <= 5: cv.width,cv.height = 2.5,2.5
        if node_count <= 2: cv.width,cv.height = 2.5,2.5
        if node_count >= 6: cv.width,cv.height = 2.75,2.75
        if node_count >= 10: cv.width,cv.height = 3,3
        if node_count >= 20: cv.width,cv.height = 3,3
        if node_count >= 40: cv.width,cv.height = 4,4
        if node_count >= 100: cv.width,cv.height = 12,10
        print "node_count", node_count
        print "w, h", cv.width, cv.height

        # weak test, first delete file if exists
        try:
            os.remove("output/img/%s-precursors" % id)
            os.remove("output/img/%s-precursors.%s" % (id, cv.vizformat))
        except OSError:
            pass
        # generate graphviz file
        graph_label = "%s Control Chain" % (id)
        cv.add_edges(cv.add_nodes(cv.digraph(engine='dot', body={'size ="%d,%d";' % (cv.width, cv.height)}, graph_attr={'label': graph_label, 'labelloc': 'bottom', 'labeljust': 'center', 'fontcolor':'slategray', 'fontname':'Arial', 'fontsize': '14', 'K': '4.6'}), cv.node_options_tuples(cv.nodes)),
            cv.edges
        ).render("output/img/%s-precursors" % id)

        # read contents of svg file into variable
        with open("output/img/%s-precursors.svg" % id, "r") as svg_file:
            svg_content = svg_file.read()

        # render json
        if format == "json":
            cherrypy.response.headers['Content-Type'] = 'application/json'
            if sc.title is None and sc.description is None:
                raise cherrypy.HTTPError("404 Not Found", "The requested resource does not exist")
            return json.dumps(sc.get_control_json())

        with open('compliance/system/project_info.yml', 'r') as f:
            project = yaml.load(f)

        sc_desc = use_org_name(sc.description.encode('utf-8'), project['organization']['name'])
        sc_desc = replace_assignments(sc_desc, project)
        sc_desc = replace_line_breaks(replace_line_breaks(sc_desc, "\n", "<br /><br />"), "\t", "&nbsp;&nbsp;&nbsp;&nbsp;")
        # render html page
        tmpl = env.get_template('control.html', project)
        return tmpl.render( sc_id = id, sc_title = sc.title, sc_desc = sc_desc,
            sc_svg = svg_content, sc_graph_height = cv.height*96,
            path=os.path.abspath(os.getcwd()) )