Add share snapshot mutation, including unit tests
This commit is contained in:
parent
631bfb338a
commit
4bdcdd8774
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.22 on 2021-05-08 20:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('books', '0027_auto_20210429_1444'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='snapshot',
|
||||
name='shared',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
|
|
@ -71,6 +71,7 @@ class Snapshot(models.Model):
|
|||
)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
creator = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, null=True)
|
||||
shared = models.BooleanField(default=False)
|
||||
|
||||
objects = SnapshotManager()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from books.schema.mutations.chapter import UpdateChapterVisibility
|
||||
from books.schema.mutations.contentblock import MutateContentBlock, AddContentBlock, DeleteContentBlock
|
||||
from books.schema.mutations.module import UpdateSolutionVisibility, UpdateLastModule, SyncModuleVisibility
|
||||
from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot
|
||||
from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot, ShareSnapshot
|
||||
from books.schema.mutations.topic import UpdateLastTopic
|
||||
|
||||
|
||||
|
|
@ -16,3 +16,4 @@ class BookMutations(object):
|
|||
sync_module_visibility = SyncModuleVisibility.Field()
|
||||
create_snapshot = CreateSnapshot.Field()
|
||||
apply_snapshot = ApplySnapshot.Field()
|
||||
share_snapshot = ShareSnapshot.Field()
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class ApplySnapshot(relay.ClientIDMutation):
|
|||
user = info.context.user
|
||||
selected_class_id = args.get('selected_class')
|
||||
selected_class = get_object(SchoolClass, selected_class_id)
|
||||
#reset everything
|
||||
# reset everything
|
||||
for chapter in Chapter.get_by_parent(snapshot.module):
|
||||
cb_qs = ContentBlock.get_by_parent(chapter)
|
||||
without_owner = Q(owner__isnull=True)
|
||||
|
|
@ -55,7 +55,7 @@ class ApplySnapshot(relay.ClientIDMutation):
|
|||
cb.hidden_for.remove(selected_class)
|
||||
for cb in cb_qs.filter(owner_user):
|
||||
cb.visible_for.remove(selected_class)
|
||||
#apply snapshot
|
||||
# apply snapshot
|
||||
if not selected_class.users.filter(username=user.username).exists() or not user.is_teacher():
|
||||
raise PermissionError('Not allowed')
|
||||
for content_block in snapshot.hidden_content_blocks.all():
|
||||
|
|
@ -69,3 +69,24 @@ class ApplySnapshot(relay.ClientIDMutation):
|
|||
if chapter_snapshot.description_hidden:
|
||||
chapter.description_hidden_for.add(selected_class)
|
||||
return cls(success=True, module=snapshot.module)
|
||||
|
||||
|
||||
class ShareSnapshot(relay.ClientIDMutation):
|
||||
class Input:
|
||||
snapshot = graphene.ID(required=True)
|
||||
shared = graphene.Boolean(required=True)
|
||||
|
||||
success = graphene.Boolean(required=True)
|
||||
snapshot = graphene.Field(SnapshotNode)
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, root, info, **args):
|
||||
snapshot_id = args.get('snapshot')
|
||||
shared = args.get('shared')
|
||||
user = info.context.user
|
||||
snapshot = get_object(Snapshot, snapshot_id)
|
||||
if snapshot.creator != user:
|
||||
raise PermissionError('Not permitted')
|
||||
snapshot.shared = shared
|
||||
snapshot.save()
|
||||
return cls(success=True, snapshot=snapshot)
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class ModuleNode(DjangoObjectType):
|
|||
|
||||
@staticmethod
|
||||
def resolve_snapshots(parent, info, **kwargs):
|
||||
return parent.snapshots.all()
|
||||
return parent.snapshots.filter(creator=info.context.user)
|
||||
|
||||
|
||||
class RecentModuleNode(DjangoObjectType):
|
||||
|
|
|
|||
|
|
@ -85,6 +85,32 @@ query SnapshotDetail($id: ID!) {
|
|||
}
|
||||
"""
|
||||
|
||||
SHARE_SNAPSHOT_MUTATION = """
|
||||
mutation ShareSnapshot($input: ShareSnapshotInput!) {
|
||||
shareSnapshot(input: $input) {
|
||||
success
|
||||
snapshot {
|
||||
shared
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
MODULE_SNAPSHOTS_QUERY = """
|
||||
query SnapshotQuery($slug: String!) {
|
||||
module(slug: $slug) {
|
||||
snapshots {
|
||||
id
|
||||
title
|
||||
created
|
||||
creator {
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def edges_to_array(entity):
|
||||
return [edge['node'] for edge in entity.get('edges')]
|
||||
|
|
@ -263,3 +289,53 @@ class CreateSnapshotTestCase(SkillboxTestCase):
|
|||
self.assertTrue(self.skillbox_class.name not in [sc['name'] for sc in cb1['hiddenFor']])
|
||||
self.assertTrue(self.skillbox_class.name not in [sc['name'] for sc in cb2['hiddenFor']])
|
||||
self.assertTrue(self.skillbox_class.name not in [sc['name'] for sc in cb3['visibleFor']])
|
||||
|
||||
|
||||
class SnapshotTestCase(SkillboxTestCase):
|
||||
def setUp(self) -> None:
|
||||
self.createDefault()
|
||||
self.client = self.get_client()
|
||||
self.slug = 'some-module'
|
||||
|
||||
self.teacher2 = User.objects.get(username='teacher2')
|
||||
self.module = ModuleFactory(slug=self.slug)
|
||||
self.skillbox_class = SchoolClass.objects.get(name='skillbox')
|
||||
self.snapshot = Snapshot.objects.create_snapshot(module=self.module, school_class=self.skillbox_class,
|
||||
user=self.teacher)
|
||||
Snapshot.objects.create_snapshot(module=self.module, school_class=self.skillbox_class,
|
||||
user=self.teacher2)
|
||||
|
||||
def test_show_only_own_snapshots(self):
|
||||
result = self.client.execute(MODULE_SNAPSHOTS_QUERY, variables={
|
||||
"slug": self.slug
|
||||
})
|
||||
self.assertIsNone(result.get('errors'))
|
||||
snapshots = result['data']['module']['snapshots']
|
||||
self.assertEqual(len(snapshots), 1)
|
||||
self.assertEqual(snapshots[0]['creator']['username'], 'teacher')
|
||||
|
||||
def test_share_snapshot(self):
|
||||
self.assertFalse(self.snapshot.shared)
|
||||
result = self.client.execute(SHARE_SNAPSHOT_MUTATION, variables={
|
||||
'input': {
|
||||
'snapshot': to_global_id('Snapshot', self.snapshot.id),
|
||||
'shared': True
|
||||
}
|
||||
})
|
||||
self.assertIsNone(result.get('errors'))
|
||||
data = result['data']['shareSnapshot']
|
||||
self.assertTrue(data['success'])
|
||||
self.assertTrue(data['snapshot']['shared'])
|
||||
snapshot = Snapshot.objects.get(pk=self.snapshot.pk)
|
||||
self.assertTrue(snapshot.shared)
|
||||
|
||||
def test_dont_share_foreign_snapshot(self):
|
||||
self.assertFalse(self.snapshot.shared)
|
||||
teacher2_client = self.get_client(self.teacher2)
|
||||
result = teacher2_client.execute(SHARE_SNAPSHOT_MUTATION, variables={
|
||||
'input': {
|
||||
'snapshot': to_global_id('Snapshot', self.snapshot.id),
|
||||
'shared': True
|
||||
}
|
||||
})
|
||||
self.assertIsNotNone(result.get('errors'))
|
||||
Loading…
Reference in New Issue