Add parts for room entry deletion
This commit is contained in:
parent
acf59b218b
commit
c536a04122
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="room-entry">
|
||||
<div class="room-entry__more">
|
||||
<div class="room-entry__more" v-if="myEntry">
|
||||
<a @click="showMenu = !showMenu" class="room-entry__more-link">
|
||||
<ellipses class="room-entry__ellipses"></ellipses>
|
||||
</a>
|
||||
|
|
@ -28,6 +28,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import DELETE_ROOM_ENTRY_MUTATION from '@/graphql/gql/mutations/deleteRoomEntry.gql';
|
||||
import ROOM_ENTRIES_QUERY from '@/graphql/gql/roomEntriesQuery.gql';
|
||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||
|
||||
import UserWidget from '@/components/UserWidget.vue';
|
||||
import Ellipses from '@/components/icons/Ellipses.vue';
|
||||
import WidgetPopover from '@/components/rooms/WidgetPopover';
|
||||
|
|
@ -42,7 +46,29 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
deleteRoomEntry() {
|
||||
deleteRoomEntry(id) {
|
||||
this.$apollo.mutate({
|
||||
mutation: DELETE_ROOM_ENTRY_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
id
|
||||
}
|
||||
},
|
||||
update(store, {data: {deleteRoomEntry: {success, roomSlug}}}) {
|
||||
if (success) {
|
||||
const query = ROOM_ENTRIES_QUERY;
|
||||
const variables = {slug: roomSlug};
|
||||
const data = store.readQuery({query, variables});
|
||||
if (data) {
|
||||
data.room.roomEntries.edges.splice(data.room.roomEntries.edges.findIndex(edge => edge.node.id === id), 1);
|
||||
store.writeQuery({query, data, variables});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
editRoomEntry(id){
|
||||
this.$store.dispatch('editRoomEntry', id);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -70,6 +96,17 @@
|
|||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
myEntry() {
|
||||
return this.author.id === this.me.id;
|
||||
}
|
||||
},
|
||||
|
||||
apollo: {
|
||||
me() {
|
||||
return {
|
||||
query: ME_QUERY
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -114,20 +151,28 @@
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&__ellipses {
|
||||
width: 30px;
|
||||
fill: $color-darkgrey-1;
|
||||
}
|
||||
|
||||
&__more {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__more-link {
|
||||
background-color: rgba($color-white, 0.9);
|
||||
width: 35px;
|
||||
height: 15px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__ellipses {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
fill: $color-darkgrey-1;
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
&__popover {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) {
|
||||
deleteRoomEntry(input: $input) {
|
||||
success
|
||||
errors
|
||||
roomSlug
|
||||
}
|
||||
}
|
||||
|
||||
#{
|
||||
# "input": {
|
||||
# "id": "Um9vbU5vZGU6MjY="
|
||||
# }
|
||||
#}
|
||||
|
|
@ -51,7 +51,9 @@
|
|||
data() {
|
||||
return {
|
||||
rooms: [],
|
||||
me: {}
|
||||
me: {
|
||||
permissions: []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class RoomEntryFactory(factory.django.DjangoModelFactory):
|
|||
subtitle = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(8, 12)))
|
||||
description = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(20, 30)))
|
||||
author = factory.Iterator(get_user_model().objects.all())
|
||||
room = factory.SubFactory(RoomFactory)
|
||||
|
||||
contents = wagtail_factories.StreamFieldFactory({
|
||||
'text_block': TextBlockFactory,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import graphene
|
||||
from graphene import relay
|
||||
from graphql_relay import to_global_id
|
||||
|
||||
from api.utils import get_object
|
||||
from rooms.inputs import UpdateRoomArgument, AddRoomArgument, AddRoomEntryArgument
|
||||
from rooms.models import Room
|
||||
from rooms.models import Room, RoomEntry
|
||||
from rooms.schema import RoomNode, RoomEntryNode
|
||||
from rooms.serializers import RoomSerializer, RoomEntrySerializer
|
||||
from users.models import SchoolClass
|
||||
|
|
@ -93,8 +94,30 @@ class AddRoomEntry(relay.ClientIDMutation):
|
|||
return cls(room_entry=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()])
|
||||
|
||||
|
||||
class DeleteRoomEntry(relay.ClientIDMutation):
|
||||
class Input:
|
||||
id = graphene.ID(required=True)
|
||||
|
||||
success = graphene.Boolean()
|
||||
room_slug = graphene.String()
|
||||
room_id = graphene.ID()
|
||||
errors = graphene.List(graphene.String)
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||
id = kwargs.get('id')
|
||||
room_entry = get_object(RoomEntry, id)
|
||||
if room_entry.author.pk != info.context.user.pk:
|
||||
raise Exception('You are not the owner of this room entry')
|
||||
room_id = to_global_id('RoomNode', room_entry.room.pk)
|
||||
room_slug = room_entry.room.slug
|
||||
room_entry.delete()
|
||||
return cls(success=True, room_id=room_id, room_slug=room_slug)
|
||||
|
||||
|
||||
class RoomMutations:
|
||||
update_room = UpdateRoom.Field()
|
||||
add_room = AddRoom.Field()
|
||||
delete_room = DeleteRoom.Field()
|
||||
add_room_entry = AddRoomEntry.Field()
|
||||
delete_room_entry = DeleteRoomEntry.Field()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
from django.test import TestCase, RequestFactory
|
||||
from graphene.test import Client
|
||||
from graphql_relay import to_global_id
|
||||
|
||||
from api.schema import schema
|
||||
from core.factories import UserFactory
|
||||
from rooms.factories import RoomEntryFactory, RoomFactory
|
||||
from rooms.models import RoomEntry
|
||||
from users.factories import SchoolClassFactory
|
||||
from users.services import create_users
|
||||
|
||||
|
||||
class RoomEntryMutationsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(username='aschi')
|
||||
self.another_user = UserFactory(username='pesche')
|
||||
s = SchoolClassFactory(users=[self.user, self.another_user])
|
||||
self.room_entry = RoomEntryFactory(author=self.user, room=RoomFactory(school_class=s))
|
||||
|
||||
request = RequestFactory().get('/')
|
||||
request.user = self.user
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
def test_delete_room_entry(self):
|
||||
self.assertEqual(RoomEntry.objects.count(), 1)
|
||||
|
||||
mutation = '''
|
||||
mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) {
|
||||
deleteRoomEntry(input: $input) {
|
||||
success
|
||||
errors
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
result = self.client.execute(mutation, variables={
|
||||
'input': {
|
||||
'id': to_global_id('RoomEntryNode', self.room_entry.pk)
|
||||
}
|
||||
})
|
||||
self.assertIsNone(result.get('errors'))
|
||||
self.assertEqual(RoomEntry.objects.count(), 0)
|
||||
|
||||
def test_delete_room_not_owner(self):
|
||||
self.assertEqual(RoomEntry.objects.count(), 1)
|
||||
mutation = '''
|
||||
mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) {
|
||||
deleteRoomEntry(input: $input) {
|
||||
success
|
||||
errors
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
request = RequestFactory().get('/')
|
||||
request.user = self.another_user
|
||||
client = Client(schema=schema, context_value=request)
|
||||
|
||||
result = client.execute(mutation, variables={
|
||||
'input': {
|
||||
'id': to_global_id('RoomEntryNode', self.room_entry.pk)
|
||||
}
|
||||
})
|
||||
|
||||
self.assertIsNotNone(result.get('errors'))
|
||||
self.assertEqual(RoomEntry.objects.count(), 1)
|
||||
Loading…
Reference in New Issue