def test_relation_types_definition_index_variable(self): book = BookFixture(Book, generate_m2m={'authors': (2, 2)}).create_one() get_nodeset_for_queryset(Store.objects.filter(pk=book.pk), sync=True) user = User.objects.filter( pk__in=book.authors.values('user')).latest('pk') perm = Permission.objects.get(content_type__app_label='auth', codename='change_user') access_rule = AccessRule.objects.create( ctype_source=utils.get_content_type(User), ctype_target=utils.get_content_type(User), relation_types=[{ 'AUTHOR': None }, { 'BOOK': None }, { '{0:AUTHORS}': None }, { 'USER': None }]) access_rule.permissions.add(perm) user.user_permissions.add(perm) objects = utils.get_objects_for_user(user, 'auth.change_user') self.assertEqual({user}, set(objects)) self.assertNotEqual(User.objects.count(), objects.count())
def test_user_has_perm_multiple_relation_types(self): # Set up a bookstore graph store = StoreFixture(Store).create_one() get_nodeset_for_queryset(Store.objects.filter(pk=store.pk), sync=True) permissions = Permission.objects.filter( codename__in=['add_store', 'change_store', 'delete_store']) user = get_user_model().objects.latest('pk') user.user_permissions.add(*list(permissions)) # Create an access rule which allows 'add_store' and 'change_store', # but not 'delete_store' access_rule = AccessRule.objects.create( ctype_source=ContentType.objects.get_for_model(user), ctype_target=ContentType.objects.get_for_model(Store), relation_types=[{ 'AUTHOR': None }, { 'BOOK': None }, { 'STORE': None }]) access_rule.permissions.add( *list(permissions.exclude(codename='delete_store'))) self.assertTrue(user.has_perm('testapp.add_store', store)) self.assertTrue(user.has_perm('testapp.change_store', store)) self.assertFalse(user.has_perm('testapp.delete_store', store))
def test_get_nodeset_for_queryset(self): queryset = Store.objects.filter( pk__in=map(lambda n: n.pk, StoreFixture(Store).create(count=2, commit=True))) nodeset = get_nodeset_for_queryset(queryset) self.assertIsInstance(nodeset, NodeSet) for node in nodeset: self.assertIsInstance(node, get_node_class_for_model(queryset.model))
def m2m_changed_handler(sender, instance, action, reverse, model, pk_set, **kwargs): """ Update relations for the node when m2m relationships are added or deleted. """ if settings.ENABLED: if action not in ('post_add', 'post_remove', 'post_clear'): return if action == 'post_add': get_nodeset_for_queryset(model.objects.filter(pk__in=pk_set), sync=True, max_depth=settings.MAX_CONNECTION_DEPTH) elif action == 'post_remove': get_nodeset_for_queryset(model.objects.filter(pk__in=pk_set), sync=True, max_depth=settings.MAX_CONNECTION_DEPTH) elif action == 'post_clear': get_node_for_object(instance, bind=False).sync( max_depth=settings.MAX_CONNECTION_DEPTH, update_existing=True)
def test_sync_related_branch(self): queryset = Store.objects.filter( pk__in=map(lambda n: n.pk, StoreFixture(Store).create(count=2, commit=True))) store_nodeset = get_nodeset_for_queryset(queryset, sync=True, max_depth=1) for store in store_nodeset: store_obj = store.get_object() if store_obj.bestseller: self.assertEqual(store.bestseller.get(), get_node_for_object(store_obj.bestseller)) self.assertEqual(len(store.books.all()), store_obj.books.count()) for book in store.books.all(): book_obj = book.get_object() self.assertTrue(store in book.store_set.all()) self.assertEqual(book.publisher.get(), get_node_for_object(book_obj.publisher)) self.assertEqual(len(book.store_set.all()), book_obj.store_set.count()) self.assertEqual(len(book.bestseller_stores.all()), book_obj.bestseller_stores.count()) self.assertEqual(len(book.authors.all()), book_obj.authors.count()) # We have currently some issues with recursive max_depth. See #7 # FIXME: workaround - Sync nodeset for related queryset. get_nodeset_for_queryset(book_obj.authors.all(), sync=True, max_depth=1) for author in book.authors.all(): author_obj = author.get_object() self.assertTrue(book in author.book_set.all()) user = author.user.get() self.assertEqual( user, get_node_for_object(author_obj.user).sync()) self.assertEqual(author, user.author.get())