class DashboardTestCase(LiveServerTestCase): """ These tests check basic functions of Sylva's dashboard. """ def setUp(self): self.browser = Browser(firefox_path=os.getenv('FIREFOX_PATH', None)) socket.setdefaulttimeout(30) signup(self, 'bob', '*****@*****.**', 'bob_secret') def tearDown(self): logout(self) self.browser.quit() @classmethod def tearDownClass(cls): sleep(10) # It needs some time for close the LiverServerTestCase super(DashboardTestCase, cls).tearDownClass() def test_dashboard(self): signin(self, 'bob', 'bob_secret') spin_assert(lambda: self.assertEquals(self.browser.title, 'SylvaDB - Dashboard')) text = self.browser.find_by_xpath( "//header[@class='global']/h1").first.value spin_assert(lambda: self.assertEqual(text, 'Dashboard')) def test_dashboard_new_graph(self): signin(self, 'bob', 'bob_secret') create_graph(self) Graph.objects.get(name="Bob's graph").destroy() def test_dashboard_graph_preview(self): """ This test, after create a graph with data, checks the Sigma visualization running a simple JavaScript code. This code gets the current instance of Sigma and checks the data with Sylva JavaScript object. """ signin(self, 'bob', 'bob_secret') create_graph(self) create_schema(self) create_type(self) create_data(self) self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() self.browser.is_element_present_by_id('wait_for_js', 3) js_code = ''' var instance = sigma.instances(0); var node = instance.graph.nodes()[0]; sylva.test_node_name = node.properties.Name; ''' self.browser.execute_script(js_code) text = self.browser.evaluate_script('sylva.test_node_name') Graph.objects.get(name="Bob's graph").destroy() spin_assert(lambda: self.assertNotEqual(text.find("Bob's node"), -1)) def test_automatic_tour(self): """ Thist test checks that the tour starts automatically after signup, only once. """ self.browser.is_element_present_by_id('wait_for_cookie_tour', 3) signin(self, 'bob', 'bob_secret') exist = self.browser.is_element_present_by_xpath( "//div[@class='joyride-content-wrapper']") spin_assert(lambda: self.assertEqual(exist, True)) self.browser.visit(self.live_server_url + '/dashboard/') exist = self.browser.is_element_present_by_xpath( "//div[@class='joyride-content-wrapper']") spin_assert(lambda: self.assertNotEqual(exist, True))
class ToolsTestCaseCsv(LiveServerTestCase): """ A master test to check the behaviour of the new 'auto' fields. Actually only works with gephi format. """ def setUp(self): self.browser = Browser(firefox_path=os.getenv('FIREFOX_PATH', None)) socket.setdefaulttimeout(30) signup(self, 'bob', '*****@*****.**', 'bob_secret') signin(self, 'bob', 'bob_secret') self.firstGraphName = "bobgraph" self.secondGraphName = "alicegraph" def tearDown(self): logout(self) self.browser.quit() @classmethod def tearDownClass(cls): sleep(10) # It needs some time for close the LiverServerTestCase super(ToolsTestCaseCsv, cls).tearDownClass() def test_graph_export_csv(self): # Create a graph with a auto_user property create_graph(self, self.firstGraphName) create_advanced_schema(self, self.firstGraphName) create_advanced_type(self, self.firstGraphName, "e") create_advanced_data(self) # Create new graph for import the data import_advanced_schema_csv(self, self.firstGraphName, self.secondGraphName) # Data import self.browser.find_by_id('toolsMenu').first.click() self.browser.find_link_by_href('/tools/' + self.secondGraphName + '/import/').first.click() self.browser.find_by_id('csv-radio').first.click() # Change the display field of input to attach the file script = """ $('#files').css('display', ''); """ self.browser.execute_script(script) self.browser.is_text_present('Drop your nodes files here', wait_time=10) # Import the nodes file_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'files/csv/bobs-type.csv' ) self.browser.attach_file('file', file_path) self.browser.is_text_present('Nodes files loaded. Loading edges files...', wait_time=10) # Wait until the data is imported self.browser.is_text_present('Now drop your edges files', wait_time=10) # Change the display field of input to attach the file script = """ $('#files2').css('display', ''); """ self.browser.execute_script(script) # Import the relationships file_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'files/csv/bobs-rels.csv' ) self.browser.attach_file('file2', file_path) self.browser.is_text_present('Data loaded. Uploading to the server...', wait_time=10) # Wait until the data is imported self.browser.is_text_present('Data uploaded.', wait_time=10) # Check that nodes and relationships are ok self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath("//a[@class='dataOption list']").first.click() alicegraph = Graph.objects.get(name=self.secondGraphName) alicegraphNodes = alicegraph.nodes.count() spin_assert(lambda: self.assertEqual(3, alicegraph.nodes.count())) spin_assert(lambda: self.assertEqual( 1, alicegraph.relationships.count())) # Add new nodes and relationships and check all is correct self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath( "//a[@class='dataOption new']").first.click() text = self.browser.find_by_id('propertiesTitle').first.value spin_assert(lambda: self.assertEqual(text, 'Properties')) self.browser.find_by_value("Save Bob's type").first.click() text = self.browser.find_by_xpath("//div[@class='pagination']/span[@class='pagination-info']").first.value spin_assert(lambda: self.assertNotEqual( text.find(" elements Bob's type."), -1)) spin_assert(lambda: self.assertEqual( alicegraphNodes + 1, alicegraph.nodes.count())) # Destroy the databases Graph.objects.get(name=self.firstGraphName).destroy() Graph.objects.get(name=self.secondGraphName).destroy()
class ToolsTestCaseCsv(LiveServerTestCase): """ A master test to check the behaviour of the new 'auto' fields. Actually only works with gephi format. """ def setUp(self): self.browser = Browser(firefox_path=os.getenv('FIREFOX_PATH', None)) socket.setdefaulttimeout(30) signup(self, 'bob', '*****@*****.**', 'bob_secret') signin(self, 'bob', 'bob_secret') self.firstGraphName = "bobgraph" self.secondGraphName = "alicegraph" def tearDown(self): logout(self) self.browser.quit() @classmethod def tearDownClass(cls): sleep(10) # It needs some time for close the LiverServerTestCase super(ToolsTestCaseCsv, cls).tearDownClass() def test_graph_export_csv(self): # Create a graph with a auto_user property create_graph(self, self.firstGraphName) create_advanced_schema(self, self.firstGraphName) create_advanced_type(self, self.firstGraphName, "e") create_advanced_data(self) # Create new graph for import the data import_advanced_schema_csv(self, self.firstGraphName, self.secondGraphName) # Data import self.browser.find_by_id('toolsMenu').first.click() self.browser.find_link_by_href('/tools/' + self.secondGraphName + '/import/').first.click() self.browser.find_by_id('csv-radio').first.click() # Change the display field of input to attach the file script = """ $('#files').css('display', ''); """ self.browser.execute_script(script) self.browser.is_text_present('Drop your nodes files here', wait_time=10) # Import the nodes file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'files/csv/bobs-type.csv') self.browser.attach_file('file', file_path) self.browser.is_text_present( 'Nodes files loaded. Loading edges files...', wait_time=10) # Wait until the data is imported self.browser.is_text_present('Now drop your edges files', wait_time=10) # Change the display field of input to attach the file script = """ $('#files2').css('display', ''); """ self.browser.execute_script(script) # Import the relationships file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'files/csv/bobs-rels.csv') self.browser.attach_file('file2', file_path) self.browser.is_text_present('Data loaded. Uploading to the server...', wait_time=10) # Wait until the data is imported self.browser.is_text_present('Data uploaded.', wait_time=10) # Check that nodes and relationships are ok self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath( "//a[@class='dataOption list']").first.click() alicegraph = Graph.objects.get(name=self.secondGraphName) alicegraphNodes = alicegraph.nodes.count() spin_assert(lambda: self.assertEqual(3, alicegraph.nodes.count())) spin_assert( lambda: self.assertEqual(1, alicegraph.relationships.count())) # Add new nodes and relationships and check all is correct self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath( "//a[@class='dataOption new']").first.click() text = self.browser.find_by_id('propertiesTitle').first.value spin_assert(lambda: self.assertEqual(text, 'Properties')) self.browser.find_by_value("Save Bob's type").first.click() text = self.browser.find_by_xpath( "//div[@class='pagination']/span[@class='pagination-info']" ).first.value spin_assert(lambda: self.assertNotEqual( text.find(" elements Bob's type."), -1)) spin_assert(lambda: self.assertEqual(alicegraphNodes + 1, alicegraph.nodes.count())) # Destroy the databases Graph.objects.get(name=self.firstGraphName).destroy() Graph.objects.get(name=self.secondGraphName).destroy()
class DataNodeTestCase(LiveServerTestCase): """ A set of tests to test all interaction related to the creation and deletion of nodes and relationships. Also, we test export the data in two formats: gexf and csv. """ def setUp(self): self.browser = Browser(firefox_path=os.getenv('FIREFOX_PATH', None)) socket.setdefaulttimeout(30) signup(self, 'bob', '*****@*****.**', 'bob_secret') signin(self, 'bob', 'bob_secret') def tearDown(self): logout(self) self.browser.quit() @classmethod def tearDownClass(cls): sleep(10) # It needs some time for close the LiverServerTestCase super(DataNodeTestCase, cls).tearDownClass() def test_data_node_addition(self): create_graph(self) create_schema(self) create_type(self) create_data(self) # Check the node name self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() text = self.browser.find_by_id('propertiesTitle').first.value spin_assert(lambda: self.assertEqual(text, 'Properties')) self.browser.find_by_xpath("//span[@class='buttonLinkOption buttonLinkRight']/a").first.click() self.browser.choose('confirm', '1') self.browser.find_by_value('Continue').first.click() text = self.browser.find_by_xpath("//div[@class='indent']/div").first.value Graph.objects.get(name="Bob's graph").destroy() spin_assert(lambda: self.assertEqual(text, 'Nodes: 0')) def test_data_node_addition_rel_add_del(self): create_graph(self) create_schema(self) create_type(self) create_node(self, "Bob") create_node(self, "Alice") # We create a allowed relation js_code = "$('a#schema-link')[0].click();" self.browser.execute_script(js_code) self.browser.find_by_id('allowedRelations').first.click() self.browser.select('source', '1') self.browser.find_by_name('name').fill("Bob's rel") self.browser.select('target', '1') self.browser.find_by_id('id_description').fill("This the allowed relationship for Bob's graph") self.browser.find_by_value('Save Type').first.click() spin_assert(lambda: self.assertEqual( self.browser.title, "SylvaDB - Bob's graph")) # We create the link between the nodes self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath("//td[@class='dataActions']/a[@class='dataOption list']").first.click() self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() self.browser.find_by_xpath("//li[@class='token-input-input-token']/input").first.fill('Alice') self.browser.is_element_present_by_id("id_user_wait", 5) self.browser.find_by_xpath("//div[@class='token-input-dropdown']//li[@class='token-input-dropdown-item2 token-input-selected-dropdown-item']/b").first.click() self.browser.find_by_value("Save Bob's type").first.click() # Delete the relationship self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() self.browser.find_by_xpath("//span[@class='all-relationships outgoing-relationships o_bobs_rel1-relationships']/span/a[@class='delete-row initial-form floating']").first.click() self.browser.find_by_value("Save Bob's type").first.click() self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-relationships']").first.value spin_assert(lambda: self.assertEqual(text, "0 relationships")) Graph.objects.get(name="Bob's graph").destroy() def test_node_type_deletion_keeping_nodes(self): create_graph(self) create_schema(self) create_type(self) # Adding relationship to the type self.browser.find_by_id('allowedRelations').first.click() self.browser.select('source', '1') self.browser.find_by_name('name').fill("Bob's rel") self.browser.select('target', '1') self.browser.find_by_id('id_description').fill( 'The loved relationship') self.browser.find_by_value('Save Type').first.click() text = self.browser.find_by_xpath( "//div[@class='form-row indent']/label").first.value spin_assert(lambda: self.assertNotEqual(text.find("Bob's rel"), -1)) # Creating nodes create_node(self, 'Bob') create_node(self, 'Alice') # Creating relationship between nodes self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath("//td[@class='dataActions']/a[@class='dataOption list']").first.click() self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() self.browser.find_by_xpath("//li[@class='token-input-input-token']/input").first.fill('Alice') self.browser.is_element_present_by_id("id_user_wait", wait_time=5) self.browser.find_by_xpath("//div[@class='token-input-dropdown']//li[@class='token-input-dropdown-item2 token-input-selected-dropdown-item']/b").first.click() self.browser.find_by_value("Save Bob's type").first.click() self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-relationships']").first.value spin_assert(lambda: self.assertEqual(text, "1 relationships")) # Deleting type js_code = "$('a#schema-link')[0].click();" self.browser.execute_script(js_code) self.browser.find_by_xpath("//fieldset[@class='module aligned wide model']/h2/a").first.click() self.browser.find_by_xpath("//span[@class='buttonLinkOption buttonLinkRight']/a[@class='delete']").first.click() text = self.browser.find_by_xpath( "//p/label[@for='id_option_0']").first.value spin_assert(lambda: self.assertNotEqual(text.find( "We found some elements of this type"), -1)) # Keeping nodes self.browser.choose('option', 'no') self.browser.find_by_value('Continue').first.click() text = self.browser.find_by_xpath( "//div[@class='body-inside']/p").first.value spin_assert(lambda: self.assertEqual( text, 'There are no types defined yet.')) # Checking self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-nodes']").first.value spin_assert(lambda: self.assertEqual(text, "2 nodes")) text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-relationships']").first.value spin_assert(lambda: self.assertEqual(text, "1 relationships")) text = self.browser.find_by_xpath( "//div[@class='graph-empty-message']").first.value spin_assert(lambda: self.assertNotEqual( text.find("Your Schema is empty."), -1)) Graph.objects.get(name="Bob's graph").destroy() def test_node_type_deletion_deleting_nodes(self): create_graph(self) create_schema(self) create_type(self) # Adding relationship to the type self.browser.find_by_id('allowedRelations').first.click() self.browser.select('source', '1') self.browser.find_by_name('name').fill("Bob's rel") self.browser.select('target', '1') self.browser.find_by_id('id_description').fill( 'The loved relationship') self.browser.find_by_value('Save Type').first.click() text = self.browser.find_by_xpath( "//div[@class='form-row indent']/label").first.value spin_assert(lambda: self.assertNotEqual(text.find("Bob's rel"), -1)) # Creating nodes create_node(self, 'Bob') create_node(self, 'Alice') # Creating relationship between nodes self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath("//td[@class='dataActions']/a[@class='dataOption list']").first.click() self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() self.browser.find_by_xpath("//li[@class='token-input-input-token']/input").first.fill('Alice') self.browser.is_element_present_by_id("id_user_wait", wait_time=5) self.browser.find_by_xpath("//div[@class='token-input-dropdown']//li[@class='token-input-dropdown-item2 token-input-selected-dropdown-item']/b").first.click() self.browser.find_by_value("Save Bob's type").first.click() self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-relationships']").first.value spin_assert(lambda: self.assertEqual(text, "1 relationships")) # Deleting type js_code = "$('a#schema-link')[0].click();" self.browser.execute_script(js_code) self.browser.find_by_xpath("//fieldset[@class='module aligned wide model']/h2/a").first.click() self.browser.find_by_xpath("//span[@class='buttonLinkOption buttonLinkRight']/a[@class='delete']").first.click() text = self.browser.find_by_xpath( "//p/label[@for='id_option_0']").first.value spin_assert(lambda: self.assertNotEqual(text.find( "We found some elements of this type"), -1)) # Deleting nodes self.browser.choose('option', 'de') self.browser.find_by_value('Continue').first.click() text = self.browser.find_by_xpath( "//div[@class='body-inside']/p").first.value spin_assert(lambda: self.assertEqual( text, 'There are no types defined yet.')) # Checking self.browser.find_link_by_href('/graphs/bobs-graph/').first.click() text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-nodes']").first.value spin_assert(lambda: self.assertEqual(text, "0 nodes")) text = self.browser.find_by_xpath("//div[@class='flags-block']/span[@class='graph-relationships']").first.value spin_assert(lambda: self.assertEqual(text, "0 relationships")) Graph.objects.get(name="Bob's graph").destroy() def test_data_node_clone(self): create_graph(self) create_schema(self) create_type(self) create_data(self) original_name = self.browser.find_by_xpath("//table[@id='content_table']/tbody/tr/td")[1].value # Clone the node self.browser.find_by_xpath("//table[@id='content_table']/tbody/tr/td/a[@class='edit']").first.click() self.browser.find_by_name('Name').first.fill(original_name + " clone") self.browser.find_by_name("as-new").first.click() # Check that two nodes exist original_name = self.browser.find_by_xpath("//table[@id='content_table']/tbody/tr/td")[1].value clone_name = self.browser.find_by_xpath("//table[@id='content_table']/tbody/tr/td")[4].value spin_assert(lambda: self.assertEqual(original_name, "Bob's node")) spin_assert(lambda: self.assertEqual(clone_name, "Bob's node clone")) Graph.objects.get(name="Bob's graph").destroy() def test_sigma_visualization_in_node_view(self): create_graph(self) create_schema(self) create_type(self) # Adding relationship to the type self.browser.find_by_id('allowedRelations').first.click() self.browser.select('source', '1') self.browser.find_by_name('name').fill("Bob's rel") self.browser.select('target', '1') self.browser.find_by_id('id_description').fill( 'The loved relationship') self.browser.find_by_value('Save Type').first.click() text = self.browser.find_by_xpath( "//div[@class='form-row indent']/label").first.value spin_assert(lambda: self.assertNotEqual(text.find("Bob's rel"), -1)) # Creating nodes create_node(self, 'Bob') create_node(self, 'Alice') # Creating relationship between nodes self.browser.find_by_id('dataMenu').first.click() self.browser.find_by_xpath("//td[@class='dataActions']/a[@class='dataOption list']").first.click() self.browser.find_by_xpath("//td[@class='dataList']/a[@class='edit']").first.click() self.browser.find_by_xpath("//li[@class='token-input-input-token']/input").first.fill('Alice') self.browser.is_element_present_by_id("id_user_wait", wait_time=5) self.browser.find_by_xpath("//div[@class='token-input-dropdown']//li[@class='token-input-dropdown-item2 token-input-selected-dropdown-item']/b").first.click() self.browser.find_by_value("Save Bob's type").first.click() # Checking self.browser.find_by_xpath("//table[@id='content_table']/tbody/tr/td/a[@title='View node']/p[text()='Alice']").first.click() self.browser.is_element_present_by_id('wait_for_js', 3) js_code = ''' var instance = sigma.instances(0); sylva.test_node_count = instance.graph.nodes().length; ''' self.browser.execute_script(js_code) text = self.browser.evaluate_script('sylva.test_node_count') spin_assert(lambda: self.assertEqual(text, 2)) Graph.objects.get(name="Bob's graph").destroy() def test_graph_export_gexf(self): create_graph(self) create_schema(self) create_type(self) create_data(self) self.browser.find_by_id('toolsMenu').first.click() cookies = {self.browser.cookies.all()[0]["name"]: self.browser.cookies.all()[0]["value"], self.browser.cookies.all()[1]["name"]: self.browser.cookies.all()[1]["value"]} result = requests.get(self.live_server_url + '/tools/bobs-graph/export/gexf/', cookies=cookies) spin_assert(lambda: self.assertEqual( result.headers['content-type'], 'application/xml')) spin_assert(lambda: self.assertEqual( self.browser.status_code.is_success(), True)) fw = open('sylva/sylva/tests/files/bobs-graph.gexf', 'w') fw.write(result.content) fw.close() f = open('sylva/sylva/tests/files/bobs-graph.gexf') xmlFile = "" for line in f: xmlFile += line f.close() spin_assert(lambda: self.assertEqual(xmlFile, result.content)) Graph.objects.get(name="Bob's graph").destroy() def test_graph_export_csv(self): create_graph(self) create_schema(self) create_type(self) create_data(self) self.browser.find_by_id('toolsMenu').first.click() cookies = {self.browser.cookies.all()[0]["name"]: self.browser.cookies.all()[0]["value"], self.browser.cookies.all()[1]["name"]: self.browser.cookies.all()[1]["value"]} result = requests.get(self.live_server_url + '/tools/bobs-graph/export/csv/', cookies=cookies) spin_assert(lambda: self.assertEqual( result.headers['content-type'], 'application/zip')) spin_assert(lambda: self.assertEqual( self.browser.status_code.is_success(), True)) test_file = StringIO(result.content) csv_zip = ZipFile(test_file) for name in csv_zip.namelist(): fw = open('sylva/sylva/tests/files/' + name, 'w') fw.write(csv_zip.read(name)) fw.close() for name in csv_zip.namelist(): f = open('sylva/sylva/tests/files/' + name) csvFile = "" for line in f: csvFile += line f.close() spin_assert(lambda: self.assertEqual(csv_zip.read(name), csvFile)) Graph.objects.get(name="Bob's graph").destroy()