Add server implementation and unit test for chapter highlight

This commit is contained in:
Ramon Wenger 2024-02-22 15:18:51 +01:00
parent 22cd8eb57f
commit 5c3ed10a26
4 changed files with 78 additions and 26 deletions

View File

@ -13,6 +13,7 @@ class ChapterNode(DjangoObjectType):
title_hidden_for = graphene.List("users.schema.SchoolClassNode") title_hidden_for = graphene.List("users.schema.SchoolClassNode")
description_hidden_for = graphene.List("users.schema.SchoolClassNode") description_hidden_for = graphene.List("users.schema.SchoolClassNode")
path = graphene.String() path = graphene.String()
highlights = graphene.List("notes.schema.HighlightNode")
class Meta: class Meta:
model = Chapter model = Chapter
@ -72,3 +73,7 @@ class ChapterNode(DjangoObjectType):
def resolve_path(root: Chapter, info, **kwargs): def resolve_path(root: Chapter, info, **kwargs):
module = root.get_parent() module = root.get_parent()
return f"module/{module.slug}#{root.graphql_id}" return f"module/{module.slug}#{root.graphql_id}"
@staticmethod
def resolve_highlights(root: Chapter, info, **kwargs):
return root.highlights.filter(user=info.context.user)

View File

@ -65,3 +65,6 @@ class Highlight(models.Model):
text = models.TextField() text = models.TextField()
note = models.OneToOneField(Note, null=True, on_delete=models.SET_NULL) note = models.OneToOneField(Note, null=True, on_delete=models.SET_NULL)
color = models.CharField(max_length=50) color = models.CharField(max_length=50)
def __str__(self) -> str:
return self.text

View File

@ -1,5 +1,5 @@
import pytest import pytest
from books.factories import ContentBlockFactory, ModuleFactory from books.factories import ChapterFactory, ContentBlockFactory, ModuleFactory
from books.models.contentblock import ContentBlock from books.models.contentblock import ContentBlock
from graphql_relay import to_global_id from graphql_relay import to_global_id
@ -110,6 +110,12 @@ module_query = (
highlights { highlights {
...HighlightLegacyParts ...HighlightLegacyParts
} }
chapters {
id
highlights {
...HighlightLegacyParts
}
}
} }
} }
""" """
@ -217,3 +223,40 @@ class TestAddHighlight:
assert module.get("id") == mid assert module.get("id") == mid
assert module.get("highlights")[0].get("color") == "alpha" assert module.get("highlights")[0].get("color") == "alpha"
assert module.get("highlights")[0].get("page").get("id") == mid assert module.get("highlights")[0].get("page").get("id") == mid
def test_add_highlight_in_chapter(self, teacher, get_client):
module = ModuleFactory()
chapter = ChapterFactory(parent=module)
client = get_client(teacher)
mid = to_global_id("ModuleNode", module.id)
cid = to_global_id("ChapterNode", chapter.id)
result = client.execute(
add_highlight_mutation,
variables={
"input": {
"highlight": {
"page": cid,
"paragraphIndex": 0,
"text": "Hallo",
"startPosition": 0,
"selectionLength": 10,
"color": "alpha",
}
}
},
)
assert result.errors is None
highlight = result.data.get("addHighlight").get("highlight")
assert highlight.get("text") == "Hallo"
assert highlight.get("page").get("id") == cid
client = get_client(teacher)
result = client.execute(module_query, variables={"id": mid})
assert result.errors is None
module = result.data.get("module")
logger.debug(module)
chapter = module.get("chapters")[0]
assert chapter.get("id") == cid
assert chapter.get("highlights")[0].get("color") == "alpha"
assert chapter.get("highlights")[0].get("page").get("id") == cid

View File

@ -567,22 +567,25 @@ type ChapterNode implements Node & ChapterInterface {
bookmark: ChapterBookmarkNode bookmark: ChapterBookmarkNode
contentBlocks: [ContentBlockNode] contentBlocks: [ContentBlockNode]
path: String path: String
highlights: [HighlightNode]
} }
type InstrumentBookmarkNode implements Node { type HighlightNode implements Node {
"""The ID of the object""" """The ID of the object"""
id: ID! id: ID!
user: PrivateUserNode! user: PrivateUserNode!
page: HighlightableNode
contentIndex: Int
contentUuid: UUID
paragraphIndex: Int!
startPosition: Int!
selectionLength: Int!
text: String!
note: NoteNode note: NoteNode
uuid: UUID color: String!
instrument: InstrumentNode!
} }
""" union HighlightableNode = ContentBlockNode | InstrumentNode | ModuleNode | ChapterNode
Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects
in fields, resolvers and input.
"""
scalar UUID
type InstrumentNode implements Node { type InstrumentNode implements Node {
"""Der Seitentitel, der öffentlich angezeigt werden soll""" """Der Seitentitel, der öffentlich angezeigt werden soll"""
@ -603,6 +606,21 @@ type InstrumentNode implements Node {
highlights: [HighlightNode] highlights: [HighlightNode]
} }
type InstrumentBookmarkNode implements Node {
"""The ID of the object"""
id: ID!
user: PrivateUserNode!
note: NoteNode
uuid: UUID
instrument: InstrumentNode!
}
"""
Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects
in fields, resolvers and input.
"""
scalar UUID
type InstrumentTypeNode implements Node { type InstrumentTypeNode implements Node {
"""The ID of the object""" """The ID of the object"""
id: ID! id: ID!
@ -620,23 +638,6 @@ type InstrumentCategoryNode implements Node {
types: [InstrumentTypeNode] types: [InstrumentTypeNode]
} }
type HighlightNode implements Node {
"""The ID of the object"""
id: ID!
user: PrivateUserNode!
page: HighlightableNode
contentIndex: Int
contentUuid: UUID
paragraphIndex: Int!
startPosition: Int!
selectionLength: Int!
text: String!
note: NoteNode
color: String!
}
union HighlightableNode = ContentBlockNode | InstrumentNode | ModuleNode | ChapterNode
type SnapshotObjectiveGroupNode implements Node { type SnapshotObjectiveGroupNode implements Node {
"""The ID of the object""" """The ID of the object"""
id: ID! id: ID!