def testExportOptionsLastOptJSONHierarchy(self): assertEqual = self.assertEqual assertTrue = self.assertTrue db = current.db s3db = current.s3db # Configure parent-field table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Get the last record table = db.fotest_lookup_table last = db(table.id>0).select(limitby=(0, 1), orderby=~table.id).first() self.assertNotEqual(last, None) # Request last option resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], only_last=True, hierarchy=True, as_json=True) fo = json.loads(result) # Inspect result assertTrue(isinstance(fo, dict)) assertTrue("option" in fo) assertTrue(isinstance(fo["option"], list)) assertEqual(len(fo["option"]), 1) opt = fo["option"][0] value = opt["@value"] assertEqual(options[value]["uuid"], last.uuid) assertEqual(opt["$"], options[value]["name"]) assertTrue("@parent" in opt) assertEqual(opt["@parent"], str(options[value]["parent"]))
def testExportOptionsAllOptsJSONHierarchy(self): """ Test export options, JSON, all options+hierarchy """ assertEqual = self.assertEqual assertTrue = self.assertTrue # Configure parent-field db = current.db table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db = current.s3db s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Request options resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], hierarchy=True, as_json=True) fo = json.loads(result) # Inspect result has_empty = False assertTrue(isinstance(fo, dict)) assertTrue("option" in fo) assertTrue(isinstance(fo["option"], list)) assertEqual(len(fo["option"]), len(options) + 1) for opt in fo["option"]: value = opt["@value"] if value == "": has_empty = True self.assertFalse("$" in opt) continue else: value = int(value) assertTrue(value in options) assertEqual(opt["$"], options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue("@parent" in opt) assertEqual(opt["@parent"], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def testRoot(self): """ Test root node lookup """ uids = self.uids rows = self.rows # Top root node = uids["HIERARCHY1-1-1"] h = S3Hierarchy("test_hierarchy") root = h.root(node) self.assertEqual(root, uids["HIERARCHY1"]) # Root by category node = uids["HIERARCHY2-1"] root = h.root(node, classify=True) self.assertEqual(root, (uids["HIERARCHY2"], rows["HIERARCHY2"].category)) # Root of root node = uids["HIERARCHY1"] root = h.root(node) self.assertEqual(root, uids["HIERARCHY1"]) # None root = h.root(None) self.assertEqual(root, None)
def testPath(self): """ Test node path lookup """ uids = self.uids rows = self.rows # Standard path from root node = uids["HIERARCHY2-1-2"] h = S3Hierarchy("test_hierarchy") path = h.path(node) self.assertEqual(path, [uids["HIERARCHY2"], uids["HIERARCHY2-1"], uids["HIERARCHY2-1-2"] ]) # Path from category root node = uids["HIERARCHY1-1-1"] path = h.path(node, category="Cat 1", classify=True) classified = lambda uid: (uids[uid], rows[uid].category) self.assertEqual(path, [classified("HIERARCHY1-1"), classified("HIERARCHY1-1-1"), ]) # Path of root node = uids["HIERARCHY2"] path = h.path(node, category="Cat 1", classify=True) classified = lambda uid: (uids[uid], rows[uid].category) self.assertEqual(path, [classified("HIERARCHY2")])
def testFilteringAnyNode(self): """ Test filtering of the tree with leafonly=False """ uids = self.uids h = S3Hierarchy("test_hierarchy", filter = FS("type") == "C", leafonly = False) # Check nodes nodes = h.nodes expected = ["HIERARCHY1", "HIERARCHY1-1", "HIERARCHY1-2", "HIERARCHY1-2-2", "HIERARCHY2", "HIERARCHY2-1", "HIERARCHY2-1-1"] self.assertEqual(len(nodes), len(expected)) self.assertTrue(all(uids[uid] in nodes for uid in expected)) # Check consistency for node in nodes.values(): for child_id in node["s"]: self.assertTrue(child_id in nodes) parent_id = node["p"] if parent_id: self.assertTrue(parent_id in nodes)
def testCategory(self): """ Test node category lookup """ uids = self.uids rows = self.rows h = S3Hierarchy("test_hierarchy") for uid in uids: category = h.category(uids[uid]) self.assertEqual(category, rows[uid].category)
def testChildren(self): """ Test child node lookup """ uids = self.uids rows = self.rows h = S3Hierarchy("test_hierarchy") for uid in uids: self.assertEqual(h.children(uids[uid]), set(row.id for row in rows.values() if row.parent == uids[uid]))
def testParent(self): """ Test parent lookup """ uids = self.uids rows = self.rows h = S3Hierarchy("test_hierarchy") for uid in uids: parent, category = h.parent(uids[uid], classify=True) self.assertEqual(parent, rows[uid].parent) if parent: parent_uid = self.ids[parent] self.assertEqual(category, rows[parent_uid].category)
def testHierarchyConstruction(self): """ Test hierarchy construction """ uids = self.uids h = S3Hierarchy("test_hierarchy") roots = h.roots self.assertEqual(len(roots), 2) self.assertTrue(uids["HIERARCHY1"] in roots) self.assertTrue(uids["HIERARCHY2"] in roots) nodes = h.nodes self.assertEqual(len(nodes), len(uids)) self.assertTrue(all(node_id in nodes for node_id in uids.values()))
def testSiblings(self): """ Test lookup of sibling nodes """ uids = self.uids rows = self.rows h = S3Hierarchy("test_hierarchy") for uid in uids: parent = rows[uid].parent siblings = set(row.id for row in rows.values() if row.parent == parent) self.assertEqual(h.siblings(uids[uid], inclusive=True), siblings) siblings.discard(uids[uid]) self.assertEqual(h.siblings(uids[uid], inclusive=False), siblings)
def testFindAll(self): """ Test lookup of descendant nodes """ uids = self.uids h = S3Hierarchy("test_hierarchy") root = uids["HIERARCHY1"] nodes = h.findall(root) expected = [ "HIERARCHY1-1", "HIERARCHY1-1-1", "HIERARCHY1-1-2", "HIERARCHY1-2", "HIERARCHY1-2-1", "HIERARCHY1-2-2", ] self.assertEqual(nodes, set(uids[uid] for uid in expected)) root = uids["HIERARCHY1"] nodes = h.findall(root, inclusive=True) expected = [ "HIERARCHY1", "HIERARCHY1-1", "HIERARCHY1-1-1", "HIERARCHY1-1-2", "HIERARCHY1-2", "HIERARCHY1-2-1", "HIERARCHY1-2-2", ] self.assertEqual(nodes, set(uids[uid] for uid in expected)) root = uids["HIERARCHY2"] nodes = h.findall(root, category="Cat 1") expected = [ "HIERARCHY2-1", ] self.assertEqual(nodes, set(uids[uid] for uid in expected)) root = uids["HIERARCHY1"] nodes = h.findall(root, category="Cat 4") self.assertEqual(nodes, set())
def testExportOptionsXMLHierarchy(self): """ Test Export Options (all options, XML+hierarchy) """ assertEqual = self.assertEqual assertTrue = self.assertTrue # Configure parent-field db = current.db table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF( db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db = current.s3db s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = { "name": "option3", "uuid": "OPTION3", "parent": list(options.keys())[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Request options resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], hierarchy=True) fo = etree.XML(result) # Inspect result xml = current.xml ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, None) continue else: value = int(value) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def testWithHierarchyInfo(self): """ Test options lookup with foreign key constraint with hierarchy info """ assertEqual = self.assertEqual assertTrue = self.assertTrue db = current.db s3db = current.s3db table = db.fotest_lookup_table # Configure parent-field represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node xml = current.xml table = db.fotest_table fo = xml.get_field_options(table, "lookup", show_uids=True, hierarchy=True) assertTrue(isinstance(fo, etree._Element)) assertEqual(fo.tag, "select") ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, "") continue else: value = int(value) assertTrue(UID in attr) assertEqual(attr[UID], options[value]["uuid"]) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def testWithHierarchyInfo(self): """ Test options lookup with foreign key constraint with hierarchy info """ assertEqual = self.assertEqual assertTrue = self.assertTrue db = current.db s3db = current.s3db table = db.fotest_lookup_table # Configure parent-field represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF( db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = { "name": "option3", "uuid": "OPTION3", "parent": list(options.keys())[0], } child_id = table.insert(**child_node) options[child_id] = child_node xml = current.xml table = db.fotest_table fo = xml.get_field_options(table, "lookup", show_uids=True, hierarchy=True) assertTrue(isinstance(fo, etree._Element)) assertEqual(fo.tag, "select") ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, "") continue else: value = int(value) assertTrue(UID in attr) assertEqual(attr[UID], options[value]["uuid"]) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")
def testExportOptionsXMLHierarchy(self): """ Test Export Options (all options, XML+hierarchy) """ assertEqual = self.assertEqual assertTrue = self.assertTrue # Configure parent-field db = current.db table = db.fotest_lookup_table represent = S3Represent(lookup="fotest_lookup_table") table.parent.requires = IS_EMPTY_OR( IS_ONE_OF(db, "fotest_lookup_table.id", represent, )) table.parent.requires = represent # Configure hierarchy s3db = current.s3db s3db.configure("fotest_lookup_table", hierarchy="parent") S3Hierarchy.dirty("fotest_lookup_table") # Insert a child node options = dict(self.records) child_node = {"name": "option3", "uuid": "OPTION3", "parent": options.keys()[0], } child_id = table.insert(**child_node) options[child_id] = child_node # Request options resource = s3db.resource("fotest_table") result = resource.export_options(fields=["lookup"], hierarchy=True) fo = etree.XML(result) # Inspect result xml = current.xml ATTRIBUTE = xml.ATTRIBUTE VALUE = ATTRIBUTE.value PARENT = ATTRIBUTE.parent UID = xml.UID has_empty = False self.assertEqual(len(fo), len(options) + 1) for opt in fo: assertEqual(opt.tag, "option") attr = opt.attrib assertTrue(VALUE in attr) value = attr[VALUE] if value == "": has_empty = True self.assertFalse(UID in attr) assertEqual(opt.text, None) continue else: value = int(value) assertTrue(value in options) assertEqual(opt.text, options[value]["name"]) if "parent" in options[value] and options[value]["parent"]: assertTrue(PARENT in attr) assertEqual(attr[PARENT], str(options[value]["parent"])) assertTrue(has_empty, msg="Empty-option missing")