From 1638ecb37331a9a9f960e14553af09fb04ff9254 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 7 Nov 2024 17:10:42 -0800 Subject: [PATCH 01/23] Hardens editable_future_graph against nodegroup changes #11570 --- arches/app/models/graph.py | 167 +++++++--------------- arches/app/utils/editable_future_graph.py | 54 +++++++ 2 files changed, 107 insertions(+), 114 deletions(-) create mode 100644 arches/app/utils/editable_future_graph.py diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 6bc3e78aa0..f4d2a9e99e 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -22,6 +22,7 @@ from copy import deepcopy from django.core.exceptions import ObjectDoesNotExist from django.db import transaction, connection +from django.db.models import OuterRef, Subquery from django.db.utils import IntegrityError from arches.app.const import IntegrityCheck from arches.app.models import models @@ -30,6 +31,7 @@ from arches.app.datatypes.datatypes import DataTypeFactory from arches.app.etl_modules.bulk_data_deletion import BulkDataDeletion from arches.app.utils.betterJSONSerializer import JSONSerializer, JSONDeserializer +from arches.app.utils.editable_future_graph import update_editable_future_nodegroups from arches.app.search.search_engine_factory import SearchEngineFactory from arches.app.utils.i18n import LanguageSynchronizer from django.utils.translation import gettext as _ @@ -2428,34 +2430,6 @@ def update_from_editable_future_graph(self): except: raise Exception(_("No identifiable future Graph")) - def _update_source_nodegroup_hierarchy(nodegroup): - if not nodegroup: - return None - - node = models.Node.objects.get(pk=nodegroup.pk) - if node.source_identifier_id: - source_nodegroup = models.NodeGroup.objects.get( - pk=node.source_identifier_id - ) - - source_nodegroup.cardinality = nodegroup.cardinality - source_nodegroup.legacygroupid = nodegroup.legacygroupid - - if nodegroup.parentnodegroup_id: - nodegroup_parent_node = models.Node.objects.get( - pk=nodegroup.parentnodegroup_id - ) - - if nodegroup_parent_node.source_identifier_id: - source_nodegroup.parentnodegroup_id = ( - nodegroup_parent_node.source_identifier_id - ) - - source_nodegroup.save() - - if nodegroup.parentnodegroup: - _update_source_nodegroup_hierarchy(nodegroup=nodegroup.parentnodegroup) - with transaction.atomic(): self.root.set_relatable_resources( [ @@ -2464,14 +2438,10 @@ def _update_source_nodegroup_hierarchy(nodegroup): ] ) - previous_card_ids = [str(card.pk) for card in self.cards.values()] - previous_node_ids = [str(node.pk) for node in self.nodes.values()] - previous_edge_ids = [str(edge.pk) for edge in self.edges.values()] - previous_widget_ids = [str(widget.pk) for widget in self.widgets.values()] - previous_nodegroup_ids = [ - str(nodegroup.pk) - for nodegroup in self.get_nodegroups(force_recalculation=True) - ] + previous_card_ids = {str(card.pk) for card in self.cards.values()} + previous_node_ids = {str(node.pk) for node in self.nodes.values()} + previous_edge_ids = {str(edge.pk) for edge in self.edges.values()} + previous_widget_ids = {str(widget.pk) for widget in self.widgets.values()} self.cards = {} self.nodes = {} @@ -2485,6 +2455,10 @@ def _update_source_nodegroup_hierarchy(nodegroup): # them to source item. If the item does not have a `source_identifier` attribute, it # has been newly created; we update the `graph_id` to match the source graph. We are # not saving in this block so updates can accur in any order. + update_editable_future_nodegroups( + editable_future_graph.get_nodegroups(force_recalculation=True) + ) + for future_widget in list(editable_future_graph.widgets.values()): source_widget = future_widget.source_identifier @@ -2580,8 +2554,6 @@ def _update_source_nodegroup_hierarchy(nodegroup): del editable_future_graph.cards[future_card.pk] self.cards[future_card.pk] = future_card - _update_source_nodegroup_hierarchy(future_card.nodegroup) - for future_edge in list(editable_future_graph.edges.values()): if future_edge.source_identifier_id: source_edge = future_edge.source_identifier @@ -2642,7 +2614,6 @@ def _update_source_nodegroup_hierarchy(nodegroup): "nodeid", "nodegroup_id", "source_identifier_id", - "is_collector", ]: setattr(source_node, key, getattr(future_node, key)) @@ -2670,8 +2641,6 @@ def _update_source_nodegroup_hierarchy(nodegroup): del editable_future_graph.nodes[future_node.pk] self.nodes[future_node.pk] = future_node - - _update_source_nodegroup_hierarchy(future_node.nodegroup) # END update related models # BEGIN copy attrs from editable_future_graph to source_graph @@ -2705,97 +2674,58 @@ def _update_source_nodegroup_hierarchy(nodegroup): # the editable_future_graph. If the item related to the source graph exists, but the item # related to the editable_future_graph does not exist, the item related to the source graph # should be deleted. - updated_card_ids = [ + updated_widget_ids = { + str(widget.pk) for widget in editable_future_graph.widgets.values() + } + + updated_card_ids = { str(card.source_identifier_id) for card in editable_future_graph.cards.values() - ] - updated_node_ids = [ - str(node.source_identifier_id) - for node in editable_future_graph.nodes.values() - ] - updated_edge_ids = [ + } + + updated_edge_ids = { str(edge.source_identifier_id) for edge in editable_future_graph.edges.values() - ] - updated_widget_ids = [ - str(widget.pk) for widget in editable_future_graph.widgets.values() - ] - - updated_node_ids.append(str(self.root.pk)) - - for previous_widget_id in previous_widget_ids: - if previous_widget_id not in updated_widget_ids: - try: - widget = models.CardXNodeXWidget.objects.get( - pk=previous_widget_id - ) - widget.delete() - except ObjectDoesNotExist: # already deleted - pass - - for previous_card_id in previous_card_ids: - if previous_card_id not in updated_card_ids: - try: - card = models.CardModel.objects.get(pk=previous_card_id) - card.delete() - except ObjectDoesNotExist: # already deleted - pass - - for previous_node_id in previous_node_ids: - if previous_node_id not in updated_node_ids: - try: - node = models.Node.objects.get(pk=previous_node_id) - node.delete() - except ObjectDoesNotExist: # already deleted - pass - - for previous_edge_id in previous_edge_ids: - if previous_edge_id not in updated_edge_ids: - try: - edge = models.Edge.objects.get(pk=previous_edge_id) - edge.delete() - except ObjectDoesNotExist: # already deleted - pass + } - for previous_nodegroup_id in previous_nodegroup_ids: - try: - node = models.Node.objects.get(pk=previous_nodegroup_id) - except ( - ObjectDoesNotExist - ): # node has been moved, therefore empty Nodegroup - nodegroup = models.NodeGroup.objects.get(pk=previous_nodegroup_id) - nodegroup.delete() + updated_node_ids = { + str(node.source_identifier_id) + for node in editable_future_graph.nodes.values() + } + updated_node_ids.add(str(self.root.pk)) + + models.CardXNodeXWidget.objects.filter( + pk__in=set(previous_widget_ids - updated_widget_ids) + | {widget.pk for widget in editable_future_graph.widgets.values()} + ).delete() + + models.CardModel.objects.filter( + pk__in=set(previous_card_ids - updated_card_ids) + | {card.pk for card in editable_future_graph.cards.values()} + ).delete() + + models.Edge.objects.filter( + pk__in=set(previous_edge_ids - updated_edge_ids) + | {edge.pk for edge in editable_future_graph.edges.values()} + ).delete() + + models.Node.objects.filter( + pk__in=set(previous_node_ids - updated_node_ids) + | {node.pk for node in editable_future_graph.nodes.values()} + ).delete() # END delete superflous models # BEGIN save related models # save order is _very_ important! - for widget in editable_future_graph.widgets.values(): - widget.delete() for widget in self.widgets.values(): - try: - widget_from_database = models.CardXNodeXWidget.objects.get( - card_id=widget.card_id, - node_id=widget.node_id, - widget_id=widget.widget_id, - ) - widget_from_database.delete() - except models.CardXNodeXWidget.DoesNotExist: - pass - widget.save() - for card in editable_future_graph.cards.values(): - card.delete() for card in self.cards.values(): card.save() - for edge in editable_future_graph.edges.values(): - edge.delete() for edge in self.edges.values(): edge.save() - for node in editable_future_graph.nodes.values(): - node.delete() for node in self.nodes.values(): node.save() # END save related models @@ -2816,6 +2746,15 @@ def _update_source_nodegroup_hierarchy(nodegroup): ) # returns an updated copy of self graph_from_database.create_editable_future_graph() + # TODO: This is a temporary fix to remove nodegroups that are no longer in use. It should be replaced with a more performant solution. + models.NodeGroup.objects.filter( + ~models.Q( + pk__in=Subquery( + models.Node.objects.values("pk").filter(pk=OuterRef("pk")) + ) + ) + ).delete() + return graph_from_database def revert(self): diff --git a/arches/app/utils/editable_future_graph.py b/arches/app/utils/editable_future_graph.py new file mode 100644 index 0000000000..8c898ee3a7 --- /dev/null +++ b/arches/app/utils/editable_future_graph.py @@ -0,0 +1,54 @@ +from arches.app.models import models + + +def update_editable_future_nodegroups(editable_future_nodegroups): + """ + Update the nodegroups in the source_graph to match those in the + editable_future_graph. + """ + + def _update_source_nodegroup_hierarchy(nodegroup): + if not nodegroup: + return None + + node = models.Node.objects.get(pk=nodegroup.pk) + if node.source_identifier_id: + source_nodegroup = models.NodeGroup.objects.get( + pk=node.source_identifier_id + ) + + source_nodegroup.cardinality = nodegroup.cardinality + source_nodegroup.legacygroupid = nodegroup.legacygroupid + + if nodegroup.parentnodegroup_id: + nodegroup_parent_node = models.Node.objects.get( + pk=nodegroup.parentnodegroup_id + ) + + if nodegroup_parent_node.source_identifier_id: + source_nodegroup.parentnodegroup_id = ( + nodegroup_parent_node.source_identifier_id + ) + + source_nodegroup.save() + + if nodegroup.parentnodegroup: + _update_source_nodegroup_hierarchy(nodegroup=nodegroup.parentnodegroup) + + # creates `NodeGroup`s for source_nodegroups_nodes whose editable_future_node has been used to create a new card + for editable_future_node in models.Node.objects.filter( + nodegroup__in=editable_future_nodegroups + ): + if ( + editable_future_node.source_identifier + and editable_future_node.pk == editable_future_node.nodegroup_id + and editable_future_node.source_identifier.pk + != editable_future_node.source_identifier.nodegroup_id + ): + models.NodeGroup.objects.create( + nodegroupid=editable_future_node.source_identifier.pk, + cardinality=editable_future_node.nodegroup.cardinality, + ) + + for editable_future_nodegroup in editable_future_nodegroups: + _update_source_nodegroup_hierarchy(editable_future_nodegroup) From 6abb19aacec1ed108473dfe69445b3260e05b0aa Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 7 Nov 2024 17:21:34 -0800 Subject: [PATCH 02/23] nit #11570 --- arches/app/models/graph.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index f4d2a9e99e..7baa63b510 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -22,7 +22,6 @@ from copy import deepcopy from django.core.exceptions import ObjectDoesNotExist from django.db import transaction, connection -from django.db.models import OuterRef, Subquery from django.db.utils import IntegrityError from arches.app.const import IntegrityCheck from arches.app.models import models @@ -2747,13 +2746,15 @@ def update_from_editable_future_graph(self): graph_from_database.create_editable_future_graph() # TODO: This is a temporary fix to remove nodegroups that are no longer in use. It should be replaced with a more performant solution. - models.NodeGroup.objects.filter( - ~models.Q( - pk__in=Subquery( - models.Node.objects.values("pk").filter(pk=OuterRef("pk")) - ) + with connection.cursor() as cursor: + cursor.execute( + """ + DELETE FROM node_groups + WHERE NOT EXISTS ( + SELECT 1 FROM nodes WHERE nodes.nodeid = node_groups.nodegroupid + ); + """ ) - ).delete() return graph_from_database From d7372edc4be3cbb3c9652d751410012c99c35d97 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Fri, 8 Nov 2024 15:54:24 -0800 Subject: [PATCH 03/23] correctly hardens editable_future_graphs #11570 --- arches/app/models/graph.py | 380 ++++-------------- arches/app/utils/editable_future_graph.py | 54 --- .../app/utils/editable_future_graph_utils.py | 268 ++++++++++++ 3 files changed, 343 insertions(+), 359 deletions(-) delete mode 100644 arches/app/utils/editable_future_graph.py create mode 100644 arches/app/utils/editable_future_graph_utils.py diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 7baa63b510..71150b166a 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -30,7 +30,7 @@ from arches.app.datatypes.datatypes import DataTypeFactory from arches.app.etl_modules.bulk_data_deletion import BulkDataDeletion from arches.app.utils.betterJSONSerializer import JSONSerializer, JSONDeserializer -from arches.app.utils.editable_future_graph import update_editable_future_nodegroups +from arches.app.utils import editable_future_graph_utils from arches.app.search.search_engine_factory import SearchEngineFactory from arches.app.utils.i18n import LanguageSynchronizer from django.utils.translation import gettext as _ @@ -2430,305 +2430,82 @@ def update_from_editable_future_graph(self): raise Exception(_("No identifiable future Graph")) with transaction.atomic(): - self.root.set_relatable_resources( - [ - node.pk - for node in editable_future_graph.root.get_relatable_resources() - ] + current_nodegroups = self.get_nodegroups(force_recalculation=True) + editable_future_nodegroups = editable_future_graph.get_nodegroups( + force_recalculation=True ) - previous_card_ids = {str(card.pk) for card in self.cards.values()} - previous_node_ids = {str(node.pk) for node in self.nodes.values()} - previous_edge_ids = {str(edge.pk) for edge in self.edges.values()} - previous_widget_ids = {str(widget.pk) for widget in self.widgets.values()} - - self.cards = {} - self.nodes = {} - self.edges = {} - self.widgets = {} - # BEGIN update related models - # Iterates over cards, nodes, and edges of the editable_future_graph. If the item - # has a `source_identifier` attribute, it represents an item related to the source - # graph ( the graph mapped to `self` ); we iterate over the item attributes and map - # them to source item. If the item does not have a `source_identifier` attribute, it - # has been newly created; we update the `graph_id` to match the source graph. We are - # not saving in this block so updates can accur in any order. - update_editable_future_nodegroups( - editable_future_graph.get_nodegroups(force_recalculation=True) - ) - - for future_widget in list(editable_future_graph.widgets.values()): - source_widget = future_widget.source_identifier - - if future_widget.source_identifier_id: - for key in vars(source_widget).keys(): - if key not in [ - "_state", - "id", - "node_id", - "card_id", - "source_identifier_id", - ]: - setattr(source_widget, key, getattr(future_widget, key)) - - if future_widget.card.source_identifier_id: - source_widget.card_id = future_widget.card.source_identifier_id - if future_widget.node.source_identifier_id: - source_widget.node_id = future_widget.node.source_identifier_id - - self.widgets[source_widget.pk] = source_widget - else: # newly-created widget - future_widget.source_identifier_id = None - - if future_widget.card.source_identifier_id: - future_widget.card_id = future_widget.card.source_identifier_id - if future_widget.node.source_identifier_id: - future_widget.node_id = future_widget.node.source_identifier_id - - del editable_future_graph.widgets[future_widget.pk] - self.widgets[future_widget.pk] = future_widget - - for future_card in list(editable_future_graph.cards.values()): - future_card_nodegroup_node = models.Node.objects.get( - pk=future_card.nodegroup.pk - ) - - if future_card.source_identifier: - source_card = future_card.source_identifier - - for key in vars(source_card).keys(): - if key not in [ - "graph_id", - "cardid", - "nodegroup_id", - "source_identifier_id", - ]: - if ( - key == "config" - and str(future_card.component_id) - == "2f9054d8-de57-45cd-8a9c-58bbb1619030" - ): # grouping card - grouped_card_ids = [] - for grouped_card_id in future_card.config[ - "groupedCardIds" - ]: - grouped_card = Card.objects.get(pk=grouped_card_id) - grouped_card_ids.append( - str(grouped_card.source_identifier_id) - ) - - source_card.config["groupedCardIds"] = grouped_card_ids - - sorted_widget_ids = [] - for node_id in future_card.config["sortedWidgetIds"]: - sorted_widget = models.Node.objects.get(pk=node_id) - sorted_widget_ids.append( - str(sorted_widget.source_identifier_id) - ) - - source_card.config["sortedWidgetIds"] = ( - sorted_widget_ids - ) - else: - setattr(source_card, key, getattr(future_card, key)) - - source_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id - if future_card_nodegroup_node.source_identifier_id: - source_card.nodegroup_id = ( - future_card_nodegroup_node.source_identifier_id - ) - - self.cards[source_card.pk] = source_card - else: # newly-created card - future_card.graph_id = self.pk - future_card.source_identifier_id = None - - future_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id - if future_card_nodegroup_node.source_identifier_id: - future_card.nodegroup_id = ( - future_card_nodegroup_node.source_identifier_id - ) - - del editable_future_graph.cards[future_card.pk] - self.cards[future_card.pk] = future_card - - for future_edge in list(editable_future_graph.edges.values()): - if future_edge.source_identifier_id: - source_edge = future_edge.source_identifier - - for key in vars(source_edge).keys(): - if key not in [ - "domainnode_id", - "edgeid", - "graph_id", - "rangenode_id", - "source_identifier_id", - ]: - setattr(source_edge, key, getattr(future_edge, key)) - - source_edge.domainnode_id = future_edge.domainnode_id - if future_edge.domainnode.source_identifier: - source_edge.domainnode_id = ( - future_edge.domainnode.source_identifier.pk - ) - - source_edge.rangenode_id = future_edge.rangenode_id - if future_edge.rangenode.source_identifier: - source_edge.rangenode_id = ( - future_edge.rangenode.source_identifier.pk - ) - - self.edges[source_edge.pk] = source_edge - else: # newly-created edge - future_edge.graph_id = self.pk - future_edge.source_identfier_id = None - - if future_edge.domainnode.source_identifier_id: - future_edge.domainnode_id = ( - future_edge.domainnode.source_identifier_id - ) - - if future_edge.rangenode.source_identifier_id: - future_edge.rangenode_id = ( - future_edge.rangenode.source_identifier_id - ) - - del editable_future_graph.edges[future_edge.pk] - self.edges[future_edge.pk] = future_edge - - for future_node in list(editable_future_graph.nodes.values()): - future_node_nodegroup_node = ( - models.Node.objects.get(pk=future_node.nodegroup.pk) - if future_node.nodegroup - else None - ) - - if future_node.source_identifier: - source_node = future_node.source_identifier - - for key in vars(source_node).keys(): - if key not in [ - "graph_id", - "nodeid", - "nodegroup_id", - "source_identifier_id", - ]: - setattr(source_node, key, getattr(future_node, key)) - - source_node.nodegroup_id = future_node.nodegroup_id - if ( - future_node_nodegroup_node - and future_node_nodegroup_node.source_identifier_id - ): - source_node.nodegroup_id = ( - future_node_nodegroup_node.source_identifier_id - ) - - self.nodes[source_node.pk] = source_node - else: # newly-created node - future_node.graph_id = self.pk - future_node.source_identifier_id = None - - if ( - future_node_nodegroup_node - and future_node_nodegroup_node.source_identifier_id - ): - future_node.nodegroup_id = ( - future_node_nodegroup_node.source_identifier_id - ) + EXCLUDED_NODEGROUP_KEYS = ["nodegroupid", "parentnodegroup_id"] + EXCLUDED_WIDGET_KEYS = [ + "_state", + "id", + "node_id", + "card_id", + "source_identifier_id", + ] + EXCLUDED_CARD_KEYS = [ + "graph_id", + "cardid", + "nodegroup_id", + "source_identifier_id", + ] + EXCLUDED_EDGE_KEYS = [ + "domainnode_id", + "edgeid", + "graph_id", + "rangenode_id", + "source_identifier_id", + ] + EXCLUDED_NODE_KEYS = [ + "graph_id", + "nodeid", + "nodegroup_id", + "source_identifier_id", + ] + EXCLUDED_GRAPH_ATTRIBUTES_KEYS = [ + "_state", + "graphid", + "cards", + "nodes", + "edges", + "widgets", + "root", + "source_identifier", + "source_identifier_id", + "resource_instance_lifecycle", + "resource_instance_lifecycle_id", + "publication_id", + "_nodegroups_to_delete", + "_functions", + "_card_constraints", + "_constraints_x_nodes", + "serialized_graph", + ] - del editable_future_graph.nodes[future_node.pk] - self.nodes[future_node.pk] = future_node + editable_future_graph_utils.update_nodegroups( + self, editable_future_graph, EXCLUDED_NODEGROUP_KEYS + ) + editable_future_graph_utils.update_widgets( + self, editable_future_graph, EXCLUDED_WIDGET_KEYS + ) + editable_future_graph_utils.update_cards( + self, editable_future_graph, EXCLUDED_CARD_KEYS + ) + editable_future_graph_utils.update_edges( + self, editable_future_graph, EXCLUDED_EDGE_KEYS + ) + editable_future_graph_utils.update_nodes( + self, editable_future_graph, EXCLUDED_NODE_KEYS + ) # END update related models # BEGIN copy attrs from editable_future_graph to source_graph - for key, value in vars(editable_future_graph).items(): - if key not in [ - "_state", - "graphid", - "cards", - "nodes", - "edges", - "widgets", - "root", - "source_identifier", - "source_identifier_id", - "resource_instance_lifecycle", - "resource_instance_lifecycle_id", - "publication_id", - "_nodegroups_to_delete", - "_functions", - "_card_constraints", - "_constraints_x_nodes", - "serialized_graph", - ]: - setattr(self, key, value) - - self.root = self.nodes[self.root.pk] + editable_future_graph_utils.update_source_graph( + self, editable_future_graph, EXCLUDED_GRAPH_ATTRIBUTES_KEYS + ) # END copy attrs from editable_future_graph to source_graph - # BEGIN delete superflous models - # Compares UUIDs between models related to the source graph and models related to - # the editable_future_graph. If the item related to the source graph exists, but the item - # related to the editable_future_graph does not exist, the item related to the source graph - # should be deleted. - updated_widget_ids = { - str(widget.pk) for widget in editable_future_graph.widgets.values() - } - - updated_card_ids = { - str(card.source_identifier_id) - for card in editable_future_graph.cards.values() - } - - updated_edge_ids = { - str(edge.source_identifier_id) - for edge in editable_future_graph.edges.values() - } - - updated_node_ids = { - str(node.source_identifier_id) - for node in editable_future_graph.nodes.values() - } - updated_node_ids.add(str(self.root.pk)) - - models.CardXNodeXWidget.objects.filter( - pk__in=set(previous_widget_ids - updated_widget_ids) - | {widget.pk for widget in editable_future_graph.widgets.values()} - ).delete() - - models.CardModel.objects.filter( - pk__in=set(previous_card_ids - updated_card_ids) - | {card.pk for card in editable_future_graph.cards.values()} - ).delete() - - models.Edge.objects.filter( - pk__in=set(previous_edge_ids - updated_edge_ids) - | {edge.pk for edge in editable_future_graph.edges.values()} - ).delete() - - models.Node.objects.filter( - pk__in=set(previous_node_ids - updated_node_ids) - | {node.pk for node in editable_future_graph.nodes.values()} - ).delete() - # END delete superflous models - - # BEGIN save related models - # save order is _very_ important! - for widget in self.widgets.values(): - widget.save() - - for card in self.cards.values(): - card.save() - - for edge in self.edges.values(): - edge.save() - - for node in self.nodes.values(): - node.save() - # END save related models - self.save(validate=False) # This ensures essential objects that have been re-assigned to the `source_graph` @@ -2740,21 +2517,14 @@ def update_from_editable_future_graph(self): editable_future_graph.delete() - graph_from_database = type(self).objects.get( - pk=self.pk - ) # returns an updated copy of self - graph_from_database.create_editable_future_graph() + # delete any nodegroups that are no longer associated with the graph + for nodegroup in current_nodegroups + editable_future_nodegroups: + if not models.Node.objects.filter(pk=nodegroup.pk).exists(): + nodegroup.delete() - # TODO: This is a temporary fix to remove nodegroups that are no longer in use. It should be replaced with a more performant solution. - with connection.cursor() as cursor: - cursor.execute( - """ - DELETE FROM node_groups - WHERE NOT EXISTS ( - SELECT 1 FROM nodes WHERE nodes.nodeid = node_groups.nodegroupid - ); - """ - ) + # returns an updated copy of self + graph_from_database = type(self).objects.get(pk=self.pk) + graph_from_database.create_editable_future_graph() return graph_from_database diff --git a/arches/app/utils/editable_future_graph.py b/arches/app/utils/editable_future_graph.py deleted file mode 100644 index 8c898ee3a7..0000000000 --- a/arches/app/utils/editable_future_graph.py +++ /dev/null @@ -1,54 +0,0 @@ -from arches.app.models import models - - -def update_editable_future_nodegroups(editable_future_nodegroups): - """ - Update the nodegroups in the source_graph to match those in the - editable_future_graph. - """ - - def _update_source_nodegroup_hierarchy(nodegroup): - if not nodegroup: - return None - - node = models.Node.objects.get(pk=nodegroup.pk) - if node.source_identifier_id: - source_nodegroup = models.NodeGroup.objects.get( - pk=node.source_identifier_id - ) - - source_nodegroup.cardinality = nodegroup.cardinality - source_nodegroup.legacygroupid = nodegroup.legacygroupid - - if nodegroup.parentnodegroup_id: - nodegroup_parent_node = models.Node.objects.get( - pk=nodegroup.parentnodegroup_id - ) - - if nodegroup_parent_node.source_identifier_id: - source_nodegroup.parentnodegroup_id = ( - nodegroup_parent_node.source_identifier_id - ) - - source_nodegroup.save() - - if nodegroup.parentnodegroup: - _update_source_nodegroup_hierarchy(nodegroup=nodegroup.parentnodegroup) - - # creates `NodeGroup`s for source_nodegroups_nodes whose editable_future_node has been used to create a new card - for editable_future_node in models.Node.objects.filter( - nodegroup__in=editable_future_nodegroups - ): - if ( - editable_future_node.source_identifier - and editable_future_node.pk == editable_future_node.nodegroup_id - and editable_future_node.source_identifier.pk - != editable_future_node.source_identifier.nodegroup_id - ): - models.NodeGroup.objects.create( - nodegroupid=editable_future_node.source_identifier.pk, - cardinality=editable_future_node.nodegroup.cardinality, - ) - - for editable_future_nodegroup in editable_future_nodegroups: - _update_source_nodegroup_hierarchy(editable_future_nodegroup) diff --git a/arches/app/utils/editable_future_graph_utils.py b/arches/app/utils/editable_future_graph_utils.py new file mode 100644 index 0000000000..30eafc6462 --- /dev/null +++ b/arches/app/utils/editable_future_graph_utils.py @@ -0,0 +1,268 @@ +from arches.app.models import models + + +def update_nodegroups(current_graph, editable_future_graph, excluded_keys): + """ + Update the nodegroups in the source_graph to match those in the editable_future_graph. + """ + + def _update_source_nodegroup_hierarchy(nodegroup): + if not nodegroup: + return None + + node = models.Node.objects.filter(pk=nodegroup.pk).first() + source_nodegroup = None + + # updates source_nodegroup if node has a source_identifier_id + if node and node.source_identifier_id: + source_nodegroup = models.NodeGroup.objects.get( + pk=node.source_identifier_id + ) + for key, value in vars(nodegroup).items(): + if key not in excluded_keys: + setattr(source_nodegroup, key, value) + + # recursively update parent nodegroup relationships if parentnodegroup_id exists + if nodegroup.parentnodegroup_id: + parent_node = models.Node.objects.filter( + pk=nodegroup.parentnodegroup_id + ).first() + if parent_node and parent_node.source_identifier_id: + if source_nodegroup: + source_nodegroup.parentnodegroup_id = ( + parent_node.source_identifier_id + ) + source_nodegroup.save() + + nodegroup.parentnodegroup_id = parent_node.source_identifier_id + nodegroup.save() + + _update_source_nodegroup_hierarchy(nodegroup=nodegroup.parentnodegroup) + + editable_future_nodegroups = editable_future_graph.get_nodegroups( + force_recalculation=True + ) + + for editable_future_node in models.Node.objects.filter( + nodegroup__in=editable_future_nodegroups + ): + if ( + editable_future_node.source_identifier + and editable_future_node.pk == editable_future_node.nodegroup_id + and editable_future_node.source_identifier.pk + != editable_future_node.source_identifier.nodegroup_id + ): + models.NodeGroup.objects.create( + nodegroupid=editable_future_node.source_identifier.pk, + cardinality=editable_future_node.nodegroup.cardinality, + ) + + for editable_future_nodegroup in editable_future_nodegroups: + _update_source_nodegroup_hierarchy(editable_future_nodegroup) + + +def update_nodes(current_graph, editable_future_graph, excluded_keys): + previous_node_ids = {str(node.pk) for node in current_graph.nodes.values()} + current_graph.nodes = {} + + for future_node in list(editable_future_graph.nodes.values()): + future_node_nodegroup_node = ( + models.Node.objects.get(pk=future_node.nodegroup.pk) + if future_node.nodegroup + else None + ) + + if future_node.source_identifier: + source_node = future_node.source_identifier + + for key in vars(source_node).keys(): + if key not in excluded_keys: + setattr(source_node, key, getattr(future_node, key)) + + source_node.nodegroup_id = future_node.nodegroup_id + if ( + future_node_nodegroup_node + and future_node_nodegroup_node.source_identifier_id + ): + source_node.nodegroup_id = ( + future_node_nodegroup_node.source_identifier_id + ) + + current_graph.nodes[source_node.pk] = source_node + else: + future_node.graph_id = current_graph.pk + future_node.source_identifier_id = None + + if ( + future_node_nodegroup_node + and future_node_nodegroup_node.source_identifier_id + ): + future_node.nodegroup_id = ( + future_node_nodegroup_node.source_identifier_id + ) + + del editable_future_graph.nodes[future_node.pk] + current_graph.nodes[future_node.pk] = future_node + + updated_node_ids = { + str(node.source_identifier_id) for node in editable_future_graph.nodes.values() + } + updated_node_ids.add(str(current_graph.root.pk)) + + models.Node.objects.filter( + pk__in=set(previous_node_ids - updated_node_ids) + | {node.pk for node in editable_future_graph.nodes.values()} + ).delete() + + for node in current_graph.nodes.values(): + node.save() + + +def update_edges(current_graph, editable_future_graph, excluded_keys): + previous_edge_ids = {str(edge.pk) for edge in current_graph.edges.values()} + current_graph.edges = {} + + for future_edge in list(editable_future_graph.edges.values()): + if future_edge.source_identifier_id: + source_edge = future_edge.source_identifier + + for key in vars(source_edge).keys(): + if key not in excluded_keys: + setattr(source_edge, key, getattr(future_edge, key)) + + source_edge.domainnode_id = future_edge.domainnode_id + if future_edge.domainnode.source_identifier: + source_edge.domainnode_id = future_edge.domainnode.source_identifier.pk + + source_edge.rangenode_id = future_edge.rangenode_id + if future_edge.rangenode.source_identifier: + source_edge.rangenode_id = future_edge.rangenode.source_identifier.pk + + current_graph.edges[source_edge.pk] = source_edge + else: + future_edge.graph_id = current_graph.pk + future_edge.source_identifier_id = None + + if future_edge.domainnode.source_identifier_id: + future_edge.domainnode_id = future_edge.domainnode.source_identifier_id + + if future_edge.rangenode.source_identifier_id: + future_edge.rangenode_id = future_edge.rangenode.source_identifier_id + + del editable_future_graph.edges[future_edge.pk] + current_graph.edges[future_edge.pk] = future_edge + + updated_edge_ids = { + str(edge.source_identifier_id) for edge in editable_future_graph.edges.values() + } + + models.Edge.objects.filter( + pk__in=set(previous_edge_ids - updated_edge_ids) + | {edge.pk for edge in editable_future_graph.edges.values()} + ).delete() + + for edge in current_graph.edges.values(): + edge.save() + + +def update_cards(current_graph, editable_future_graph, excluded_keys): + previous_card_ids = {str(card.pk) for card in current_graph.cards.values()} + current_graph.cards = {} + + for future_card in list(editable_future_graph.cards.values()): + future_card_nodegroup_node = models.Node.objects.get( + pk=future_card.nodegroup.pk + ) + + if future_card.source_identifier: + source_card = future_card.source_identifier + + for key in vars(source_card).keys(): + if key not in excluded_keys: + setattr(source_card, key, getattr(future_card, key)) + + source_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id + if future_card_nodegroup_node.source_identifier_id: + source_card.nodegroup_id = ( + future_card_nodegroup_node.source_identifier_id + ) + + current_graph.cards[source_card.pk] = source_card + else: + future_card.graph_id = current_graph.pk + future_card.source_identifier_id = None + + future_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id + if future_card_nodegroup_node.source_identifier_id: + future_card.nodegroup_id = ( + future_card_nodegroup_node.source_identifier_id + ) + + del editable_future_graph.cards[future_card.pk] + current_graph.cards[future_card.pk] = future_card + + updated_card_ids = { + str(card.source_identifier_id) for card in editable_future_graph.cards.values() + } + + models.CardModel.objects.filter( + pk__in=set(previous_card_ids - updated_card_ids) + | {card.pk for card in editable_future_graph.cards.values()} + ).delete() + + for card in current_graph.cards.values(): + card.save() + + +def update_widgets(current_graph, editable_future_graph, excluded_keys): + previous_widget_ids = {str(widget.pk) for widget in current_graph.widgets.values()} + current_graph.widgets = {} + + for future_widget in list(editable_future_graph.widgets.values()): + if future_widget.source_identifier_id: + source_widget = future_widget.source_identifier + + for key in vars(source_widget).keys(): + if key not in excluded_keys: + setattr(source_widget, key, getattr(future_widget, key)) + + if future_widget.card.source_identifier_id: + source_widget.card_id = future_widget.card.source_identifier_id + if future_widget.node.source_identifier_id: + source_widget.node_id = future_widget.node.source_identifier_id + + current_graph.widgets[source_widget.pk] = source_widget + else: + future_widget.source_identifier_id = None + + if future_widget.card.source_identifier_id: + future_widget.card_id = future_widget.card.source_identifier_id + if future_widget.node.source_identifier_id: + future_widget.node_id = future_widget.node.source_identifier_id + + del editable_future_graph.widgets[future_widget.pk] + current_graph.widgets[future_widget.pk] = future_widget + + updated_widget_ids = { + str(widget.source_identifier_id) + for widget in editable_future_graph.widgets.values() + } + + models.CardXNodeXWidget.objects.filter( + pk__in=set(previous_widget_ids - updated_widget_ids) + | {widget.pk for widget in editable_future_graph.widgets.values()} + ).delete() + + for widget in current_graph.widgets.values(): + widget.save() + + +def update_source_graph(current_graph, editable_future_graph, excluded_keys): + for key, value in vars(editable_future_graph).items(): + if key not in excluded_keys: + setattr(current_graph, key, value) + + current_graph.root = current_graph.nodes[current_graph.root.pk] + current_graph.root.set_relatable_resources( + [node.pk for node in editable_future_graph.root.get_relatable_resources()] + ) From d7e2bfcd9f70762cac67dc46b320d4da6a5ce197 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 00:53:16 -0800 Subject: [PATCH 04/23] re-architect editable_future_graphs #11570 --- arches/app/models/card.py | 4 +- arches/app/models/graph.py | 353 ++++++++++++++++++++----------------- arches/app/views/graph.py | 4 +- 3 files changed, 192 insertions(+), 169 deletions(-) diff --git a/arches/app/models/card.py b/arches/app/models/card.py index 88fc304826..1dfc5c9b1f 100644 --- a/arches/app/models/card.py +++ b/arches/app/models/card.py @@ -207,8 +207,8 @@ def save(self): edge.ontologyproperty = self.ontologyproperty edge.save() - self.nodegroup.cardinality = self.cardinality - self.nodegroup.save() + # self.nodegroup.cardinality = self.cardinality + # self.nodegroup.save() super(Card, self).save() for widget in self.widgets: diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 71150b166a..fafa34832c 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -735,7 +735,7 @@ def delete(self): except Graph.DoesNotExist: pass # no editable future graph to delete - for nodegroup in self.get_nodegroups(): + for nodegroup in self.get_nodegroups(force_recalculation=True): nodegroup.delete() for edge in self.edges.values(): @@ -2426,107 +2426,122 @@ def update_from_editable_future_graph(self): """ try: editable_future_graph = Graph.objects.get(source_identifier_id=self.pk) - except: + except Graph.DoesNotExist: raise Exception(_("No identifiable future Graph")) with transaction.atomic(): - current_nodegroups = self.get_nodegroups(force_recalculation=True) - editable_future_nodegroups = editable_future_graph.get_nodegroups( - force_recalculation=True + foo = JSONDeserializer().deserialize(JSONSerializer().serialize(self)) + bar = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) ) - # BEGIN update related models - EXCLUDED_NODEGROUP_KEYS = ["nodegroupid", "parentnodegroup_id"] - EXCLUDED_WIDGET_KEYS = [ - "_state", - "id", - "node_id", - "card_id", - "source_identifier_id", - ] - EXCLUDED_CARD_KEYS = [ - "graph_id", - "cardid", - "nodegroup_id", - "source_identifier_id", - ] - EXCLUDED_EDGE_KEYS = [ - "domainnode_id", - "edgeid", - "graph_id", - "rangenode_id", - "source_identifier_id", - ] - EXCLUDED_NODE_KEYS = [ - "graph_id", - "nodeid", - "nodegroup_id", - "source_identifier_id", - ] - EXCLUDED_GRAPH_ATTRIBUTES_KEYS = [ - "_state", - "graphid", - "cards", - "nodes", - "edges", - "widgets", - "root", - "source_identifier", - "source_identifier_id", - "resource_instance_lifecycle", - "resource_instance_lifecycle_id", - "publication_id", - "_nodegroups_to_delete", - "_functions", - "_card_constraints", - "_constraints_x_nodes", - "serialized_graph", - ] + # import pdb; pdb.set_trace() + node_id_to_node_source_identifier_id = { + node["nodeid"]: node["source_identifier_id"] + for node in bar["nodes"] + if node["source_identifier_id"] + } - editable_future_graph_utils.update_nodegroups( - self, editable_future_graph, EXCLUDED_NODEGROUP_KEYS - ) - editable_future_graph_utils.update_widgets( - self, editable_future_graph, EXCLUDED_WIDGET_KEYS - ) - editable_future_graph_utils.update_cards( - self, editable_future_graph, EXCLUDED_CARD_KEYS - ) - editable_future_graph_utils.update_edges( - self, editable_future_graph, EXCLUDED_EDGE_KEYS - ) - editable_future_graph_utils.update_nodes( - self, editable_future_graph, EXCLUDED_NODE_KEYS - ) - # END update related models + card_id_to_card_source_identifier_id = { + card["cardid"]: card["source_identifier_id"] + for card in bar["cards"] + if card["source_identifier_id"] + } - # BEGIN copy attrs from editable_future_graph to source_graph - editable_future_graph_utils.update_source_graph( - self, editable_future_graph, EXCLUDED_GRAPH_ATTRIBUTES_KEYS - ) - # END copy attrs from editable_future_graph to source_graph + for serialized_card_x_node_x_widget in bar["cards_x_nodes_x_widgets"]: + if serialized_card_x_node_x_widget["source_identifier_id"]: + serialized_card_x_node_x_widget["id"] = ( + serialized_card_x_node_x_widget["source_identifier_id"] + ) + serialized_card_x_node_x_widget["source_identifier_id"] = None - self.save(validate=False) + updated_card_id = card_id_to_card_source_identifier_id.get( + serialized_card_x_node_x_widget["card_id"] + ) + if updated_card_id: + serialized_card_x_node_x_widget["card_id"] = updated_card_id - # This ensures essential objects that have been re-assigned to the `source_graph` - # are NOT deleted via waterfall deletion when the `editable_future_graph` is deleted. - editable_future_graph.cards = {} - editable_future_graph.nodes = {} - editable_future_graph.edges = {} - editable_future_graph.widgets = {} + updated_node_id = node_id_to_node_source_identifier_id.get( + serialized_card_x_node_x_widget["node_id"] + ) + if updated_node_id: + serialized_card_x_node_x_widget["node_id"] = updated_node_id - editable_future_graph.delete() + for serialized_card in bar["cards"]: + if serialized_card["source_identifier_id"]: + serialized_card["cardid"] = serialized_card["source_identifier_id"] + serialized_card["source_identifier_id"] = None - # delete any nodegroups that are no longer associated with the graph - for nodegroup in current_nodegroups + editable_future_nodegroups: - if not models.Node.objects.filter(pk=nodegroup.pk).exists(): - nodegroup.delete() + source_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_card["nodegroup_id"] + ) + if source_nodegroup_id: + serialized_card["nodegroup_id"] = source_nodegroup_id + + serialized_card["graph_id"] = str(self.pk) + + for serialized_node in bar["nodes"]: + if serialized_node["source_identifier_id"]: + serialized_node["nodeid"] = serialized_node["source_identifier_id"] + serialized_node["source_identifier_id"] = None + + updated_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_node["nodegroup_id"] + ) + if updated_nodegroup_id: + serialized_node["nodegroup_id"] = updated_nodegroup_id + + serialized_node["graph_id"] = str(self.pk) + + for serialized_nodegroup in bar["nodegroups"]: + updated_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_nodegroup["nodegroupid"] + ) + if updated_nodegroup_id: + serialized_nodegroup["nodegroupid"] = updated_nodegroup_id + + updated_parent_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_nodegroup["parentnodegroup_id"] + ) + if updated_nodegroup_id: + serialized_nodegroup["parentnodegroup_id"] = ( + updated_parent_nodegroup_id + ) + + for serialized_edge in bar["edges"]: + if serialized_edge["source_identifier_id"]: + serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] + serialized_edge["source_identifier_id"] = None + + source_domain_node_id = node_id_to_node_source_identifier_id.get( + serialized_edge["domainnode_id"] + ) + if source_domain_node_id: + serialized_edge["domainnode_id"] = source_domain_node_id - # returns an updated copy of self - graph_from_database = type(self).objects.get(pk=self.pk) - graph_from_database.create_editable_future_graph() + source_range_node_id = node_id_to_node_source_identifier_id.get( + serialized_edge["rangenode_id"] + ) + if source_range_node_id: + serialized_edge["rangenode_id"] = source_range_node_id + + serialized_edge["graph_id"] = str(self.pk) + + bar["graphid"] = str(self.pk) + bar["has_unpublished_changes"] = False + bar["resource_instance_lifecycle_id"] = foo[ + "resource_instance_lifecycle_id" + ] + bar["root"]["graph_id"] = str(self.pk) + bar["root"]["nodeid"] = bar["root"]["source_identifier_id"] - return graph_from_database + bar["root"]["source_identifier_id"] = None + + bar["source_identifier_id"] = None + + editable_future_graph.delete() + + return self.restore_state_from_serialized_graph(bar) def revert(self): """ @@ -2543,99 +2558,107 @@ def restore_state_from_serialized_graph(self, serialized_graph): Restores a Graph's state from a serialized graph, and creates a new editable_future_graph """ - models.NodeGroup.objects.filter( - pk__in=[ - nodegroup.pk - for nodegroup in self.get_nodegroups(force_recalculation=True) - ] - ).delete() - models.Node.objects.filter( - pk__in=[node.pk for node in self.nodes.values()] - ).delete() - models.Edge.objects.filter( - pk__in=[edge.pk for edge in self.edges.values()] - ).delete() - models.CardModel.objects.filter( - pk__in=[card.pk for card in self.cards.values()] - ).delete() - models.CardXNodeXWidget.objects.filter( - pk__in=[ - card_x_node_x_widget.pk - for card_x_node_x_widget in self.widgets.values() - ] - ).delete() + with transaction.atomic(): + models.NodeGroup.objects.filter( + pk__in=[ + nodegroup.pk + for nodegroup in self.get_nodegroups(force_recalculation=True) + ] + ).delete() + models.Node.objects.filter( + pk__in=[node.pk for node in self.nodes.values()] + ).delete() + models.Edge.objects.filter( + pk__in=[edge.pk for edge in self.edges.values()] + ).delete() + models.CardModel.objects.filter( + pk__in=[card.pk for card in self.cards.values()] + ).delete() + models.CardXNodeXWidget.objects.filter( + pk__in=[ + card_x_node_x_widget.pk + for card_x_node_x_widget in self.widgets.values() + ] + ).delete() - for serialized_nodegroup in serialized_graph["nodegroups"]: - for key, value in serialized_nodegroup.items(): - try: - serialized_nodegroup[key] = uuid.UUID(value) - except: - pass + # ensures any resources that were related to the source graph are not deleted + self.pk = uuid.uuid4() + self.save() + self.delete() - nodegroup = models.NodeGroup(**serialized_nodegroup) - nodegroup.save() + for serialized_nodegroup in serialized_graph["nodegroups"]: + for key, value in serialized_nodegroup.items(): + try: + serialized_nodegroup[key] = uuid.UUID(value) + except: + pass - for serialized_node in serialized_graph["nodes"]: - for key, value in serialized_node.items(): - try: - serialized_node[key] = uuid.UUID(value) - except: - pass + nodegroup = models.NodeGroup(**serialized_nodegroup) + nodegroup.save() + + for serialized_node in serialized_graph["nodes"]: + for key, value in serialized_node.items(): + try: + serialized_node[key] = uuid.UUID(value) + except: + pass - del serialized_node["is_collector"] - del serialized_node["parentproperty"] + del serialized_node["is_collector"] + del serialized_node["parentproperty"] - node = models.Node(**serialized_node) - node.save() + node = models.Node(**serialized_node) + node.save() - for serialized_edge in serialized_graph["edges"]: - for key, value in serialized_edge.items(): - try: - serialized_edge[key] = uuid.UUID(value) - except: - pass + for serialized_edge in serialized_graph["edges"]: + for key, value in serialized_edge.items(): + try: + serialized_edge[key] = uuid.UUID(value) + except: + pass - edge = models.Edge(**serialized_edge) - edge.save() + edge = models.Edge(**serialized_edge) + edge.save() - for serialized_card in serialized_graph["cards"]: - for key, value in serialized_card.items(): - try: - serialized_card[key] = uuid.UUID(value) - except: - pass + for serialized_card in serialized_graph["cards"]: + for key, value in serialized_card.items(): + try: + serialized_card[key] = uuid.UUID(value) + except: + pass - del serialized_card["constraints"] + del serialized_card["constraints"] - if "is_editable" in serialized_card: - del serialized_card["is_editable"] + if "is_editable" in serialized_card: + del serialized_card["is_editable"] - card = Card(**serialized_card) - card.save() + card = Card(**serialized_card) + card.save() - widget_dict = {} - for serialized_widget in serialized_graph.get( - "widgets", serialized_graph.get("cards_x_nodes_x_widgets") - ): - for key, value in serialized_widget.items(): - try: - serialized_widget[key] = uuid.UUID(value) - except: - pass + widget_dict = {} + for serialized_widget in serialized_graph.get( + "widgets", serialized_graph.get("cards_x_nodes_x_widgets") + ): + for key, value in serialized_widget.items(): + try: + serialized_widget[key] = uuid.UUID(value) + except: + pass + + updated_widget = models.CardXNodeXWidget(**serialized_widget) + updated_widget.save() - updated_widget = models.CardXNodeXWidget(**serialized_widget) - updated_widget.save() + widget_dict[updated_widget.pk] = updated_widget - widget_dict[updated_widget.pk] = updated_widget + updated_graph = Graph(serialized_graph) + updated_graph.widgets = widget_dict + updated_graph.is_active = self.is_active - updated_graph = Graph(serialized_graph) - updated_graph.widgets = widget_dict - updated_graph.is_active = self.is_active + # import pdb; pdb.set_trace() - updated_graph.save() - updated_graph.create_editable_future_graph() + updated_graph.save() + updated_graph.create_editable_future_graph() - return Graph.objects.get(pk=updated_graph.pk) + return Graph.objects.get(pk=updated_graph.pk) def publish(self, user=None, notes=None): """ diff --git a/arches/app/views/graph.py b/arches/app/views/graph.py index 660b022197..8596e34c53 100644 --- a/arches/app/views/graph.py +++ b/arches/app/views/graph.py @@ -690,8 +690,8 @@ def post(self, request, graphid): try: data = JSONDeserializer().deserialize(request.body) - source_graph.update_from_editable_future_graph() - source_graph.publish(notes=data.get("notes"), user=request.user) + updated_graph = source_graph.update_from_editable_future_graph() + updated_graph.publish(notes=data.get("notes"), user=request.user) return JSONResponse( { From b6c6a8d266d14e2b0b3f22c9a86141acde7be393 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 08:39:06 -0800 Subject: [PATCH 05/23] nit #11570 --- arches/app/models/card.py | 3 --- arches/app/models/graph.py | 55 ++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/arches/app/models/card.py b/arches/app/models/card.py index 1dfc5c9b1f..c7fab63e46 100644 --- a/arches/app/models/card.py +++ b/arches/app/models/card.py @@ -207,9 +207,6 @@ def save(self): edge.ontologyproperty = self.ontologyproperty edge.save() - # self.nodegroup.cardinality = self.cardinality - # self.nodegroup.save() - super(Card, self).save() for widget in self.widgets: widget.save() diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index fafa34832c..a68245ac97 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -2431,24 +2431,25 @@ def update_from_editable_future_graph(self): with transaction.atomic(): foo = JSONDeserializer().deserialize(JSONSerializer().serialize(self)) - bar = JSONDeserializer().deserialize( + serialized_editiable_future_graph = JSONDeserializer().deserialize( JSONSerializer().serialize(editable_future_graph) ) - # import pdb; pdb.set_trace() node_id_to_node_source_identifier_id = { node["nodeid"]: node["source_identifier_id"] - for node in bar["nodes"] + for node in serialized_editiable_future_graph["nodes"] if node["source_identifier_id"] } card_id_to_card_source_identifier_id = { card["cardid"]: card["source_identifier_id"] - for card in bar["cards"] + for card in serialized_editiable_future_graph["cards"] if card["source_identifier_id"] } - for serialized_card_x_node_x_widget in bar["cards_x_nodes_x_widgets"]: + for serialized_card_x_node_x_widget in serialized_editiable_future_graph[ + "cards_x_nodes_x_widgets" + ]: if serialized_card_x_node_x_widget["source_identifier_id"]: serialized_card_x_node_x_widget["id"] = ( serialized_card_x_node_x_widget["source_identifier_id"] @@ -2467,7 +2468,7 @@ def update_from_editable_future_graph(self): if updated_node_id: serialized_card_x_node_x_widget["node_id"] = updated_node_id - for serialized_card in bar["cards"]: + for serialized_card in serialized_editiable_future_graph["cards"]: if serialized_card["source_identifier_id"]: serialized_card["cardid"] = serialized_card["source_identifier_id"] serialized_card["source_identifier_id"] = None @@ -2480,7 +2481,7 @@ def update_from_editable_future_graph(self): serialized_card["graph_id"] = str(self.pk) - for serialized_node in bar["nodes"]: + for serialized_node in serialized_editiable_future_graph["nodes"]: if serialized_node["source_identifier_id"]: serialized_node["nodeid"] = serialized_node["source_identifier_id"] serialized_node["source_identifier_id"] = None @@ -2493,7 +2494,7 @@ def update_from_editable_future_graph(self): serialized_node["graph_id"] = str(self.pk) - for serialized_nodegroup in bar["nodegroups"]: + for serialized_nodegroup in serialized_editiable_future_graph["nodegroups"]: updated_nodegroup_id = node_id_to_node_source_identifier_id.get( serialized_nodegroup["nodegroupid"] ) @@ -2508,7 +2509,7 @@ def update_from_editable_future_graph(self): updated_parent_nodegroup_id ) - for serialized_edge in bar["edges"]: + for serialized_edge in serialized_editiable_future_graph["edges"]: if serialized_edge["source_identifier_id"]: serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] serialized_edge["source_identifier_id"] = None @@ -2527,21 +2528,24 @@ def update_from_editable_future_graph(self): serialized_edge["graph_id"] = str(self.pk) - bar["graphid"] = str(self.pk) - bar["has_unpublished_changes"] = False - bar["resource_instance_lifecycle_id"] = foo[ + serialized_editiable_future_graph["root"]["graph_id"] = str(self.pk) + serialized_editiable_future_graph["root"]["nodeid"] = ( + serialized_editiable_future_graph["root"]["source_identifier_id"] + ) + serialized_editiable_future_graph["root"]["source_identifier_id"] = None + + serialized_editiable_future_graph["has_unpublished_changes"] = False + serialized_editiable_future_graph["resource_instance_lifecycle_id"] = foo[ "resource_instance_lifecycle_id" ] - bar["root"]["graph_id"] = str(self.pk) - bar["root"]["nodeid"] = bar["root"]["source_identifier_id"] - - bar["root"]["source_identifier_id"] = None - - bar["source_identifier_id"] = None + serialized_editiable_future_graph["source_identifier_id"] = None + serialized_editiable_future_graph["graphid"] = str(self.pk) editable_future_graph.delete() - return self.restore_state_from_serialized_graph(bar) + return self.restore_state_from_serialized_graph( + serialized_editiable_future_graph + ) def revert(self): """ @@ -2653,7 +2657,18 @@ def restore_state_from_serialized_graph(self, serialized_graph): updated_graph.widgets = widget_dict updated_graph.is_active = self.is_active - # import pdb; pdb.set_trace() + relatable_resource_model_nodes = models.Node.objects.filter( + graph_id__in=serialized_graph["relatable_resource_model_ids"], + istopnode=True, + ) + updated_graph.root.set_relatable_resources( + list( + { + node.source_identifier.pk if node.source_identifier else node.pk + for node in relatable_resource_model_nodes + } + ) + ) updated_graph.save() updated_graph.create_editable_future_graph() From e1b497fc93c0af2224863d2cbe51a76380f52bf0 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 08:40:47 -0800 Subject: [PATCH 06/23] nit #11570 --- arches/app/models/graph.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index a68245ac97..d8dec22d2c 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -2430,7 +2430,6 @@ def update_from_editable_future_graph(self): raise Exception(_("No identifiable future Graph")) with transaction.atomic(): - foo = JSONDeserializer().deserialize(JSONSerializer().serialize(self)) serialized_editiable_future_graph = JSONDeserializer().deserialize( JSONSerializer().serialize(editable_future_graph) ) @@ -2535,9 +2534,9 @@ def update_from_editable_future_graph(self): serialized_editiable_future_graph["root"]["source_identifier_id"] = None serialized_editiable_future_graph["has_unpublished_changes"] = False - serialized_editiable_future_graph["resource_instance_lifecycle_id"] = foo[ - "resource_instance_lifecycle_id" - ] + serialized_editiable_future_graph["resource_instance_lifecycle_id"] = str( + self.resource_instance_lifecycle_id + ) serialized_editiable_future_graph["source_identifier_id"] = None serialized_editiable_future_graph["graphid"] = str(self.pk) From 2a34dc3cab6cc321ccfcfb4b39244637b9fb5fb9 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 09:41:07 -0800 Subject: [PATCH 07/23] nit #11570 --- arches/app/models/graph.py | 221 ++++++++++++++++--------------------- arches/app/views/graph.py | 8 +- 2 files changed, 100 insertions(+), 129 deletions(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index d8dec22d2c..f588cf46ed 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -2418,133 +2418,123 @@ def create_editable_future_graph(self): return editable_future_graph - def update_from_editable_future_graph(self): + def update_from_editable_future_graph(self, editable_future_graph): """ Updates the graph with any changes made to the editable future graph, removes the editable future graph and related resources, then creates an editable future graph from the updated graph. """ - try: - editable_future_graph = Graph.objects.get(source_identifier_id=self.pk) - except Graph.DoesNotExist: - raise Exception(_("No identifiable future Graph")) - - with transaction.atomic(): - serialized_editiable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - - node_id_to_node_source_identifier_id = { - node["nodeid"]: node["source_identifier_id"] - for node in serialized_editiable_future_graph["nodes"] - if node["source_identifier_id"] - } - - card_id_to_card_source_identifier_id = { - card["cardid"]: card["source_identifier_id"] - for card in serialized_editiable_future_graph["cards"] - if card["source_identifier_id"] - } - - for serialized_card_x_node_x_widget in serialized_editiable_future_graph[ - "cards_x_nodes_x_widgets" - ]: - if serialized_card_x_node_x_widget["source_identifier_id"]: - serialized_card_x_node_x_widget["id"] = ( - serialized_card_x_node_x_widget["source_identifier_id"] - ) - serialized_card_x_node_x_widget["source_identifier_id"] = None + serialized_editiable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) - updated_card_id = card_id_to_card_source_identifier_id.get( - serialized_card_x_node_x_widget["card_id"] - ) - if updated_card_id: - serialized_card_x_node_x_widget["card_id"] = updated_card_id + node_id_to_node_source_identifier_id = { + node["nodeid"]: node["source_identifier_id"] + for node in serialized_editiable_future_graph["nodes"] + if node["source_identifier_id"] + } - updated_node_id = node_id_to_node_source_identifier_id.get( - serialized_card_x_node_x_widget["node_id"] - ) - if updated_node_id: - serialized_card_x_node_x_widget["node_id"] = updated_node_id + card_id_to_card_source_identifier_id = { + card["cardid"]: card["source_identifier_id"] + for card in serialized_editiable_future_graph["cards"] + if card["source_identifier_id"] + } - for serialized_card in serialized_editiable_future_graph["cards"]: - if serialized_card["source_identifier_id"]: - serialized_card["cardid"] = serialized_card["source_identifier_id"] - serialized_card["source_identifier_id"] = None + for serialized_card_x_node_x_widget in serialized_editiable_future_graph[ + "cards_x_nodes_x_widgets" + ]: + if serialized_card_x_node_x_widget["source_identifier_id"]: + serialized_card_x_node_x_widget["id"] = serialized_card_x_node_x_widget[ + "source_identifier_id" + ] + serialized_card_x_node_x_widget["source_identifier_id"] = None - source_nodegroup_id = node_id_to_node_source_identifier_id.get( - serialized_card["nodegroup_id"] - ) - if source_nodegroup_id: - serialized_card["nodegroup_id"] = source_nodegroup_id + updated_card_id = card_id_to_card_source_identifier_id.get( + serialized_card_x_node_x_widget["card_id"] + ) + if updated_card_id: + serialized_card_x_node_x_widget["card_id"] = updated_card_id - serialized_card["graph_id"] = str(self.pk) + updated_node_id = node_id_to_node_source_identifier_id.get( + serialized_card_x_node_x_widget["node_id"] + ) + if updated_node_id: + serialized_card_x_node_x_widget["node_id"] = updated_node_id - for serialized_node in serialized_editiable_future_graph["nodes"]: - if serialized_node["source_identifier_id"]: - serialized_node["nodeid"] = serialized_node["source_identifier_id"] - serialized_node["source_identifier_id"] = None + for serialized_card in serialized_editiable_future_graph["cards"]: + if serialized_card["source_identifier_id"]: + serialized_card["cardid"] = serialized_card["source_identifier_id"] + serialized_card["source_identifier_id"] = None - updated_nodegroup_id = node_id_to_node_source_identifier_id.get( - serialized_node["nodegroup_id"] - ) - if updated_nodegroup_id: - serialized_node["nodegroup_id"] = updated_nodegroup_id + source_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_card["nodegroup_id"] + ) + if source_nodegroup_id: + serialized_card["nodegroup_id"] = source_nodegroup_id - serialized_node["graph_id"] = str(self.pk) + serialized_card["graph_id"] = str(self.pk) - for serialized_nodegroup in serialized_editiable_future_graph["nodegroups"]: - updated_nodegroup_id = node_id_to_node_source_identifier_id.get( - serialized_nodegroup["nodegroupid"] - ) - if updated_nodegroup_id: - serialized_nodegroup["nodegroupid"] = updated_nodegroup_id + for serialized_node in serialized_editiable_future_graph["nodes"]: + if serialized_node["source_identifier_id"]: + serialized_node["nodeid"] = serialized_node["source_identifier_id"] + serialized_node["source_identifier_id"] = None - updated_parent_nodegroup_id = node_id_to_node_source_identifier_id.get( - serialized_nodegroup["parentnodegroup_id"] - ) - if updated_nodegroup_id: - serialized_nodegroup["parentnodegroup_id"] = ( - updated_parent_nodegroup_id - ) + updated_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_node["nodegroup_id"] + ) + if updated_nodegroup_id: + serialized_node["nodegroup_id"] = updated_nodegroup_id - for serialized_edge in serialized_editiable_future_graph["edges"]: - if serialized_edge["source_identifier_id"]: - serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] - serialized_edge["source_identifier_id"] = None + serialized_node["graph_id"] = str(self.pk) - source_domain_node_id = node_id_to_node_source_identifier_id.get( - serialized_edge["domainnode_id"] - ) - if source_domain_node_id: - serialized_edge["domainnode_id"] = source_domain_node_id + for serialized_nodegroup in serialized_editiable_future_graph["nodegroups"]: + updated_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_nodegroup["nodegroupid"] + ) + if updated_nodegroup_id: + serialized_nodegroup["nodegroupid"] = updated_nodegroup_id - source_range_node_id = node_id_to_node_source_identifier_id.get( - serialized_edge["rangenode_id"] - ) - if source_range_node_id: - serialized_edge["rangenode_id"] = source_range_node_id + updated_parent_nodegroup_id = node_id_to_node_source_identifier_id.get( + serialized_nodegroup["parentnodegroup_id"] + ) + if updated_nodegroup_id: + serialized_nodegroup["parentnodegroup_id"] = updated_parent_nodegroup_id - serialized_edge["graph_id"] = str(self.pk) + for serialized_edge in serialized_editiable_future_graph["edges"]: + if serialized_edge["source_identifier_id"]: + serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] + serialized_edge["source_identifier_id"] = None - serialized_editiable_future_graph["root"]["graph_id"] = str(self.pk) - serialized_editiable_future_graph["root"]["nodeid"] = ( - serialized_editiable_future_graph["root"]["source_identifier_id"] + source_domain_node_id = node_id_to_node_source_identifier_id.get( + serialized_edge["domainnode_id"] ) - serialized_editiable_future_graph["root"]["source_identifier_id"] = None + if source_domain_node_id: + serialized_edge["domainnode_id"] = source_domain_node_id - serialized_editiable_future_graph["has_unpublished_changes"] = False - serialized_editiable_future_graph["resource_instance_lifecycle_id"] = str( - self.resource_instance_lifecycle_id + source_range_node_id = node_id_to_node_source_identifier_id.get( + serialized_edge["rangenode_id"] ) - serialized_editiable_future_graph["source_identifier_id"] = None - serialized_editiable_future_graph["graphid"] = str(self.pk) + if source_range_node_id: + serialized_edge["rangenode_id"] = source_range_node_id - editable_future_graph.delete() + serialized_edge["graph_id"] = str(self.pk) - return self.restore_state_from_serialized_graph( - serialized_editiable_future_graph - ) + serialized_editiable_future_graph["root"]["graph_id"] = str(self.pk) + serialized_editiable_future_graph["root"]["nodeid"] = ( + serialized_editiable_future_graph["root"]["source_identifier_id"] + ) + serialized_editiable_future_graph["root"]["source_identifier_id"] = None + + serialized_editiable_future_graph["has_unpublished_changes"] = False + serialized_editiable_future_graph["resource_instance_lifecycle_id"] = str( + self.resource_instance_lifecycle_id + ) + serialized_editiable_future_graph["source_identifier_id"] = None + serialized_editiable_future_graph["graphid"] = str(self.pk) + + return self.restore_state_from_serialized_graph( + serialized_editiable_future_graph + ) def revert(self): """ @@ -2562,31 +2552,14 @@ def restore_state_from_serialized_graph(self, serialized_graph): new editable_future_graph """ with transaction.atomic(): - models.NodeGroup.objects.filter( - pk__in=[ - nodegroup.pk - for nodegroup in self.get_nodegroups(force_recalculation=True) - ] - ).delete() - models.Node.objects.filter( - pk__in=[node.pk for node in self.nodes.values()] - ).delete() - models.Edge.objects.filter( - pk__in=[edge.pk for edge in self.edges.values()] - ).delete() - models.CardModel.objects.filter( - pk__in=[card.pk for card in self.cards.values()] - ).delete() - models.CardXNodeXWidget.objects.filter( - pk__in=[ - card_x_node_x_widget.pk - for card_x_node_x_widget in self.widgets.values() - ] - ).delete() + editable_future_graph = Graph.objects.filter( + source_identifier_id=self.pk + ).first() + if editable_future_graph: + editable_future_graph.delete() # ensures any resources that were related to the source graph are not deleted self.pk = uuid.uuid4() - self.save() self.delete() for serialized_nodegroup in serialized_graph["nodegroups"]: diff --git a/arches/app/views/graph.py b/arches/app/views/graph.py index 8596e34c53..f15848575e 100644 --- a/arches/app/views/graph.py +++ b/arches/app/views/graph.py @@ -690,12 +690,13 @@ def post(self, request, graphid): try: data = JSONDeserializer().deserialize(request.body) - updated_graph = source_graph.update_from_editable_future_graph() + updated_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) updated_graph.publish(notes=data.get("notes"), user=request.user) return JSONResponse( { - "graph": editable_future_graph, "title": _("Success!"), "message": _( "The graph has been updated. Please click the OK button to reload the page." @@ -714,7 +715,6 @@ def post(self, request, graphid): source_graph.revert() return JSONResponse( { - "graph": editable_future_graph, "title": _("Success!"), "message": _( "The graph has been reverted. Please click the OK button to reload the page." @@ -739,7 +739,6 @@ def post(self, request, graphid): return JSONResponse( { - "graph": source_graph, "title": _("Success!"), "message": _( "The published graphs have been successfully updated." @@ -761,7 +760,6 @@ def post(self, request, graphid): return JSONResponse( { - "graph": source_graph, "title": _("Success!"), "message": _("The graph has been successfully restored."), } From 124560cc6ffa65a51d8957ed7d3af9e1f6c0df2f Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 09:46:08 -0800 Subject: [PATCH 08/23] removes editable_future_graph_utils #11570 --- .../app/utils/editable_future_graph_utils.py | 268 ------------------ 1 file changed, 268 deletions(-) delete mode 100644 arches/app/utils/editable_future_graph_utils.py diff --git a/arches/app/utils/editable_future_graph_utils.py b/arches/app/utils/editable_future_graph_utils.py deleted file mode 100644 index 30eafc6462..0000000000 --- a/arches/app/utils/editable_future_graph_utils.py +++ /dev/null @@ -1,268 +0,0 @@ -from arches.app.models import models - - -def update_nodegroups(current_graph, editable_future_graph, excluded_keys): - """ - Update the nodegroups in the source_graph to match those in the editable_future_graph. - """ - - def _update_source_nodegroup_hierarchy(nodegroup): - if not nodegroup: - return None - - node = models.Node.objects.filter(pk=nodegroup.pk).first() - source_nodegroup = None - - # updates source_nodegroup if node has a source_identifier_id - if node and node.source_identifier_id: - source_nodegroup = models.NodeGroup.objects.get( - pk=node.source_identifier_id - ) - for key, value in vars(nodegroup).items(): - if key not in excluded_keys: - setattr(source_nodegroup, key, value) - - # recursively update parent nodegroup relationships if parentnodegroup_id exists - if nodegroup.parentnodegroup_id: - parent_node = models.Node.objects.filter( - pk=nodegroup.parentnodegroup_id - ).first() - if parent_node and parent_node.source_identifier_id: - if source_nodegroup: - source_nodegroup.parentnodegroup_id = ( - parent_node.source_identifier_id - ) - source_nodegroup.save() - - nodegroup.parentnodegroup_id = parent_node.source_identifier_id - nodegroup.save() - - _update_source_nodegroup_hierarchy(nodegroup=nodegroup.parentnodegroup) - - editable_future_nodegroups = editable_future_graph.get_nodegroups( - force_recalculation=True - ) - - for editable_future_node in models.Node.objects.filter( - nodegroup__in=editable_future_nodegroups - ): - if ( - editable_future_node.source_identifier - and editable_future_node.pk == editable_future_node.nodegroup_id - and editable_future_node.source_identifier.pk - != editable_future_node.source_identifier.nodegroup_id - ): - models.NodeGroup.objects.create( - nodegroupid=editable_future_node.source_identifier.pk, - cardinality=editable_future_node.nodegroup.cardinality, - ) - - for editable_future_nodegroup in editable_future_nodegroups: - _update_source_nodegroup_hierarchy(editable_future_nodegroup) - - -def update_nodes(current_graph, editable_future_graph, excluded_keys): - previous_node_ids = {str(node.pk) for node in current_graph.nodes.values()} - current_graph.nodes = {} - - for future_node in list(editable_future_graph.nodes.values()): - future_node_nodegroup_node = ( - models.Node.objects.get(pk=future_node.nodegroup.pk) - if future_node.nodegroup - else None - ) - - if future_node.source_identifier: - source_node = future_node.source_identifier - - for key in vars(source_node).keys(): - if key not in excluded_keys: - setattr(source_node, key, getattr(future_node, key)) - - source_node.nodegroup_id = future_node.nodegroup_id - if ( - future_node_nodegroup_node - and future_node_nodegroup_node.source_identifier_id - ): - source_node.nodegroup_id = ( - future_node_nodegroup_node.source_identifier_id - ) - - current_graph.nodes[source_node.pk] = source_node - else: - future_node.graph_id = current_graph.pk - future_node.source_identifier_id = None - - if ( - future_node_nodegroup_node - and future_node_nodegroup_node.source_identifier_id - ): - future_node.nodegroup_id = ( - future_node_nodegroup_node.source_identifier_id - ) - - del editable_future_graph.nodes[future_node.pk] - current_graph.nodes[future_node.pk] = future_node - - updated_node_ids = { - str(node.source_identifier_id) for node in editable_future_graph.nodes.values() - } - updated_node_ids.add(str(current_graph.root.pk)) - - models.Node.objects.filter( - pk__in=set(previous_node_ids - updated_node_ids) - | {node.pk for node in editable_future_graph.nodes.values()} - ).delete() - - for node in current_graph.nodes.values(): - node.save() - - -def update_edges(current_graph, editable_future_graph, excluded_keys): - previous_edge_ids = {str(edge.pk) for edge in current_graph.edges.values()} - current_graph.edges = {} - - for future_edge in list(editable_future_graph.edges.values()): - if future_edge.source_identifier_id: - source_edge = future_edge.source_identifier - - for key in vars(source_edge).keys(): - if key not in excluded_keys: - setattr(source_edge, key, getattr(future_edge, key)) - - source_edge.domainnode_id = future_edge.domainnode_id - if future_edge.domainnode.source_identifier: - source_edge.domainnode_id = future_edge.domainnode.source_identifier.pk - - source_edge.rangenode_id = future_edge.rangenode_id - if future_edge.rangenode.source_identifier: - source_edge.rangenode_id = future_edge.rangenode.source_identifier.pk - - current_graph.edges[source_edge.pk] = source_edge - else: - future_edge.graph_id = current_graph.pk - future_edge.source_identifier_id = None - - if future_edge.domainnode.source_identifier_id: - future_edge.domainnode_id = future_edge.domainnode.source_identifier_id - - if future_edge.rangenode.source_identifier_id: - future_edge.rangenode_id = future_edge.rangenode.source_identifier_id - - del editable_future_graph.edges[future_edge.pk] - current_graph.edges[future_edge.pk] = future_edge - - updated_edge_ids = { - str(edge.source_identifier_id) for edge in editable_future_graph.edges.values() - } - - models.Edge.objects.filter( - pk__in=set(previous_edge_ids - updated_edge_ids) - | {edge.pk for edge in editable_future_graph.edges.values()} - ).delete() - - for edge in current_graph.edges.values(): - edge.save() - - -def update_cards(current_graph, editable_future_graph, excluded_keys): - previous_card_ids = {str(card.pk) for card in current_graph.cards.values()} - current_graph.cards = {} - - for future_card in list(editable_future_graph.cards.values()): - future_card_nodegroup_node = models.Node.objects.get( - pk=future_card.nodegroup.pk - ) - - if future_card.source_identifier: - source_card = future_card.source_identifier - - for key in vars(source_card).keys(): - if key not in excluded_keys: - setattr(source_card, key, getattr(future_card, key)) - - source_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id - if future_card_nodegroup_node.source_identifier_id: - source_card.nodegroup_id = ( - future_card_nodegroup_node.source_identifier_id - ) - - current_graph.cards[source_card.pk] = source_card - else: - future_card.graph_id = current_graph.pk - future_card.source_identifier_id = None - - future_card.nodegroup_id = future_card_nodegroup_node.nodegroup_id - if future_card_nodegroup_node.source_identifier_id: - future_card.nodegroup_id = ( - future_card_nodegroup_node.source_identifier_id - ) - - del editable_future_graph.cards[future_card.pk] - current_graph.cards[future_card.pk] = future_card - - updated_card_ids = { - str(card.source_identifier_id) for card in editable_future_graph.cards.values() - } - - models.CardModel.objects.filter( - pk__in=set(previous_card_ids - updated_card_ids) - | {card.pk for card in editable_future_graph.cards.values()} - ).delete() - - for card in current_graph.cards.values(): - card.save() - - -def update_widgets(current_graph, editable_future_graph, excluded_keys): - previous_widget_ids = {str(widget.pk) for widget in current_graph.widgets.values()} - current_graph.widgets = {} - - for future_widget in list(editable_future_graph.widgets.values()): - if future_widget.source_identifier_id: - source_widget = future_widget.source_identifier - - for key in vars(source_widget).keys(): - if key not in excluded_keys: - setattr(source_widget, key, getattr(future_widget, key)) - - if future_widget.card.source_identifier_id: - source_widget.card_id = future_widget.card.source_identifier_id - if future_widget.node.source_identifier_id: - source_widget.node_id = future_widget.node.source_identifier_id - - current_graph.widgets[source_widget.pk] = source_widget - else: - future_widget.source_identifier_id = None - - if future_widget.card.source_identifier_id: - future_widget.card_id = future_widget.card.source_identifier_id - if future_widget.node.source_identifier_id: - future_widget.node_id = future_widget.node.source_identifier_id - - del editable_future_graph.widgets[future_widget.pk] - current_graph.widgets[future_widget.pk] = future_widget - - updated_widget_ids = { - str(widget.source_identifier_id) - for widget in editable_future_graph.widgets.values() - } - - models.CardXNodeXWidget.objects.filter( - pk__in=set(previous_widget_ids - updated_widget_ids) - | {widget.pk for widget in editable_future_graph.widgets.values()} - ).delete() - - for widget in current_graph.widgets.values(): - widget.save() - - -def update_source_graph(current_graph, editable_future_graph, excluded_keys): - for key, value in vars(editable_future_graph).items(): - if key not in excluded_keys: - setattr(current_graph, key, value) - - current_graph.root = current_graph.nodes[current_graph.root.pk] - current_graph.root.set_relatable_resources( - [node.pk for node in editable_future_graph.root.get_relatable_resources()] - ) From 4964911d01311d7edc0a3c8b34434b3361274a9e Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Tue, 12 Nov 2024 09:47:07 -0800 Subject: [PATCH 09/23] nit #11570 --- arches/app/models/graph.py | 1 - 1 file changed, 1 deletion(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index f588cf46ed..6ad50791cd 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -30,7 +30,6 @@ from arches.app.datatypes.datatypes import DataTypeFactory from arches.app.etl_modules.bulk_data_deletion import BulkDataDeletion from arches.app.utils.betterJSONSerializer import JSONSerializer, JSONDeserializer -from arches.app.utils import editable_future_graph_utils from arches.app.search.search_engine_factory import SearchEngineFactory from arches.app.utils.i18n import LanguageSynchronizer from django.utils.translation import gettext as _ From db6051e19213d4ccee5f717945ca60c4a85f80f1 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 16:10:09 -0800 Subject: [PATCH 10/23] updates editable_future_graph tests #11570 --- tests/models/graph_tests.py | 1102 ++++++++++++++++++++++++++++------- 1 file changed, 891 insertions(+), 211 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index d2ff30cb5c..a78e861f7e 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -19,6 +19,7 @@ import uuid from django.contrib.auth.models import User +from guardian.models import GroupObjectPermission, UserObjectPermission from tests.base_test import ArchesTestCase from arches.app.models import models from arches.app.models.graph import Graph, GraphValidationError @@ -1208,217 +1209,6 @@ def test_appending_a_branch_with_an_invalid_ontology_class(self): with self.assertRaises(GraphValidationError) as cm: graph.save() - def test_update_empty_graph_from_editable_future_graph(self): - source_graph = Graph.new(name="TEST RESOURCE") - editable_future_graph = ( - source_graph.create_editable_future_graph() - ) # TODO: replace with db lookup after 9114 signal work - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/E1_Entity", graphid=source_graph.pk - ) - editable_future_graph.save() - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - - updated_source_graph = source_graph.update_from_editable_future_graph() - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - for idx, editable_future_graph_serialized_card in enumerate( - serialized_editable_future_graph["cards"] - ): - updated_source_graph_serialized_card = serialized_updated_source_graph[ - "cards" - ][idx] - - # ensures all relevant values are equal between graphs - for key, value in editable_future_graph_serialized_card.items(): - if key not in [ - "graph_id", - "nodegroup_id", - "name", - "cardid", - "source_identifier_id", - ]: - if type(value) == "dict": - self.assertDictEqual( - value, updated_source_graph_serialized_card[key] - ) - else: - updated_value = updated_source_graph_serialized_card[key] - if ( - updated_value == '{"en": ""}' - ): # workaround for updated str default values - updated_value = "" - - self.assertEqual(value, updated_value) - - # ensures all superflous values relating to `editable_future_graph` have been deleted - try: - future_card_from_database = models.CardModel.objects.get( - pk=editable_future_graph_serialized_card["cardid"] - ) - self.assertEqual( - str(future_card_from_database.graph_id), - updated_source_graph_serialized_card["graph_id"], - ) - except models.CardModel.DoesNotExist: - pass # card has been successfully deleted - - for idx, editable_future_graph_serialized_node in enumerate( - serialized_editable_future_graph["nodes"] - ): - updated_source_graph_serialized_node = serialized_updated_source_graph[ - "nodes" - ][idx] - - # ensures all relevant values are equal between graphs - for key, value in editable_future_graph_serialized_node.items(): - if key not in [ - "graph_id", - "nodegroup_id", - "nodeid", - "source_identifier_id", - ]: - if type(value) == "dict": - self.assertDictEqual( - value, updated_source_graph_serialized_node[key] - ) - else: - updated_value = updated_source_graph_serialized_node[key] - if ( - updated_value == '{"en": ""}' - ): # workaround for updated str default values - updated_value = "" - - self.assertEqual(value, updated_value) - - # ensures all superflous values relating to `editable_future_graph` have been deleted - try: - future_node_from_database = models.Node.objects.get( - pk=editable_future_graph_serialized_node["nodeid"] - ) - self.assertEqual( - str(future_node_from_database.graph_id), - updated_source_graph_serialized_node["graph_id"], - ) - except models.Node.DoesNotExist: - pass # node has been successfully deleted - - for idx, editable_future_graph_serialized_edge in enumerate( - serialized_editable_future_graph["edges"] - ): - updated_source_graph_serialized_edge = serialized_updated_source_graph[ - "edges" - ][idx] - - # ensures all relevant values are equal between graphs - for key, value in editable_future_graph_serialized_edge.items(): - if key not in [ - "graph_id", - "domainnode_id", - "rangenode_id", - "edgeid", - "source_identifier_id", - ]: - if type(value) == "dict": - self.assertDictEqual( - value, updated_source_graph_serialized_edge[key] - ) - else: - self.assertEqual( - value, updated_source_graph_serialized_edge[key] - ) - - # ensures all superflous values relating to `editable_future_graph` have been deleted - try: - future_edge_from_database = models.Edge.objects.get( - pk=editable_future_graph_serialized_edge["edgeid"] - ) - self.assertEqual( - str(future_edge_from_database.graph_id), - updated_source_graph_serialized_edge["graph_id"], - ) - except models.Edge.DoesNotExist: - pass # edge has been successfully deleted - - for idx, editable_future_graph_serialized_nodegroup in enumerate( - serialized_editable_future_graph["nodegroups"] - ): - updated_source_graph_serialized_nodegroup = serialized_updated_source_graph[ - "nodegroups" - ][idx] - - # ensures all relevant values are equal between graphs - for key, value in editable_future_graph_serialized_nodegroup.items(): - if key not in ["parentnodegroup_id", "nodegroupid", "legacygroupid"]: - if type(value) == "dict": - self.assertDictEqual( - value, updated_source_graph_serialized_nodegroup[key] - ) - else: - self.assertEqual( - value, updated_source_graph_serialized_nodegroup[key] - ) - - for key, value in serialized_editable_future_graph.items(): - if key == "name": - self.assertEqual(value, serialized_updated_source_graph[key]) - elif key not in [ - "graphid", - "cards", - "nodes", - "edges", - "nodegroups", - "functions", - "root", - "widgets", - "resource_instance_lifecycle", - "resource_instance_lifecycle_id", - "source_identifier", - "source_identifier_id", - "publication_id", - ]: - if type(value) == "dict": - self.assertDictEqual(value, serialized_updated_source_graph[key]) - else: - self.assertEqual(value, serialized_updated_source_graph[key]) - - def test_update_graph_from_editable_future_graph_after_node_deletion(self): - source_graph = Graph.new(name="TEST RESOURCE") - - source_graph.append_branch( - "http://www.ics.forth.gr/isl/CRMdig/L54_is_same-as", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - source_graph.save() - - self.assertEqual(len(source_graph.nodes), 3) - - editable_future_graph = ( - source_graph.create_editable_future_graph() - ) # TODO: replace with db lookup after 9114 signal work - - child_node = [node for node in editable_future_graph.nodes.values()][ - len(editable_future_graph.nodes.values()) - 1 - ] - child_node_source_identifier = child_node.source_identifier_id - - editable_future_graph.delete_node(child_node) - editable_future_graph = Graph.objects.get( - pk=editable_future_graph.pk - ) # updates from DB to refresh node list - - updated_source_graph = source_graph.update_from_editable_future_graph() - - with self.assertRaises(Exception): - models.Node.objects.get(pk=child_node_source_identifier) - - self.assertEqual(len(updated_source_graph.nodes), 2) - def test_add_resource_instance_lifecycle(self): resource_instance_lifecycle = { "id": "f7a0fd46-4c71-49cb-ae1e-778c96763440", @@ -1481,3 +1271,893 @@ def test_add_resource_instance_lifecycle(self): # Verify the lifecycle contains the states self.assertIn(state1, resource_instance_lifecycle_states) self.assertIn(state2, resource_instance_lifecycle_states) + + +class EditableFutureGraphTests(ArchesTestCase): + @classmethod + def setUpTestData(cls): + super().setUpTestData() + cls.NODE_NODETYPE_GRAPHID = "22000000-0000-0000-0000-000000000001" + cls.SINGLE_NODE_GRAPHID = "22000000-0000-0000-0000-000000000000" + + # Node Branch + graph_dict = { + "author": "Arches", + "color": None, + "deploymentdate": None, + "deploymentfile": None, + "description": "Represents a single node in a graph", + "graphid": cls.SINGLE_NODE_GRAPHID, + "iconclass": "fa fa-circle", + "isresource": False, + "name": "Node", + "ontology_id": "e6e8db47-2ccf-11e6-927e-b8f6b115d7dd", + "subtitle": "Represents a single node in a graph.", + "version": "v1", + } + models.GraphModel.objects.create(**graph_dict).save() + + node_dict = { + "config": None, + "datatype": "semantic", + "description": "Represents a single node in a graph", + "graph_id": cls.SINGLE_NODE_GRAPHID, + "isrequired": False, + "issearchable": True, + "istopnode": True, + "name": "Node", + "nodegroup_id": None, + "nodeid": "20000000-0000-0000-0000-100000000000", + "ontologyclass": "http://www.cidoc-crm.org/cidoc-crm/E1_CRM_Entity", + } + models.Node.objects.create(**node_dict).save() + + # Node/Node Type Branch + graph_dict = { + "author": "Arches", + "color": None, + "deploymentdate": None, + "deploymentfile": None, + "description": "Represents a node and node type pairing", + "graphid": cls.NODE_NODETYPE_GRAPHID, + "iconclass": "fa fa-angle-double-down", + "isresource": False, + "name": "Node/Node Type", + "ontology_id": "e6e8db47-2ccf-11e6-927e-b8f6b115d7dd", + "subtitle": "Represents a node and node type pairing", + "version": "v1", + } + models.GraphModel.objects.create(**graph_dict).save() + + nodegroup_dict = { + "cardinality": "n", + "legacygroupid": "", + "nodegroupid": "20000000-0000-0000-0000-100000000001", + "parentnodegroup_id": None, + } + models.NodeGroup.objects.create(**nodegroup_dict).save() + + card_dict = { + "active": True, + "cardid": "bf9ea150-3eaa-11e8-8b2b-c3a348661f61", + "description": "Represents a node and node type pairing", + "graph_id": cls.NODE_NODETYPE_GRAPHID, + "helpenabled": False, + "helptext": None, + "helptitle": None, + "instructions": "", + "name": "Node/Node Type", + "nodegroup_id": "20000000-0000-0000-0000-100000000001", + "sortorder": None, + "visible": True, + } + models.CardModel.objects.create(**card_dict).save() + + nodes = [ + { + "config": None, + "datatype": "string", + "description": "", + "graph_id": cls.NODE_NODETYPE_GRAPHID, + "isrequired": False, + "issearchable": True, + "istopnode": True, + "name": "Node", + "nodegroup_id": "20000000-0000-0000-0000-100000000001", + "nodeid": "20000000-0000-0000-0000-100000000001", + "ontologyclass": "http://www.cidoc-crm.org/cidoc-crm/E1_CRM_Entity", + }, + { + "config": {"rdmCollection": None}, + "datatype": "concept", + "description": "", + "graph_id": cls.NODE_NODETYPE_GRAPHID, + "isrequired": False, + "issearchable": True, + "istopnode": False, + "name": "Node Type", + "nodegroup_id": "20000000-0000-0000-0000-100000000001", + "nodeid": "20000000-0000-0000-0000-100000000002", + "ontologyclass": "http://www.cidoc-crm.org/cidoc-crm/E55_Type", + }, + ] + + for node in nodes: + models.Node.objects.create(**node).save() + + edges_dict = { + "description": None, + "domainnode_id": "20000000-0000-0000-0000-100000000001", + "edgeid": "22200000-0000-0000-0000-000000000001", + "graph_id": cls.NODE_NODETYPE_GRAPHID, + "name": None, + "ontologyproperty": "http://www.cidoc-crm.org/cidoc-crm/P2_has_type", + "rangenode_id": "20000000-0000-0000-0000-100000000002", + } + models.Edge.objects.create(**edges_dict).save() + + graph = Graph.new() + graph.name = "TEST GRAPH" + graph.subtitle = "ARCHES TEST GRAPH" + graph.author = "Arches" + graph.description = "ARCHES TEST GRAPH" + graph.ontology_id = "e6e8db47-2ccf-11e6-927e-b8f6b115d7dd" + graph.version = "v1.0.0" + graph.iconclass = "fa fa-building" + graph.nodegroups = [] + graph.root.ontologyclass = "http://www.cidoc-crm.org/cidoc-crm/E1_CRM_Entity" + graph.save() + + graph.root.name = "ROOT NODE" + graph.root.description = "Test Root Node" + graph.root.datatype = "semantic" + graph.root.save() + + cls.source_graph = graph + cls.editable_future_graph = graph.create_editable_future_graph() + + cls.rootNode = graph.root + + def _compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + self, serialized_updated_source_graph, serialized_editable_future_graph + ): + def are_dicts_equal(dict_1, dict_2, ignore_keys): + def filter_and_sort(entity): + """Recursively filter out ignored keys from a entity and sort by key.""" + if isinstance(entity, dict): + return { + key: filter_and_sort(value) + for key, value in entity.items() + if key not in ignore_keys + } + elif isinstance(entity, list): + return [filter_and_sort(item) for item in entity] + else: + return entity + + dict_1_filtered = filter_and_sort(dict_1) + dict_2_filtered = filter_and_sort(dict_2) + + return dict_1_filtered == dict_2_filtered + + serialized_updated_source_nodes = { + ( + node["source_identifier_id"] + if node.get("source_identifier_id") not in [None, "None"] + else node["nodeid"] + ): node + for node in serialized_updated_source_graph["nodes"] + } + + serialized_editable_future_nodes = { + ( + node["source_identifier_id"] + if node.get("source_identifier_id") not in [None, "None"] + else node["nodeid"] + ): node + for node in serialized_editable_future_graph["nodes"] + } + + self.assertTrue( + are_dicts_equal( + serialized_updated_source_nodes, + serialized_editable_future_nodes, + [ + "graph_id", + "nodeid", + "nodegroup_id", + "source_identifier_id", + ], + ) + ) + + serialized_updated_source_edges = { + ( + edge["source_identifier_id"] + if edge.get("source_identifier_id") not in [None, "None"] + else edge["edgeid"] + ): edge + for edge in serialized_updated_source_graph["edges"] + } + + serialized_editable_future_edges = { + ( + edge["source_identifier_id"] + if edge.get("source_identifier_id") not in [None, "None"] + else edge["edgeid"] + ): edge + for edge in serialized_editable_future_graph["edges"] + } + + self.assertTrue( + are_dicts_equal( + serialized_updated_source_edges, + serialized_editable_future_edges, + [ + "graph_id", + "edgeid", + "domainnode_id", + "rangenode_id", + "source_identifier_id", + ], + ) + ) + + serialized_updated_source_cards = { + ( + card["source_identifier_id"] + if card.get("source_identifier_id") not in [None, "None"] + else card["cardid"] + ): card + for card in serialized_updated_source_graph["cards"] + } + + serialized_editable_future_cards = { + ( + card["source_identifier_id"] + if card.get("source_identifier_id") not in [None, "None"] + else card["cardid"] + ): card + for card in serialized_editable_future_graph["cards"] + } + + self.assertTrue( + are_dicts_equal( + serialized_updated_source_cards, + serialized_editable_future_cards, + [ + "graph_id", + "cardid", + "nodegroup_id", + "source_identifier_id", + ], + ) + ) + + serialized_updated_source_cards_x_nodes_x_widgets = { + ( + card_x_node_x_widget["source_identifier_id"] + if card_x_node_x_widget.get("source_identifier_id") + not in [None, "None"] + else card_x_node_x_widget["id"] + ): card_x_node_x_widget + for card_x_node_x_widget in serialized_updated_source_graph[ + "cards_x_nodes_x_widgets" + ] + } + + serialized_editable_future_cards_x_nodes_x_widgets = { + ( + card_x_node_x_widget["source_identifier_id"] + if card_x_node_x_widget.get("source_identifier_id") + not in [None, "None"] + else card_x_node_x_widget["id"] + ): card_x_node_x_widget + for card_x_node_x_widget in serialized_editable_future_graph[ + "cards_x_nodes_x_widgets" + ] + } + + self.assertTrue( + are_dicts_equal( + serialized_updated_source_cards_x_nodes_x_widgets, + serialized_editable_future_cards_x_nodes_x_widgets, + [ + "graph_id", + "id", + "card_id", + "node_id", + "source_identifier_id", + ], + ) + ) + + self.assertTrue( + are_dicts_equal( + serialized_updated_source_graph, + serialized_editable_future_graph, + [ + "graphid", + "cards", + "nodes", + "edges", + "nodegroups", + "functions", + "root", + "widgets", + "cards_x_nodes_x_widgets", + "resource_instance_lifecycle", + "resource_instance_lifecycle_id", + "source_identifier", + "source_identifier_id", + "publication_id", + ], + ) + ) + + def test_update_empty_graph_from_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_multiple_nodes_and_edges(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.SINGLE_NODE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_updated_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_updated_editable_future_graph + ) + + def test_update_graph_with_permissions(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + + GroupObjectPermission.objects.create( + group_id=1, content_object=nodegroup, permission_id=93 + ) + UserObjectPermission.objects.create( + user_id=2, content_object=nodegroup, permission_id=94 + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_relatable_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.root.set_relatable_resources( + [editable_future_graph.root.pk] + ) + editable_future_graph.root.save() + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_create_editable_future_graphs_does_not_pollute_database(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + updated_source_graph.create_editable_future_graph() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( + self, + ): + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + updated_source_graph.delete() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_revert_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + source_graph.revert() + + editable_future_graph = models.Graph.objects.get( + source_identifier_id=source_graph.pk + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_nodegroup(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + nodegroup = editable_future_graph.get_nodegroups()[:1][0] + nodegroup.cardinality = "1" + nodegroup.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + self.assertEqual(nodegroup.cardinality, "1") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_node(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.root.name = "UPDATED_NODE_NAME" + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_card(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + card = [card for card in editable_future_graph.cards.values()][0] + card.description = "UPDATED_CARD_DESCRIPTION" + card.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_card = [card for card in updated_source_graph.cards.values()][0] + self.assertEqual( + updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_widget(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + card = [card for card in editable_future_graph.cards.values()][0] + card_x_node_x_widget = models.CardXNodeXWidget.objects.create( + card=card, + node_id=card.nodegroup_id, + widget=models.Widget.objects.first(), + label="Widget name", + ) + + editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget + + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + widget = [widget for widget in editable_future_graph.widgets.values()][0] + widget.label = "UPDATED_WIDGET_NAME" + widget.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_widget = [widget for widget in editable_future_graph.widgets.values()][ + 0 + ] + self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_from_editable_future_graph_does_not_affect_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup = models.NodeGroup.objects.create() + string_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="String Node", + datatype="string", + istopnode=False, + ) + resource_instance_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="Resource Node", + datatype="resource-instance", + istopnode=False, + ) + + resource = models.ResourceInstance.objects.create(graph=source_graph) + tile = models.TileModel.objects.create( + nodegroup_id=nodegroup.pk, + resourceinstance=resource, + data={ + str(string_node.pk): { + "en": {"value": "test value", "direction": "ltr"}, + }, + str(resource_instance_node.pk): { + "resourceId": str(resource.pk), + "ontologyProperty": "", + "inverseOntologyProperty": "", + }, + }, + sortorder=0, + ) + + serialized_resource = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource) + ) + serialized_tile = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile) + ) + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) + tile_from_database = models.TileModel.objects.get(pk=tile.pk) + + serialized_resource_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource_from_database) + ) + serialized_tile_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile_from_database) + ) + + self.assertEqual(serialized_resource, serialized_resource_from_database) + self.assertEqual(serialized_tile, serialized_tile_from_database) From c59b4b574c8ebcfd00ad7ac883445ee0ec9df5b1 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 16:14:07 -0800 Subject: [PATCH 11/23] update graph #11570 --- arches/app/models/graph.py | 84 ++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 6ad50791cd..b8db52965a 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -1707,9 +1707,15 @@ def update_permissions(self, serialized_graph): "user_permissions" ].values(): for serialized_user_permission in serialized_user_permission_list: + serialized_user_permission["content_object"] = ( + models.NodeGroup.objects.get( + pk=serialized_user_permission["object_pk"] + ) + ) updated_user_permission = UserObjectPermission( **serialized_user_permission ) + updated_user_permission.save() if "group_permissions" in serialized_graph: @@ -1727,9 +1733,15 @@ def update_permissions(self, serialized_graph): "group_permissions" ].values(): for serialized_group_permission in serialized_group_permission_list: + serialized_group_permission["content_object"] = ( + models.NodeGroup.objects.get( + pk=serialized_group_permission["object_pk"] + ) + ) updated_group_permission = GroupObjectPermission( **serialized_group_permission ) + updated_group_permission.save() def get_user_permissions(self, force_recalculation=False): @@ -2423,23 +2435,26 @@ def update_from_editable_future_graph(self, editable_future_graph): removes the editable future graph and related resources, then creates an editable future graph from the updated graph. """ - serialized_editiable_future_graph = JSONDeserializer().deserialize( + serialized_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(self) + ) + serialized_editable_future_graph = JSONDeserializer().deserialize( JSONSerializer().serialize(editable_future_graph) ) node_id_to_node_source_identifier_id = { node["nodeid"]: node["source_identifier_id"] - for node in serialized_editiable_future_graph["nodes"] + for node in serialized_editable_future_graph["nodes"] if node["source_identifier_id"] } card_id_to_card_source_identifier_id = { card["cardid"]: card["source_identifier_id"] - for card in serialized_editiable_future_graph["cards"] + for card in serialized_editable_future_graph["cards"] if card["source_identifier_id"] } - for serialized_card_x_node_x_widget in serialized_editiable_future_graph[ + for serialized_card_x_node_x_widget in serialized_editable_future_graph[ "cards_x_nodes_x_widgets" ]: if serialized_card_x_node_x_widget["source_identifier_id"]: @@ -2460,7 +2475,7 @@ def update_from_editable_future_graph(self, editable_future_graph): if updated_node_id: serialized_card_x_node_x_widget["node_id"] = updated_node_id - for serialized_card in serialized_editiable_future_graph["cards"]: + for serialized_card in serialized_editable_future_graph["cards"]: if serialized_card["source_identifier_id"]: serialized_card["cardid"] = serialized_card["source_identifier_id"] serialized_card["source_identifier_id"] = None @@ -2471,9 +2486,9 @@ def update_from_editable_future_graph(self, editable_future_graph): if source_nodegroup_id: serialized_card["nodegroup_id"] = source_nodegroup_id - serialized_card["graph_id"] = str(self.pk) + serialized_card["graph_id"] = serialized_source_graph["graphid"] - for serialized_node in serialized_editiable_future_graph["nodes"]: + for serialized_node in serialized_editable_future_graph["nodes"]: if serialized_node["source_identifier_id"]: serialized_node["nodeid"] = serialized_node["source_identifier_id"] serialized_node["source_identifier_id"] = None @@ -2484,9 +2499,9 @@ def update_from_editable_future_graph(self, editable_future_graph): if updated_nodegroup_id: serialized_node["nodegroup_id"] = updated_nodegroup_id - serialized_node["graph_id"] = str(self.pk) + serialized_node["graph_id"] = serialized_source_graph["graphid"] - for serialized_nodegroup in serialized_editiable_future_graph["nodegroups"]: + for serialized_nodegroup in serialized_editable_future_graph["nodegroups"]: updated_nodegroup_id = node_id_to_node_source_identifier_id.get( serialized_nodegroup["nodegroupid"] ) @@ -2499,7 +2514,7 @@ def update_from_editable_future_graph(self, editable_future_graph): if updated_nodegroup_id: serialized_nodegroup["parentnodegroup_id"] = updated_parent_nodegroup_id - for serialized_edge in serialized_editiable_future_graph["edges"]: + for serialized_edge in serialized_editable_future_graph["edges"]: if serialized_edge["source_identifier_id"]: serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] serialized_edge["source_identifier_id"] = None @@ -2516,23 +2531,48 @@ def update_from_editable_future_graph(self, editable_future_graph): if source_range_node_id: serialized_edge["rangenode_id"] = source_range_node_id - serialized_edge["graph_id"] = str(self.pk) + serialized_edge["graph_id"] = serialized_source_graph["graphid"] - serialized_editiable_future_graph["root"]["graph_id"] = str(self.pk) - serialized_editiable_future_graph["root"]["nodeid"] = ( - serialized_editiable_future_graph["root"]["source_identifier_id"] + serialized_editable_future_graph["root"]["graph_id"] = serialized_source_graph[ + "graphid" + ] + serialized_editable_future_graph["root"]["nodeid"] = ( + serialized_editable_future_graph["root"]["source_identifier_id"] ) - serialized_editiable_future_graph["root"]["source_identifier_id"] = None + serialized_editable_future_graph["root"]["source_identifier_id"] = None - serialized_editiable_future_graph["has_unpublished_changes"] = False - serialized_editiable_future_graph["resource_instance_lifecycle_id"] = str( - self.resource_instance_lifecycle_id + serialized_editable_future_graph["graphid"] = serialized_source_graph["graphid"] + serialized_editable_future_graph["has_unpublished_changes"] = False + serialized_editable_future_graph["resource_instance_lifecycle_id"] = ( + serialized_source_graph["resource_instance_lifecycle_id"] ) - serialized_editiable_future_graph["source_identifier_id"] = None - serialized_editiable_future_graph["graphid"] = str(self.pk) + serialized_editable_future_graph["source_identifier_id"] = None + + serialized_editable_future_graph["group_permissions"] = { + key: value + for key, value in serialized_source_graph["group_permissions"].items() + if key in node_id_to_node_source_identifier_id.values() + } + serialized_editable_future_graph["user_permissions"] = { + key: value + for key, value in serialized_source_graph["user_permissions"].items() + if key in node_id_to_node_source_identifier_id.values() + } + + serialized_editable_future_graph["relatable_resource_model_ids"] = [ + ( + serialized_source_graph["graphid"] + if relatable_resource_model_id + == serialized_editable_future_graph["graphid"] + else relatable_resource_model_id + ) + for relatable_resource_model_id in serialized_editable_future_graph[ + "relatable_resource_model_ids" + ] + ] return self.restore_state_from_serialized_graph( - serialized_editiable_future_graph + serialized_editable_future_graph ) def revert(self): @@ -2628,6 +2668,8 @@ def restore_state_from_serialized_graph(self, serialized_graph): updated_graph.widgets = widget_dict updated_graph.is_active = self.is_active + updated_graph.update_permissions(serialized_graph) + relatable_resource_model_nodes = models.Node.objects.filter( graph_id__in=serialized_graph["relatable_resource_model_ids"], istopnode=True, From ccc1ff6c9874d6cfa7b81dc450b7763ba4cf1099 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 16:18:54 -0800 Subject: [PATCH 12/23] adds migration #11570 --- .../11570_harden_editble_future_graphs.py | 38 ++++++++++ arches/app/models/models.py | 69 ++++++++++++++----- 2 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 arches/app/models/migrations/11570_harden_editble_future_graphs.py diff --git a/arches/app/models/migrations/11570_harden_editble_future_graphs.py b/arches/app/models/migrations/11570_harden_editble_future_graphs.py new file mode 100644 index 0000000000..2c1b8b7945 --- /dev/null +++ b/arches/app/models/migrations/11570_harden_editble_future_graphs.py @@ -0,0 +1,38 @@ +# Generated by Django 5.1.2 on 2024-11-13 18:17 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("models", "10437_node_alias_not_null"), + ] + + operations = [ + migrations.AlterField( + model_name="resource2resourceconstraint", + name="resourceclassfrom", + field=models.ForeignKey( + blank=True, + db_column="resourceclassfrom", + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="resxres_contstraint_classes_from", + to="models.node", + ), + ), + migrations.AlterField( + model_name="resource2resourceconstraint", + name="resourceclassto", + field=models.ForeignKey( + blank=True, + db_column="resourceclassto", + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="resxres_contstraint_classes_to", + to="models.node", + ), + ), + ] diff --git a/arches/app/models/models.py b/arches/app/models/models.py index 9421c5b833..916e805775 100644 --- a/arches/app/models/models.py +++ b/arches/app/models/models.py @@ -858,34 +858,67 @@ def get_relatable_resources(self): relatable_resource_ids = [ r2r.resourceclassfrom for r2r in Resource2ResourceConstraint.objects.filter( - resourceclassto_id=self.nodeid + resourceclassto_id=( + self.source_identifier_id + if self.source_identifier_id + else self.nodeid + ) ) if r2r.resourceclassfrom is not None ] relatable_resource_ids = relatable_resource_ids + [ r2r.resourceclassto for r2r in Resource2ResourceConstraint.objects.filter( - resourceclassfrom_id=self.nodeid + resourceclassfrom_id=( + self.source_identifier_id + if self.source_identifier_id + else self.nodeid + ) ) if r2r.resourceclassto is not None ] - return relatable_resource_ids + return list(set(relatable_resource_ids)) def set_relatable_resources(self, new_ids): - old_ids = [res.nodeid for res in self.get_relatable_resources()] - for old_id in old_ids: - if old_id not in new_ids: - Resource2ResourceConstraint.objects.filter( - Q(resourceclassto_id=self.nodeid) - | Q(resourceclassfrom_id=self.nodeid), - Q(resourceclassto_id=old_id) | Q(resourceclassfrom_id=old_id), - ).delete() - for new_id in new_ids: - if new_id not in old_ids: - new_r2r = Resource2ResourceConstraint.objects.create( - resourceclassfrom_id=self.nodeid, resourceclassto_id=new_id + new_ids = set(new_ids) + old_ids = set() + + for res in self.get_relatable_resources(): + if res.source_identifier_id: + old_ids.add(res.source_identifier_id) + if res.nodeid: + old_ids.add(res.nodeid) + + self_ids = set() + if self.source_identifier_id: + self_ids.add(self.source_identifier_id) + if self.nodeid: + self_ids.add(self.nodeid) + + old_ids.discard(None) + self_ids.discard(None) + + old_ids_to_delete = old_ids - new_ids + new_ids_to_create = new_ids - old_ids + + if old_ids_to_delete and self_ids: + Resource2ResourceConstraint.objects.filter( + ( + Q(resourceclassto_id__in=self_ids) + & Q(resourceclassfrom_id__in=old_ids_to_delete) + ) + | ( + Q(resourceclassto_id__in=old_ids_to_delete) + & Q(resourceclassfrom_id__in=self_ids) ) - new_r2r.save() + ).delete() + + for new_id in new_ids_to_create: + new_r2r = Resource2ResourceConstraint( + resourceclassfrom_id=self.source_identifier_id or self.nodeid, + resourceclassto_id=new_id, + ) + new_r2r.save() def serialize(self, fields=None, exclude=None, **kwargs): ret = JSONSerializer().handle_model( @@ -1110,7 +1143,7 @@ class Resource2ResourceConstraint(models.Model): blank=True, null=True, related_name="resxres_contstraint_classes_from", - on_delete=models.SET_NULL, + on_delete=models.CASCADE, ) resourceclassto = models.ForeignKey( Node, @@ -1118,7 +1151,7 @@ class Resource2ResourceConstraint(models.Model): blank=True, null=True, related_name="resxres_contstraint_classes_to", - on_delete=models.SET_NULL, + on_delete=models.CASCADE, ) def __init__(self, *args, **kwargs): From ee75d441686bc6c9dbf70dfbf90b87b7a0498040 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 19:39:34 -0800 Subject: [PATCH 13/23] nit #11570 --- tests/models/graph_tests.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index a78e861f7e..f3a9ba5107 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1698,9 +1698,7 @@ def test_update_graph_with_relatable_resources(self): source_graph.save() editable_future_graph = source_graph.create_editable_future_graph() - editable_future_graph.root.set_relatable_resources( - [editable_future_graph.root.pk] - ) + editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) editable_future_graph.root.save() editable_future_graph.save() From fd77699cdfec87170f251182c202440192713168 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 21:49:54 -0800 Subject: [PATCH 14/23] updates relateable resources logic #11570 --- .../app/media/js/viewmodels/graph-settings.js | 9 ++- arches/app/models/models.py | 68 ++++++++++--------- 2 files changed, 41 insertions(+), 36 deletions(-) diff --git a/arches/app/media/js/viewmodels/graph-settings.js b/arches/app/media/js/viewmodels/graph-settings.js index d681a234bd..1d79e661d7 100644 --- a/arches/app/media/js/viewmodels/graph-settings.js +++ b/arches/app/media/js/viewmodels/graph-settings.js @@ -15,9 +15,12 @@ define([ self.resource_data = ko.observableArray([]); self.relatable_resources = ko.computed(function() { - return _.each(self.resource_data(), function(resource) { - resource.isRelatable = ko.observable(resource.is_relatable); - }).filter(resource => !resource.graph.source_identifier_id); + return _.each( + self.resource_data().sort((a, b) => a.graph.name.localeCompare(b.graph.name)), + function(resource) { + resource.isRelatable = ko.observable(resource.is_relatable); + } + ).filter(resource => !resource.graph.source_identifier_id); }); self.designerViewModel = params.designerViewModel; diff --git a/arches/app/models/models.py b/arches/app/models/models.py index 01de50bdd3..bd5217d1bf 100644 --- a/arches/app/models/models.py +++ b/arches/app/models/models.py @@ -855,61 +855,63 @@ def is_collector(self): ) def get_relatable_resources(self): - primary_id = self.source_identifier_id or self.nodeid - - relatable_resources = Resource2ResourceConstraint.objects.filter( - Q(resourceclassto_id=primary_id) | Q(resourceclassfrom_id=primary_id) + query_id = ( + self.source_identifier_id if self.source_identifier_id else self.nodeid ) - unique_ids = set() - for r2r in relatable_resources: - if r2r.resourceclassfrom is not None: - unique_ids.add(r2r.resourceclassfrom) - if r2r.resourceclassto is not None: - unique_ids.add(r2r.resourceclassto) + constraints = Resource2ResourceConstraint.objects.filter( + Q(resourceclassto_id=query_id) | Q(resourceclassfrom_id=query_id) + ).select_related("resourceclassfrom", "resourceclassto") + + filtered_constraints = set() + for r2r in constraints: + if r2r.resourceclassto_id == query_id and r2r.resourceclassfrom is not None: + filtered_constraints.add(r2r.resourceclassfrom) + elif ( + r2r.resourceclassfrom_id == query_id and r2r.resourceclassto is not None + ): + filtered_constraints.add(r2r.resourceclassto) - return list(unique_ids) + return list(filtered_constraints) def set_relatable_resources(self, new_ids): new_ids = set(new_ids) - old_ids = set() + old_ids = set() for res in self.get_relatable_resources(): - if res.source_identifier_id: + if res.source_identifier_id is not None: old_ids.add(res.source_identifier_id) - if res.nodeid: + if res.nodeid is not None: old_ids.add(res.nodeid) - self_ids = set() - if self.source_identifier_id: - self_ids.add(self.source_identifier_id) - if self.nodeid: - self_ids.add(self.nodeid) - - old_ids.discard(None) - self_ids.discard(None) + self_ids = set( + id for id in (self.source_identifier_id, self.nodeid) if id is not None + ) - old_ids_to_delete = old_ids - new_ids - new_ids_to_create = new_ids - old_ids + ids_to_delete = old_ids - new_ids + ids_to_create = new_ids - old_ids - if old_ids_to_delete and self_ids: + if ids_to_delete and self_ids: Resource2ResourceConstraint.objects.filter( ( Q(resourceclassto_id__in=self_ids) - & Q(resourceclassfrom_id__in=old_ids_to_delete) + & Q(resourceclassfrom_id__in=ids_to_delete) ) | ( - Q(resourceclassto_id__in=old_ids_to_delete) + Q(resourceclassto_id__in=ids_to_delete) & Q(resourceclassfrom_id__in=self_ids) ) ).delete() - for new_id in new_ids_to_create: - new_r2r = Resource2ResourceConstraint( - resourceclassfrom_id=self.source_identifier_id or self.nodeid, - resourceclassto_id=new_id, - ) - new_r2r.save() + if ids_to_create: + new_constraints = [ + Resource2ResourceConstraint( + resourceclassfrom_id=self.source_identifier_id or self.nodeid, + resourceclassto_id=id_to_create, + ) + for id_to_create in ids_to_create + ] + Resource2ResourceConstraint.objects.bulk_create(new_constraints) def serialize(self, fields=None, exclude=None, **kwargs): ret = JSONSerializer().handle_model( From d57289bd660fe32d20b7c050c84c69f32c45a796 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 22:30:17 -0800 Subject: [PATCH 15/23] nit #11570 --- tests/models/graph_tests.py | 1114 +++++++++++++++++++---------------- 1 file changed, 592 insertions(+), 522 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index f3a9ba5107..8a2caed4cc 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1595,7 +1595,572 @@ def filter_and_sort(entity): ) ) - def test_update_empty_graph_from_editable_future_graph(self): + # def test_update_empty_graph_from_editable_future_graph(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_update_graph_with_multiple_nodes_and_edges(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.SINGLE_NODE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # serialized_updated_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_updated_editable_future_graph + # ) + + # def test_update_graph_with_permissions(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # nodegroup = updated_source_graph.get_nodegroups()[:1][0] + + # GroupObjectPermission.objects.create( + # group_id=1, content_object=nodegroup, permission_id=93 + # ) + # UserObjectPermission.objects.create( + # user_id=2, content_object=nodegroup, permission_id=94 + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_update_graph_with_relatable_resources(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) + # editable_future_graph.root.save() + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_create_editable_future_graphs_does_not_pollute_database(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # updated_source_graph.create_editable_future_graph() + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( + # self, + # ): + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # updated_source_graph.delete() + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_revert_editable_future_graph(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # source_graph.revert() + + # editable_future_graph = models.Graph.objects.get( + # source_identifier_id=source_graph.pk + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_nodegroup(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # nodegroup = editable_future_graph.get_nodegroups()[:1][0] + # nodegroup.cardinality = "1" + # nodegroup.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # nodegroup = updated_source_graph.get_nodegroups()[:1][0] + # self.assertEqual(nodegroup.cardinality, "1") + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_node(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # editable_future_graph.root.name = "UPDATED_NODE_NAME" + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_card(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # card = [card for card in editable_future_graph.cards.values()][0] + # card.description = "UPDATED_CARD_DESCRIPTION" + # card.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # updated_card = [card for card in updated_source_graph.cards.values()][0] + # self.assertEqual( + # updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' + # ) + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_widget(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # card = [card for card in editable_future_graph.cards.values()][0] + # card_x_node_x_widget = models.CardXNodeXWidget.objects.create( + # card=card, + # node_id=card.nodegroup_id, + # widget=models.Widget.objects.first(), + # label="Widget name", + # ) + + # editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget + + # editable_future_graph.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # widget = [widget for widget in editable_future_graph.widgets.values()][0] + # widget.label = "UPDATED_WIDGET_NAME" + # widget.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # updated_widget = [widget for widget in editable_future_graph.widgets.values()][ + # 0 + # ] + # self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_from_editable_future_graph_does_not_affect_resources(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # nodegroup = models.NodeGroup.objects.create() + # string_node = models.Node.objects.create( + # graph=source_graph, + # nodegroup=nodegroup, + # name="String Node", + # datatype="string", + # istopnode=False, + # ) + # resource_instance_node = models.Node.objects.create( + # graph=source_graph, + # nodegroup=nodegroup, + # name="Resource Node", + # datatype="resource-instance", + # istopnode=False, + # ) + + # resource = models.ResourceInstance.objects.create(graph=source_graph) + # tile = models.TileModel.objects.create( + # nodegroup_id=nodegroup.pk, + # resourceinstance=resource, + # data={ + # str(string_node.pk): { + # "en": {"value": "test value", "direction": "ltr"}, + # }, + # str(resource_instance_node.pk): { + # "resourceId": str(resource.pk), + # "ontologyProperty": "", + # "inverseOntologyProperty": "", + # }, + # }, + # sortorder=0, + # ) + + # serialized_resource = JSONDeserializer().deserialize( + # JSONSerializer().serialize(resource) + # ) + # serialized_tile = JSONDeserializer().deserialize( + # JSONSerializer().serialize(tile) + # ) + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) + # tile_from_database = models.TileModel.objects.get(pk=tile.pk) + + # serialized_resource_from_database = JSONDeserializer().deserialize( + # JSONSerializer().serialize(resource_from_database) + # ) + # serialized_tile_from_database = JSONDeserializer().deserialize( + # JSONSerializer().serialize(tile_from_database) + # ) + + # self.assertEqual(serialized_resource, serialized_resource_from_database) + # self.assertEqual(serialized_tile, serialized_tile_from_database) + + def test_foo(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") source_graph.save() editable_future_graph = source_graph.create_editable_future_graph() @@ -1606,461 +2171,45 @@ def test_update_empty_graph_from_editable_future_graph(self): ) editable_future_graph.save() - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_update_graph_with_multiple_nodes_and_edges(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.SINGLE_NODE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - serialized_updated_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_updated_editable_future_graph - ) - - def test_update_graph_with_permissions(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - nodegroup = updated_source_graph.get_nodegroups()[:1][0] - - GroupObjectPermission.objects.create( - group_id=1, content_object=nodegroup, permission_id=93 - ) - UserObjectPermission.objects.create( - user_id=2, content_object=nodegroup, permission_id=94 - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_update_graph_with_relatable_resources(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) - editable_future_graph.root.save() - editable_future_graph.save() - updated_source_graph = source_graph.update_from_editable_future_graph( editable_future_graph=editable_future_graph ) editable_future_graph = updated_source_graph.create_editable_future_graph() - self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_create_editable_future_graphs_does_not_pollute_database(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - updated_source_graph.create_editable_future_graph() - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( - self, - ): - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - updated_source_graph.delete() - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_revert_editable_future_graph(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - source_graph.revert() - - editable_future_graph = models.Graph.objects.get( - source_identifier_id=source_graph.pk - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_nodegroup(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - nodegroup = editable_future_graph.get_nodegroups()[:1][0] - nodegroup.cardinality = "1" - nodegroup.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - nodegroup = updated_source_graph.get_nodegroups()[:1][0] - self.assertEqual(nodegroup.cardinality, "1") - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_node(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - editable_future_graph.root.name = "UPDATED_NODE_NAME" - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_card(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - card = [card for card in editable_future_graph.cards.values()][0] - card.description = "UPDATED_CARD_DESCRIPTION" - card.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - updated_card = [card for card in updated_source_graph.cards.values()][0] - self.assertEqual( - updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' - ) - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_widget(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - card = [card for card in editable_future_graph.cards.values()][0] - card_x_node_x_widget = models.CardXNodeXWidget.objects.create( - card=card, - node_id=card.nodegroup_id, - widget=models.Widget.objects.first(), - label="Widget name", - ) + node = [node for node in editable_future_graph.nodes.values()][2] + source_identifier_id = node.source_identifier_id + original_nodegroup_id = node.nodegroup_id + updated_nodegroup_id = node.pk + + models.NodeGroup.objects.create( + **{ + "cardinality": "n", + "legacygroupid": "", + "nodegroupid": str(updated_nodegroup_id), + "parentnodegroup_id": None, + } + ).save() - editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget - - editable_future_graph.save() + node.nodegroup_id = updated_nodegroup_id + node.save() updated_source_graph = updated_source_graph.update_from_editable_future_graph( editable_future_graph=editable_future_graph ) editable_future_graph = updated_source_graph.create_editable_future_graph() - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + # a source_graph nodegroup and an editable_future_graph nodegroup have been created + self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count() - 2) - widget = [widget for widget in editable_future_graph.widgets.values()][0] - widget.label = "UPDATED_WIDGET_NAME" - widget.save() + node = [ + node + for node in editable_future_graph.nodes.values() + if node.source_identifier_id == source_identifier_id + ][0] + node.nodegroup_id = original_nodegroup_id + node.save() updated_source_graph = updated_source_graph.update_from_editable_future_graph( editable_future_graph=editable_future_graph @@ -2078,84 +2227,5 @@ def test_update_widget(self): serialized_updated_source_graph, serialized_editable_future_graph ) - updated_widget = [widget for widget in editable_future_graph.widgets.values()][ - 0 - ] - self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_from_editable_future_graph_does_not_affect_resources(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - nodegroup = models.NodeGroup.objects.create() - string_node = models.Node.objects.create( - graph=source_graph, - nodegroup=nodegroup, - name="String Node", - datatype="string", - istopnode=False, - ) - resource_instance_node = models.Node.objects.create( - graph=source_graph, - nodegroup=nodegroup, - name="Resource Node", - datatype="resource-instance", - istopnode=False, - ) - - resource = models.ResourceInstance.objects.create(graph=source_graph) - tile = models.TileModel.objects.create( - nodegroup_id=nodegroup.pk, - resourceinstance=resource, - data={ - str(string_node.pk): { - "en": {"value": "test value", "direction": "ltr"}, - }, - str(resource_instance_node.pk): { - "resourceId": str(resource.pk), - "ontologyProperty": "", - "inverseOntologyProperty": "", - }, - }, - sortorder=0, - ) - - serialized_resource = JSONDeserializer().deserialize( - JSONSerializer().serialize(resource) - ) - serialized_tile = JSONDeserializer().deserialize( - JSONSerializer().serialize(tile) - ) - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) - tile_from_database = models.TileModel.objects.get(pk=tile.pk) - - serialized_resource_from_database = JSONDeserializer().deserialize( - JSONSerializer().serialize(resource_from_database) - ) - serialized_tile_from_database = JSONDeserializer().deserialize( - JSONSerializer().serialize(tile_from_database) - ) - - self.assertEqual(serialized_resource, serialized_resource_from_database) - self.assertEqual(serialized_tile, serialized_tile_from_database) + # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted + self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) From d8029391d84e430ef8567a50bc65507130860dd0 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 22:30:38 -0800 Subject: [PATCH 16/23] nit #11570 --- tests/models/graph_tests.py | 1128 +++++++++++++++++------------------ 1 file changed, 564 insertions(+), 564 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index 8a2caed4cc..c22909121a 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1595,570 +1595,570 @@ def filter_and_sort(entity): ) ) - # def test_update_empty_graph_from_editable_future_graph(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_update_graph_with_multiple_nodes_and_edges(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.SINGLE_NODE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # serialized_updated_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_updated_editable_future_graph - # ) - - # def test_update_graph_with_permissions(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # nodegroup = updated_source_graph.get_nodegroups()[:1][0] - - # GroupObjectPermission.objects.create( - # group_id=1, content_object=nodegroup, permission_id=93 - # ) - # UserObjectPermission.objects.create( - # user_id=2, content_object=nodegroup, permission_id=94 - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_update_graph_with_relatable_resources(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) - # editable_future_graph.root.save() - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_create_editable_future_graphs_does_not_pollute_database(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # updated_source_graph.create_editable_future_graph() - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( - # self, - # ): - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # updated_source_graph.delete() - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_revert_editable_future_graph(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # source_graph.revert() - - # editable_future_graph = models.Graph.objects.get( - # source_identifier_id=source_graph.pk - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_nodegroup(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # nodegroup = editable_future_graph.get_nodegroups()[:1][0] - # nodegroup.cardinality = "1" - # nodegroup.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # nodegroup = updated_source_graph.get_nodegroups()[:1][0] - # self.assertEqual(nodegroup.cardinality, "1") - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_node(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # editable_future_graph.root.name = "UPDATED_NODE_NAME" - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_card(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # card = [card for card in editable_future_graph.cards.values()][0] - # card.description = "UPDATED_CARD_DESCRIPTION" - # card.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # updated_card = [card for card in updated_source_graph.cards.values()][0] - # self.assertEqual( - # updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' - # ) - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_widget(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # card = [card for card in editable_future_graph.cards.values()][0] - # card_x_node_x_widget = models.CardXNodeXWidget.objects.create( - # card=card, - # node_id=card.nodegroup_id, - # widget=models.Widget.objects.first(), - # label="Widget name", - # ) - - # editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget - - # editable_future_graph.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # widget = [widget for widget in editable_future_graph.widgets.values()][0] - # widget.label = "UPDATED_WIDGET_NAME" - # widget.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # updated_widget = [widget for widget in editable_future_graph.widgets.values()][ - # 0 - # ] - # self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_from_editable_future_graph_does_not_affect_resources(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # nodegroup = models.NodeGroup.objects.create() - # string_node = models.Node.objects.create( - # graph=source_graph, - # nodegroup=nodegroup, - # name="String Node", - # datatype="string", - # istopnode=False, - # ) - # resource_instance_node = models.Node.objects.create( - # graph=source_graph, - # nodegroup=nodegroup, - # name="Resource Node", - # datatype="resource-instance", - # istopnode=False, - # ) - - # resource = models.ResourceInstance.objects.create(graph=source_graph) - # tile = models.TileModel.objects.create( - # nodegroup_id=nodegroup.pk, - # resourceinstance=resource, - # data={ - # str(string_node.pk): { - # "en": {"value": "test value", "direction": "ltr"}, - # }, - # str(resource_instance_node.pk): { - # "resourceId": str(resource.pk), - # "ontologyProperty": "", - # "inverseOntologyProperty": "", - # }, - # }, - # sortorder=0, - # ) - - # serialized_resource = JSONDeserializer().deserialize( - # JSONSerializer().serialize(resource) - # ) - # serialized_tile = JSONDeserializer().deserialize( - # JSONSerializer().serialize(tile) - # ) - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) - # tile_from_database = models.TileModel.objects.get(pk=tile.pk) - - # serialized_resource_from_database = JSONDeserializer().deserialize( - # JSONSerializer().serialize(resource_from_database) - # ) - # serialized_tile_from_database = JSONDeserializer().deserialize( - # JSONSerializer().serialize(tile_from_database) - # ) - - # self.assertEqual(serialized_resource, serialized_resource_from_database) - # self.assertEqual(serialized_tile, serialized_tile_from_database) + def test_update_empty_graph_from_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_multiple_nodes_and_edges(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.SINGLE_NODE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_updated_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_updated_editable_future_graph + ) + + def test_update_graph_with_permissions(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + + GroupObjectPermission.objects.create( + group_id=1, content_object=nodegroup, permission_id=93 + ) + UserObjectPermission.objects.create( + user_id=2, content_object=nodegroup, permission_id=94 + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_relatable_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) + editable_future_graph.root.save() + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_create_editable_future_graphs_does_not_pollute_database(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + updated_source_graph.create_editable_future_graph() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( + self, + ): + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + updated_source_graph.delete() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_revert_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + source_graph.revert() + + editable_future_graph = models.Graph.objects.get( + source_identifier_id=source_graph.pk + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_nodegroup(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + nodegroup = editable_future_graph.get_nodegroups()[:1][0] + nodegroup.cardinality = "1" + nodegroup.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + self.assertEqual(nodegroup.cardinality, "1") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_node(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.root.name = "UPDATED_NODE_NAME" + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_card(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + card = [card for card in editable_future_graph.cards.values()][0] + card.description = "UPDATED_CARD_DESCRIPTION" + card.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_card = [card for card in updated_source_graph.cards.values()][0] + self.assertEqual( + updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_widget(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + card = [card for card in editable_future_graph.cards.values()][0] + card_x_node_x_widget = models.CardXNodeXWidget.objects.create( + card=card, + node_id=card.nodegroup_id, + widget=models.Widget.objects.first(), + label="Widget name", + ) + + editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget + + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + widget = [widget for widget in editable_future_graph.widgets.values()][0] + widget.label = "UPDATED_WIDGET_NAME" + widget.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_widget = [widget for widget in editable_future_graph.widgets.values()][ + 0 + ] + self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_from_editable_future_graph_does_not_affect_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup = models.NodeGroup.objects.create() + string_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="String Node", + datatype="string", + istopnode=False, + ) + resource_instance_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="Resource Node", + datatype="resource-instance", + istopnode=False, + ) + + resource = models.ResourceInstance.objects.create(graph=source_graph) + tile = models.TileModel.objects.create( + nodegroup_id=nodegroup.pk, + resourceinstance=resource, + data={ + str(string_node.pk): { + "en": {"value": "test value", "direction": "ltr"}, + }, + str(resource_instance_node.pk): { + "resourceId": str(resource.pk), + "ontologyProperty": "", + "inverseOntologyProperty": "", + }, + }, + sortorder=0, + ) + + serialized_resource = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource) + ) + serialized_tile = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile) + ) + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) + tile_from_database = models.TileModel.objects.get(pk=tile.pk) + + serialized_resource_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource_from_database) + ) + serialized_tile_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile_from_database) + ) + + self.assertEqual(serialized_resource, serialized_resource_from_database) + self.assertEqual(serialized_tile, serialized_tile_from_database) def test_foo(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") From 92a69deeadd930a7f9007e1cd4b509a9f3bf7b90 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 13 Nov 2024 22:48:13 -0800 Subject: [PATCH 17/23] nit #11570 --- arches/app/models/graph.py | 8 ++++++++ tests/models/graph_tests.py | 12 +++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 1ec92bf65d..4c43c1ec25 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -2449,6 +2449,7 @@ def update_from_editable_future_graph(self, editable_future_graph): if card["source_identifier_id"] } + # update cards_x_nodes_x_widgets for serialized_card_x_node_x_widget in serialized_editable_future_graph[ "cards_x_nodes_x_widgets" ]: @@ -2470,6 +2471,7 @@ def update_from_editable_future_graph(self, editable_future_graph): if updated_node_id: serialized_card_x_node_x_widget["node_id"] = updated_node_id + # update cards for serialized_card in serialized_editable_future_graph["cards"]: if serialized_card["source_identifier_id"]: serialized_card["cardid"] = serialized_card["source_identifier_id"] @@ -2483,6 +2485,7 @@ def update_from_editable_future_graph(self, editable_future_graph): serialized_card["graph_id"] = serialized_source_graph["graphid"] + # update nodes for serialized_node in serialized_editable_future_graph["nodes"]: if serialized_node["source_identifier_id"]: serialized_node["nodeid"] = serialized_node["source_identifier_id"] @@ -2496,6 +2499,7 @@ def update_from_editable_future_graph(self, editable_future_graph): serialized_node["graph_id"] = serialized_source_graph["graphid"] + # update nodegroups for serialized_nodegroup in serialized_editable_future_graph["nodegroups"]: updated_nodegroup_id = node_id_to_node_source_identifier_id.get( serialized_nodegroup["nodegroupid"] @@ -2509,6 +2513,7 @@ def update_from_editable_future_graph(self, editable_future_graph): if updated_nodegroup_id: serialized_nodegroup["parentnodegroup_id"] = updated_parent_nodegroup_id + # update edges for serialized_edge in serialized_editable_future_graph["edges"]: if serialized_edge["source_identifier_id"]: serialized_edge["edgeid"] = serialized_edge["source_identifier_id"] @@ -2528,6 +2533,7 @@ def update_from_editable_future_graph(self, editable_future_graph): serialized_edge["graph_id"] = serialized_source_graph["graphid"] + # update root node serialized_editable_future_graph["root"]["graph_id"] = serialized_source_graph[ "graphid" ] @@ -2536,6 +2542,7 @@ def update_from_editable_future_graph(self, editable_future_graph): ) serialized_editable_future_graph["root"]["source_identifier_id"] = None + # update graph data serialized_editable_future_graph["graphid"] = serialized_source_graph["graphid"] serialized_editable_future_graph["has_unpublished_changes"] = False serialized_editable_future_graph["resource_instance_lifecycle_id"] = ( @@ -2543,6 +2550,7 @@ def update_from_editable_future_graph(self, editable_future_graph): ) serialized_editable_future_graph["source_identifier_id"] = None + # update permissions serialized_editable_future_graph["group_permissions"] = { key: value for key, value in serialized_source_graph["group_permissions"].items() diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index c22909121a..ef7968caa9 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1765,6 +1765,9 @@ def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_mod edge_count_before = models.Edge.objects.count() card_count_before = models.CardModel.objects.count() card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + resource_2_resource_constraints_count_before = ( + models.Resource2ResourceConstraint.objects.count() + ) source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") source_graph.save() @@ -1786,6 +1789,9 @@ def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_mod edge_count_after = models.Edge.objects.count() card_count_after = models.CardModel.objects.count() card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + resource_2_resource_constraints_count_after = ( + models.Resource2ResourceConstraint.objects.count() + ) self.assertEqual(nodegroup_count_before, nodegroup_count_after) self.assertEqual(node_count_before, node_count_after) @@ -1794,6 +1800,10 @@ def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_mod self.assertEqual( card_x_node_x_widget_count_before, card_x_node_x_widget_count_after ) + self.assertEqual( + resource_2_resource_constraints_count_before, + resource_2_resource_constraints_count_after, + ) def test_revert_editable_future_graph(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") @@ -2160,7 +2170,7 @@ def test_update_from_editable_future_graph_does_not_affect_resources(self): self.assertEqual(serialized_resource, serialized_resource_from_database) self.assertEqual(serialized_tile, serialized_tile_from_database) - def test_foo(self): + def test_placing_node_in_separate_card_does_not_pollute_database(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") source_graph.save() editable_future_graph = source_graph.create_editable_future_graph() From 6f541536443eb0c8d69ce547c92092a6291214bc Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 14 Nov 2024 07:44:42 -0800 Subject: [PATCH 18/23] nit #11570 --- tests/models/graph_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index ef7968caa9..bcfab45cd0 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -2193,14 +2193,14 @@ def test_placing_node_in_separate_card_does_not_pollute_database(self): original_nodegroup_id = node.nodegroup_id updated_nodegroup_id = node.pk - models.NodeGroup.objects.create( + models.NodeGroup.objects.update_or_create( **{ "cardinality": "n", "legacygroupid": "", "nodegroupid": str(updated_nodegroup_id), "parentnodegroup_id": None, } - ).save() + ) node.nodegroup_id = updated_nodegroup_id node.save() From af893342a57585b37feff4ae36bffaa7e181548b Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 14 Nov 2024 08:03:02 -0800 Subject: [PATCH 19/23] nit #11570 --- tests/models/graph_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index bcfab45cd0..b8a4d8b84c 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -2194,12 +2194,12 @@ def test_placing_node_in_separate_card_does_not_pollute_database(self): updated_nodegroup_id = node.pk models.NodeGroup.objects.update_or_create( - **{ + nodegroupid=str(updated_nodegroup_id), + defaults={ "cardinality": "n", "legacygroupid": "", - "nodegroupid": str(updated_nodegroup_id), "parentnodegroup_id": None, - } + }, ) node.nodegroup_id = updated_nodegroup_id From 723485d3c9ace93d26e53988bf1890cadf2535a8 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 14 Nov 2024 08:43:35 -0800 Subject: [PATCH 20/23] nit #11570 --- tests/models/graph_tests.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index b8a4d8b84c..5991ad651f 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -2186,21 +2186,25 @@ def test_placing_node_in_separate_card_does_not_pollute_database(self): ) editable_future_graph = updated_source_graph.create_editable_future_graph() + node = [node for node in editable_future_graph.nodes.values()][2] + + # fixes flaky test + models.NodeGroup.objects.filter(pk=node.pk).delete() + nodegroup_count_before = models.NodeGroup.objects.count() - node = [node for node in editable_future_graph.nodes.values()][2] source_identifier_id = node.source_identifier_id original_nodegroup_id = node.nodegroup_id updated_nodegroup_id = node.pk - models.NodeGroup.objects.update_or_create( - nodegroupid=str(updated_nodegroup_id), - defaults={ + models.NodeGroup.objects.create( + **{ "cardinality": "n", "legacygroupid": "", + "nodegroupid": str(updated_nodegroup_id), "parentnodegroup_id": None, - }, - ) + } + ).save() node.nodegroup_id = updated_nodegroup_id node.save() From e2a7fc756d78327fb20297cf5cf8f10181029027 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Thu, 14 Nov 2024 19:06:34 -0800 Subject: [PATCH 21/23] nit #11570 --- tests/models/graph_tests.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index 5991ad651f..7b4f0a2af5 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -2243,3 +2243,29 @@ def test_placing_node_in_separate_card_does_not_pollute_database(self): # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) + + def test_can_update_graph_slug(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.slug = "test-resource" + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self.assertEqual(serialized_updated_source_graph["slug"], "test-resource") + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) From 23234ad25c08ef0da2266f8413d12b31925699a8 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 20 Nov 2024 13:54:52 -0800 Subject: [PATCH 22/23] nit #11570 --- arches/app/models/graph.py | 23 +- tests/models/graph_tests.py | 1261 ++++++++++++++++++----------------- 2 files changed, 668 insertions(+), 616 deletions(-) diff --git a/arches/app/models/graph.py b/arches/app/models/graph.py index 4c43c1ec25..ac1dfa780a 100644 --- a/arches/app/models/graph.py +++ b/arches/app/models/graph.py @@ -2313,22 +2313,17 @@ def validate_fieldname(fieldname, fieldnames): .exclude(source_identifier__isnull=False) .filter(slug=self.slug) ) - if ( - first_matching_graph := graphs_with_matching_slug.first() - ) and first_matching_graph.graphid != self.graphid: - if self.source_identifier_id: - if self.source_identifier_id != first_matching_graph.graphid: - raise GraphValidationError( - _( - "Another resource model already uses the slug '{self.slug}'" - ).format(**locals()), - 1007, - ) - else: + if (first_matching_graph := graphs_with_matching_slug.first()) and str( + first_matching_graph.graphid + ) != str(self.graphid): + if ( + not self.source_identifier_id + or self.source_identifier_id != first_matching_graph.graphid + ): raise GraphValidationError( _( - "Another resource model already uses the slug '{self.slug}'" - ).format(**locals()), + "Another resource model already uses the slug '{slug}'" + ).format(slug=self.slug), 1007, ) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index 7b4f0a2af5..646b48f3c9 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1595,111 +1595,662 @@ def filter_and_sort(entity): ) ) - def test_update_empty_graph_from_editable_future_graph(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_update_graph_with_multiple_nodes_and_edges(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.SINGLE_NODE_GRAPHID, - ) - editable_future_graph.save() + # def test_update_empty_graph_from_editable_future_graph(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_update_graph_with_multiple_nodes_and_edges(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.SINGLE_NODE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # serialized_updated_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_updated_editable_future_graph + # ) + + # def test_update_graph_with_permissions(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # nodegroup = updated_source_graph.get_nodegroups()[:1][0] + + # GroupObjectPermission.objects.create( + # group_id=1, content_object=nodegroup, permission_id=93 + # ) + # UserObjectPermission.objects.create( + # user_id=2, content_object=nodegroup, permission_id=94 + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_update_graph_with_relatable_resources(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) + # editable_future_graph.root.save() + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # def test_create_editable_future_graphs_does_not_pollute_database(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # updated_source_graph.create_editable_future_graph() + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( + # self, + # ): + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + # resource_2_resource_constraints_count_before = ( + # models.Resource2ResourceConstraint.objects.count() + # ) + + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + + # updated_source_graph.delete() + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + # resource_2_resource_constraints_count_after = ( + # models.Resource2ResourceConstraint.objects.count() + # ) + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + # self.assertEqual( + # resource_2_resource_constraints_count_before, + # resource_2_resource_constraints_count_after, + # ) + + # def test_revert_editable_future_graph(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # source_graph.revert() + + # editable_future_graph = models.Graph.objects.get( + # source_identifier_id=source_graph.pk + # ) + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_nodegroup(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # nodegroup = editable_future_graph.get_nodegroups()[:1][0] + # nodegroup.cardinality = "1" + # nodegroup.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # nodegroup = updated_source_graph.get_nodegroups()[:1][0] + # self.assertEqual(nodegroup.cardinality, "1") + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_node(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # editable_future_graph.root.name = "UPDATED_NODE_NAME" + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_card(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # card = [card for card in editable_future_graph.cards.values()][0] + # card.description = "UPDATED_CARD_DESCRIPTION" + # card.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # updated_card = [card for card in updated_source_graph.cards.values()][0] + # self.assertEqual( + # updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' + # ) + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_widget(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # card = [card for card in editable_future_graph.cards.values()][0] + # card_x_node_x_widget = models.CardXNodeXWidget.objects.create( + # card=card, + # node_id=card.nodegroup_id, + # widget=models.Widget.objects.first(), + # label="Widget name", + # ) + + # editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget + + # editable_future_graph.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # nodegroup_count_before = models.NodeGroup.objects.count() + # node_count_before = models.Node.objects.count() + # edge_count_before = models.Edge.objects.count() + # card_count_before = models.CardModel.objects.count() + # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + # widget = [widget for widget in editable_future_graph.widgets.values()][0] + # widget.label = "UPDATED_WIDGET_NAME" + # widget.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # updated_widget = [widget for widget in editable_future_graph.widgets.values()][ + # 0 + # ] + # self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') + + # nodegroup_count_after = models.NodeGroup.objects.count() + # node_count_after = models.Node.objects.count() + # edge_count_after = models.Edge.objects.count() + # card_count_after = models.CardModel.objects.count() + # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + # self.assertEqual(nodegroup_count_before, nodegroup_count_after) + # self.assertEqual(node_count_before, node_count_after) + # self.assertEqual(edge_count_before, edge_count_after) + # self.assertEqual(card_count_before, card_count_after) + # self.assertEqual( + # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + # ) + + # def test_update_from_editable_future_graph_does_not_affect_resources(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # nodegroup = models.NodeGroup.objects.create() + # string_node = models.Node.objects.create( + # graph=source_graph, + # nodegroup=nodegroup, + # name="String Node", + # datatype="string", + # istopnode=False, + # ) + # resource_instance_node = models.Node.objects.create( + # graph=source_graph, + # nodegroup=nodegroup, + # name="Resource Node", + # datatype="resource-instance", + # istopnode=False, + # ) + + # resource = models.ResourceInstance.objects.create(graph=source_graph) + # tile = models.TileModel.objects.create( + # nodegroup_id=nodegroup.pk, + # resourceinstance=resource, + # data={ + # str(string_node.pk): { + # "en": {"value": "test value", "direction": "ltr"}, + # }, + # str(resource_instance_node.pk): { + # "resourceId": str(resource.pk), + # "ontologyProperty": "", + # "inverseOntologyProperty": "", + # }, + # }, + # sortorder=0, + # ) + + # serialized_resource = JSONDeserializer().deserialize( + # JSONSerializer().serialize(resource) + # ) + # serialized_tile = JSONDeserializer().deserialize( + # JSONSerializer().serialize(tile) + # ) + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) + # tile_from_database = models.TileModel.objects.get(pk=tile.pk) + + # serialized_resource_from_database = JSONDeserializer().deserialize( + # JSONSerializer().serialize(resource_from_database) + # ) + # serialized_tile_from_database = JSONDeserializer().deserialize( + # JSONSerializer().serialize(tile_from_database) + # ) + + # self.assertEqual(serialized_resource, serialized_resource_from_database) + # self.assertEqual(serialized_tile, serialized_tile_from_database) + + # def test_placing_node_in_separate_card_does_not_pollute_database(self): + # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + # source_graph.save() + # editable_future_graph = source_graph.create_editable_future_graph() + + # editable_future_graph.append_branch( + # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + # graphid=self.NODE_NODETYPE_GRAPHID, + # ) + # editable_future_graph.save() + + # updated_source_graph = source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # node = [node for node in editable_future_graph.nodes.values()][2] + + # # fixes flaky test + # models.NodeGroup.objects.filter(pk=node.pk).delete() + + # nodegroup_count_before = models.NodeGroup.objects.count() + + # source_identifier_id = node.source_identifier_id + # original_nodegroup_id = node.nodegroup_id + # updated_nodegroup_id = node.pk + + # models.NodeGroup.objects.create( + # **{ + # "cardinality": "n", + # "legacygroupid": "", + # "nodegroupid": str(updated_nodegroup_id), + # "parentnodegroup_id": None, + # } + # ).save() + + # node.nodegroup_id = updated_nodegroup_id + # node.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # # a source_graph nodegroup and an editable_future_graph nodegroup have been created + # self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count() - 2) + + # node = [ + # node + # for node in editable_future_graph.nodes.values() + # if node.source_identifier_id == source_identifier_id + # ][0] + # node.nodegroup_id = original_nodegroup_id + # node.save() + + # updated_source_graph = updated_source_graph.update_from_editable_future_graph( + # editable_future_graph=editable_future_graph + # ) + # editable_future_graph = updated_source_graph.create_editable_future_graph() + + # serialized_editable_future_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(editable_future_graph) + # ) + # serialized_updated_source_graph = JSONDeserializer().deserialize( + # JSONSerializer().serialize(updated_source_graph) + # ) + + # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + # serialized_updated_source_graph, serialized_editable_future_graph + # ) + + # # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted + # self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - serialized_updated_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_updated_editable_future_graph - ) - - def test_update_graph_with_permissions(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - nodegroup = updated_source_graph.get_nodegroups()[:1][0] - - GroupObjectPermission.objects.create( - group_id=1, content_object=nodegroup, permission_id=93 - ) - UserObjectPermission.objects.create( - user_id=2, content_object=nodegroup, permission_id=94 - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_update_graph_with_relatable_resources(self): + def test_can_update_graph_slug(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") source_graph.save() editable_future_graph = source_graph.create_editable_future_graph() - editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) - editable_future_graph.root.save() + # test adding slug + editable_future_graph.slug = "test-resource" editable_future_graph.save() updated_source_graph = source_graph.update_from_editable_future_graph( @@ -1707,8 +2258,6 @@ def test_update_graph_with_relatable_resources(self): ) editable_future_graph = updated_source_graph.create_editable_future_graph() - self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) - serialized_editable_future_graph = JSONDeserializer().deserialize( JSONSerializer().serialize(editable_future_graph) ) @@ -1716,226 +2265,16 @@ def test_update_graph_with_relatable_resources(self): JSONSerializer().serialize(updated_source_graph) ) - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - def test_create_editable_future_graphs_does_not_pollute_database(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - updated_source_graph.create_editable_future_graph() - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( - self, - ): - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - resource_2_resource_constraints_count_before = ( - models.Resource2ResourceConstraint.objects.count() - ) - - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - - updated_source_graph.delete() - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - resource_2_resource_constraints_count_after = ( - models.Resource2ResourceConstraint.objects.count() - ) - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - self.assertEqual( - resource_2_resource_constraints_count_before, - resource_2_resource_constraints_count_after, - ) - - def test_revert_editable_future_graph(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - source_graph.revert() - - editable_future_graph = models.Graph.objects.get( - source_identifier_id=source_graph.pk - ) - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_nodegroup(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - nodegroup = editable_future_graph.get_nodegroups()[:1][0] - nodegroup.cardinality = "1" - nodegroup.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) + self.assertEqual(serialized_updated_source_graph["slug"], "test-resource") self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( serialized_updated_source_graph, serialized_editable_future_graph ) - nodegroup = updated_source_graph.get_nodegroups()[:1][0] - self.assertEqual(nodegroup.cardinality, "1") - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_node(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) + # test updating slug + editable_future_graph.slug = "test-resource-two" editable_future_graph.save() - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - editable_future_graph.root.name = "UPDATED_NODE_NAME" - updated_source_graph = updated_source_graph.update_from_editable_future_graph( editable_future_graph=editable_future_graph ) @@ -1948,96 +2287,18 @@ def test_update_node(self): JSONSerializer().serialize(updated_source_graph) ) - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_card(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - card = [card for card in editable_future_graph.cards.values()][0] - card.description = "UPDATED_CARD_DESCRIPTION" - card.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) + self.assertEqual(serialized_updated_source_graph["slug"], "test-resource-two") self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( serialized_updated_source_graph, serialized_editable_future_graph ) - updated_card = [card for card in updated_source_graph.cards.values()][0] - self.assertEqual( - updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' - ) - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_widget(self): + def test_can_update_other_data_in_graph_with_slug(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") source_graph.save() editable_future_graph = source_graph.create_editable_future_graph() - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) + editable_future_graph.slug = "test-resource" editable_future_graph.save() updated_source_graph = source_graph.update_from_editable_future_graph( @@ -2045,16 +2306,7 @@ def test_update_widget(self): ) editable_future_graph = updated_source_graph.create_editable_future_graph() - card = [card for card in editable_future_graph.cards.values()][0] - card_x_node_x_widget = models.CardXNodeXWidget.objects.create( - card=card, - node_id=card.nodegroup_id, - widget=models.Widget.objects.first(), - label="Widget name", - ) - - editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget - + editable_future_graph.name = "TEST RESOURCE TWO" editable_future_graph.save() updated_source_graph = updated_source_graph.update_from_editable_future_graph( @@ -2062,21 +2314,6 @@ def test_update_widget(self): ) editable_future_graph = updated_source_graph.create_editable_future_graph() - nodegroup_count_before = models.NodeGroup.objects.count() - node_count_before = models.Node.objects.count() - edge_count_before = models.Edge.objects.count() - card_count_before = models.CardModel.objects.count() - card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - widget = [widget for widget in editable_future_graph.widgets.values()][0] - widget.label = "UPDATED_WIDGET_NAME" - widget.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - serialized_editable_future_graph = JSONDeserializer().deserialize( JSONSerializer().serialize(editable_future_graph) ) @@ -2084,187 +2321,7 @@ def test_update_widget(self): JSONSerializer().serialize(updated_source_graph) ) - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - updated_widget = [widget for widget in editable_future_graph.widgets.values()][ - 0 - ] - self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') - - nodegroup_count_after = models.NodeGroup.objects.count() - node_count_after = models.Node.objects.count() - edge_count_after = models.Edge.objects.count() - card_count_after = models.CardModel.objects.count() - card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - self.assertEqual(nodegroup_count_before, nodegroup_count_after) - self.assertEqual(node_count_before, node_count_after) - self.assertEqual(edge_count_before, edge_count_after) - self.assertEqual(card_count_before, card_count_after) - self.assertEqual( - card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - ) - - def test_update_from_editable_future_graph_does_not_affect_resources(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - nodegroup = models.NodeGroup.objects.create() - string_node = models.Node.objects.create( - graph=source_graph, - nodegroup=nodegroup, - name="String Node", - datatype="string", - istopnode=False, - ) - resource_instance_node = models.Node.objects.create( - graph=source_graph, - nodegroup=nodegroup, - name="Resource Node", - datatype="resource-instance", - istopnode=False, - ) - - resource = models.ResourceInstance.objects.create(graph=source_graph) - tile = models.TileModel.objects.create( - nodegroup_id=nodegroup.pk, - resourceinstance=resource, - data={ - str(string_node.pk): { - "en": {"value": "test value", "direction": "ltr"}, - }, - str(resource_instance_node.pk): { - "resourceId": str(resource.pk), - "ontologyProperty": "", - "inverseOntologyProperty": "", - }, - }, - sortorder=0, - ) - - serialized_resource = JSONDeserializer().deserialize( - JSONSerializer().serialize(resource) - ) - serialized_tile = JSONDeserializer().deserialize( - JSONSerializer().serialize(tile) - ) - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) - tile_from_database = models.TileModel.objects.get(pk=tile.pk) - - serialized_resource_from_database = JSONDeserializer().deserialize( - JSONSerializer().serialize(resource_from_database) - ) - serialized_tile_from_database = JSONDeserializer().deserialize( - JSONSerializer().serialize(tile_from_database) - ) - - self.assertEqual(serialized_resource, serialized_resource_from_database) - self.assertEqual(serialized_tile, serialized_tile_from_database) - - def test_placing_node_in_separate_card_does_not_pollute_database(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.append_branch( - "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - graphid=self.NODE_NODETYPE_GRAPHID, - ) - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - node = [node for node in editable_future_graph.nodes.values()][2] - - # fixes flaky test - models.NodeGroup.objects.filter(pk=node.pk).delete() - - nodegroup_count_before = models.NodeGroup.objects.count() - - source_identifier_id = node.source_identifier_id - original_nodegroup_id = node.nodegroup_id - updated_nodegroup_id = node.pk - - models.NodeGroup.objects.create( - **{ - "cardinality": "n", - "legacygroupid": "", - "nodegroupid": str(updated_nodegroup_id), - "parentnodegroup_id": None, - } - ).save() - - node.nodegroup_id = updated_nodegroup_id - node.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - # a source_graph nodegroup and an editable_future_graph nodegroup have been created - self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count() - 2) - - node = [ - node - for node in editable_future_graph.nodes.values() - if node.source_identifier_id == source_identifier_id - ][0] - node.nodegroup_id = original_nodegroup_id - node.save() - - updated_source_graph = updated_source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - serialized_updated_source_graph, serialized_editable_future_graph - ) - - # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted - self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) - - def test_can_update_graph_slug(self): - source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - source_graph.save() - editable_future_graph = source_graph.create_editable_future_graph() - - editable_future_graph.slug = "test-resource" - editable_future_graph.save() - - updated_source_graph = source_graph.update_from_editable_future_graph( - editable_future_graph=editable_future_graph - ) - editable_future_graph = updated_source_graph.create_editable_future_graph() - - serialized_editable_future_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(editable_future_graph) - ) - serialized_updated_source_graph = JSONDeserializer().deserialize( - JSONSerializer().serialize(updated_source_graph) - ) - - self.assertEqual(serialized_updated_source_graph["slug"], "test-resource") + self.assertEqual(serialized_updated_source_graph["name"], "TEST RESOURCE TWO") self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( serialized_updated_source_graph, serialized_editable_future_graph From 453c2e6caba39dc4ea7ba312a38be42d8b0e5d56 Mon Sep 17 00:00:00 2001 From: Christopher Byrd Date: Wed, 20 Nov 2024 13:55:43 -0800 Subject: [PATCH 23/23] nit #11570 --- tests/models/graph_tests.py | 1296 +++++++++++++++++------------------ 1 file changed, 648 insertions(+), 648 deletions(-) diff --git a/tests/models/graph_tests.py b/tests/models/graph_tests.py index 646b48f3c9..a0f8cc35c5 100644 --- a/tests/models/graph_tests.py +++ b/tests/models/graph_tests.py @@ -1595,654 +1595,654 @@ def filter_and_sort(entity): ) ) - # def test_update_empty_graph_from_editable_future_graph(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_update_graph_with_multiple_nodes_and_edges(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.SINGLE_NODE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # serialized_updated_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_updated_editable_future_graph - # ) - - # def test_update_graph_with_permissions(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # nodegroup = updated_source_graph.get_nodegroups()[:1][0] - - # GroupObjectPermission.objects.create( - # group_id=1, content_object=nodegroup, permission_id=93 - # ) - # UserObjectPermission.objects.create( - # user_id=2, content_object=nodegroup, permission_id=94 - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_update_graph_with_relatable_resources(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) - # editable_future_graph.root.save() - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # def test_create_editable_future_graphs_does_not_pollute_database(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # updated_source_graph.create_editable_future_graph() - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( - # self, - # ): - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - # resource_2_resource_constraints_count_before = ( - # models.Resource2ResourceConstraint.objects.count() - # ) - - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - - # updated_source_graph.delete() - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - # resource_2_resource_constraints_count_after = ( - # models.Resource2ResourceConstraint.objects.count() - # ) - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - # self.assertEqual( - # resource_2_resource_constraints_count_before, - # resource_2_resource_constraints_count_after, - # ) - - # def test_revert_editable_future_graph(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # source_graph.revert() - - # editable_future_graph = models.Graph.objects.get( - # source_identifier_id=source_graph.pk - # ) - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_nodegroup(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # nodegroup = editable_future_graph.get_nodegroups()[:1][0] - # nodegroup.cardinality = "1" - # nodegroup.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # nodegroup = updated_source_graph.get_nodegroups()[:1][0] - # self.assertEqual(nodegroup.cardinality, "1") - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_node(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # editable_future_graph.root.name = "UPDATED_NODE_NAME" - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_card(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # card = [card for card in editable_future_graph.cards.values()][0] - # card.description = "UPDATED_CARD_DESCRIPTION" - # card.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # updated_card = [card for card in updated_source_graph.cards.values()][0] - # self.assertEqual( - # updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' - # ) - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_widget(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # card = [card for card in editable_future_graph.cards.values()][0] - # card_x_node_x_widget = models.CardXNodeXWidget.objects.create( - # card=card, - # node_id=card.nodegroup_id, - # widget=models.Widget.objects.first(), - # label="Widget name", - # ) - - # editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget - - # editable_future_graph.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # nodegroup_count_before = models.NodeGroup.objects.count() - # node_count_before = models.Node.objects.count() - # edge_count_before = models.Edge.objects.count() - # card_count_before = models.CardModel.objects.count() - # card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() - - # widget = [widget for widget in editable_future_graph.widgets.values()][0] - # widget.label = "UPDATED_WIDGET_NAME" - # widget.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # updated_widget = [widget for widget in editable_future_graph.widgets.values()][ - # 0 - # ] - # self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') - - # nodegroup_count_after = models.NodeGroup.objects.count() - # node_count_after = models.Node.objects.count() - # edge_count_after = models.Edge.objects.count() - # card_count_after = models.CardModel.objects.count() - # card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() - - # self.assertEqual(nodegroup_count_before, nodegroup_count_after) - # self.assertEqual(node_count_before, node_count_after) - # self.assertEqual(edge_count_before, edge_count_after) - # self.assertEqual(card_count_before, card_count_after) - # self.assertEqual( - # card_x_node_x_widget_count_before, card_x_node_x_widget_count_after - # ) - - # def test_update_from_editable_future_graph_does_not_affect_resources(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # nodegroup = models.NodeGroup.objects.create() - # string_node = models.Node.objects.create( - # graph=source_graph, - # nodegroup=nodegroup, - # name="String Node", - # datatype="string", - # istopnode=False, - # ) - # resource_instance_node = models.Node.objects.create( - # graph=source_graph, - # nodegroup=nodegroup, - # name="Resource Node", - # datatype="resource-instance", - # istopnode=False, - # ) - - # resource = models.ResourceInstance.objects.create(graph=source_graph) - # tile = models.TileModel.objects.create( - # nodegroup_id=nodegroup.pk, - # resourceinstance=resource, - # data={ - # str(string_node.pk): { - # "en": {"value": "test value", "direction": "ltr"}, - # }, - # str(resource_instance_node.pk): { - # "resourceId": str(resource.pk), - # "ontologyProperty": "", - # "inverseOntologyProperty": "", - # }, - # }, - # sortorder=0, - # ) - - # serialized_resource = JSONDeserializer().deserialize( - # JSONSerializer().serialize(resource) - # ) - # serialized_tile = JSONDeserializer().deserialize( - # JSONSerializer().serialize(tile) - # ) - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) - # tile_from_database = models.TileModel.objects.get(pk=tile.pk) - - # serialized_resource_from_database = JSONDeserializer().deserialize( - # JSONSerializer().serialize(resource_from_database) - # ) - # serialized_tile_from_database = JSONDeserializer().deserialize( - # JSONSerializer().serialize(tile_from_database) - # ) - - # self.assertEqual(serialized_resource, serialized_resource_from_database) - # self.assertEqual(serialized_tile, serialized_tile_from_database) - - # def test_placing_node_in_separate_card_does_not_pollute_database(self): - # source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") - # source_graph.save() - # editable_future_graph = source_graph.create_editable_future_graph() - - # editable_future_graph.append_branch( - # "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", - # graphid=self.NODE_NODETYPE_GRAPHID, - # ) - # editable_future_graph.save() - - # updated_source_graph = source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # node = [node for node in editable_future_graph.nodes.values()][2] - - # # fixes flaky test - # models.NodeGroup.objects.filter(pk=node.pk).delete() - - # nodegroup_count_before = models.NodeGroup.objects.count() - - # source_identifier_id = node.source_identifier_id - # original_nodegroup_id = node.nodegroup_id - # updated_nodegroup_id = node.pk - - # models.NodeGroup.objects.create( - # **{ - # "cardinality": "n", - # "legacygroupid": "", - # "nodegroupid": str(updated_nodegroup_id), - # "parentnodegroup_id": None, - # } - # ).save() - - # node.nodegroup_id = updated_nodegroup_id - # node.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # # a source_graph nodegroup and an editable_future_graph nodegroup have been created - # self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count() - 2) - - # node = [ - # node - # for node in editable_future_graph.nodes.values() - # if node.source_identifier_id == source_identifier_id - # ][0] - # node.nodegroup_id = original_nodegroup_id - # node.save() - - # updated_source_graph = updated_source_graph.update_from_editable_future_graph( - # editable_future_graph=editable_future_graph - # ) - # editable_future_graph = updated_source_graph.create_editable_future_graph() - - # serialized_editable_future_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(editable_future_graph) - # ) - # serialized_updated_source_graph = JSONDeserializer().deserialize( - # JSONSerializer().serialize(updated_source_graph) - # ) - - # self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( - # serialized_updated_source_graph, serialized_editable_future_graph - # ) - - # # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted - # self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) + def test_update_empty_graph_from_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_multiple_nodes_and_edges(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.SINGLE_NODE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + serialized_updated_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_updated_editable_future_graph + ) + + def test_update_graph_with_permissions(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + + GroupObjectPermission.objects.create( + group_id=1, content_object=nodegroup, permission_id=93 + ) + UserObjectPermission.objects.create( + user_id=2, content_object=nodegroup, permission_id=94 + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_update_graph_with_relatable_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.root.set_relatable_resources([source_graph.root.pk]) + editable_future_graph.root.save() + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + self.assertTrue(len(updated_source_graph.root.get_relatable_resources())) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + def test_create_editable_future_graphs_does_not_pollute_database(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + updated_source_graph.create_editable_future_graph() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_deleting_source_graph_deletes_editable_future_graph_and_all_related_models( + self, + ): + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + resource_2_resource_constraints_count_before = ( + models.Resource2ResourceConstraint.objects.count() + ) + + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + + updated_source_graph.delete() + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + resource_2_resource_constraints_count_after = ( + models.Resource2ResourceConstraint.objects.count() + ) + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + self.assertEqual( + resource_2_resource_constraints_count_before, + resource_2_resource_constraints_count_after, + ) + + def test_revert_editable_future_graph(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + source_graph.revert() + + editable_future_graph = models.Graph.objects.get( + source_identifier_id=source_graph.pk + ) + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_nodegroup(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + nodegroup = editable_future_graph.get_nodegroups()[:1][0] + nodegroup.cardinality = "1" + nodegroup.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + nodegroup = updated_source_graph.get_nodegroups()[:1][0] + self.assertEqual(nodegroup.cardinality, "1") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_node(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + editable_future_graph.root.name = "UPDATED_NODE_NAME" + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + self.assertEqual(updated_source_graph.root.name, "UPDATED_NODE_NAME") + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_card(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + card = [card for card in editable_future_graph.cards.values()][0] + card.description = "UPDATED_CARD_DESCRIPTION" + card.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_card = [card for card in updated_source_graph.cards.values()][0] + self.assertEqual( + updated_card.description.value, '{"en": "UPDATED_CARD_DESCRIPTION"}' + ) + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_widget(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + card = [card for card in editable_future_graph.cards.values()][0] + card_x_node_x_widget = models.CardXNodeXWidget.objects.create( + card=card, + node_id=card.nodegroup_id, + widget=models.Widget.objects.first(), + label="Widget name", + ) + + editable_future_graph.widgets[card_x_node_x_widget.pk] = card_x_node_x_widget + + editable_future_graph.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + nodegroup_count_before = models.NodeGroup.objects.count() + node_count_before = models.Node.objects.count() + edge_count_before = models.Edge.objects.count() + card_count_before = models.CardModel.objects.count() + card_x_node_x_widget_count_before = models.CardXNodeXWidget.objects.count() + + widget = [widget for widget in editable_future_graph.widgets.values()][0] + widget.label = "UPDATED_WIDGET_NAME" + widget.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + updated_widget = [widget for widget in editable_future_graph.widgets.values()][ + 0 + ] + self.assertEqual(updated_widget.label.value, '{"en": "UPDATED_WIDGET_NAME"}') + + nodegroup_count_after = models.NodeGroup.objects.count() + node_count_after = models.Node.objects.count() + edge_count_after = models.Edge.objects.count() + card_count_after = models.CardModel.objects.count() + card_x_node_x_widget_count_after = models.CardXNodeXWidget.objects.count() + + self.assertEqual(nodegroup_count_before, nodegroup_count_after) + self.assertEqual(node_count_before, node_count_after) + self.assertEqual(edge_count_before, edge_count_after) + self.assertEqual(card_count_before, card_count_after) + self.assertEqual( + card_x_node_x_widget_count_before, card_x_node_x_widget_count_after + ) + + def test_update_from_editable_future_graph_does_not_affect_resources(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + nodegroup = models.NodeGroup.objects.create() + string_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="String Node", + datatype="string", + istopnode=False, + ) + resource_instance_node = models.Node.objects.create( + graph=source_graph, + nodegroup=nodegroup, + name="Resource Node", + datatype="resource-instance", + istopnode=False, + ) + + resource = models.ResourceInstance.objects.create(graph=source_graph) + tile = models.TileModel.objects.create( + nodegroup_id=nodegroup.pk, + resourceinstance=resource, + data={ + str(string_node.pk): { + "en": {"value": "test value", "direction": "ltr"}, + }, + str(resource_instance_node.pk): { + "resourceId": str(resource.pk), + "ontologyProperty": "", + "inverseOntologyProperty": "", + }, + }, + sortorder=0, + ) + + serialized_resource = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource) + ) + serialized_tile = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile) + ) + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + resource_from_database = models.ResourceInstance.objects.get(pk=resource.pk) + tile_from_database = models.TileModel.objects.get(pk=tile.pk) + + serialized_resource_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(resource_from_database) + ) + serialized_tile_from_database = JSONDeserializer().deserialize( + JSONSerializer().serialize(tile_from_database) + ) + + self.assertEqual(serialized_resource, serialized_resource_from_database) + self.assertEqual(serialized_tile, serialized_tile_from_database) + + def test_placing_node_in_separate_card_does_not_pollute_database(self): + source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST") + source_graph.save() + editable_future_graph = source_graph.create_editable_future_graph() + + editable_future_graph.append_branch( + "http://www.cidoc-crm.org/cidoc-crm/P1_is_identified_by", + graphid=self.NODE_NODETYPE_GRAPHID, + ) + editable_future_graph.save() + + updated_source_graph = source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + node = [node for node in editable_future_graph.nodes.values()][2] + + # fixes flaky test + models.NodeGroup.objects.filter(pk=node.pk).delete() + + nodegroup_count_before = models.NodeGroup.objects.count() + + source_identifier_id = node.source_identifier_id + original_nodegroup_id = node.nodegroup_id + updated_nodegroup_id = node.pk + + models.NodeGroup.objects.create( + **{ + "cardinality": "n", + "legacygroupid": "", + "nodegroupid": str(updated_nodegroup_id), + "parentnodegroup_id": None, + } + ).save() + + node.nodegroup_id = updated_nodegroup_id + node.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + # a source_graph nodegroup and an editable_future_graph nodegroup have been created + self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count() - 2) + + node = [ + node + for node in editable_future_graph.nodes.values() + if node.source_identifier_id == source_identifier_id + ][0] + node.nodegroup_id = original_nodegroup_id + node.save() + + updated_source_graph = updated_source_graph.update_from_editable_future_graph( + editable_future_graph=editable_future_graph + ) + editable_future_graph = updated_source_graph.create_editable_future_graph() + + serialized_editable_future_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(editable_future_graph) + ) + serialized_updated_source_graph = JSONDeserializer().deserialize( + JSONSerializer().serialize(updated_source_graph) + ) + + self._compare_serialized_updated_source_graph_and_serialized_editable_future_graph( + serialized_updated_source_graph, serialized_editable_future_graph + ) + + # the source_graph nodegroup and the editable_future_graph nodegroup have been deleted + self.assertEqual(nodegroup_count_before, models.NodeGroup.objects.count()) def test_can_update_graph_slug(self): source_graph = Graph.new(name="TEST RESOURCE", is_resource=True, author="TEST")