Re-add comment test

This commit is contained in:
Ramon Wenger 2021-08-24 13:31:05 +02:00
parent 4aca082621
commit b966b4e981
9 changed files with 122 additions and 31 deletions

View File

@ -16,8 +16,7 @@ describe('Article page', () => {
RoomEntryQuery: { RoomEntryQuery: {
roomEntry, roomEntry,
}, },
AddComment(input) { AddComment({input}) {
console.log(input);
return { return {
addComment: { addComment: {
success: true, success: true,
@ -38,7 +37,7 @@ describe('Article page', () => {
cy.setup(); cy.setup();
}); });
it.skip('goes to article and leaves a comment', () => { it('goes to article and leaves a comment', () => {
cy.mockGraphqlOps({ cy.mockGraphqlOps({
operations, operations,
}); });

View File

@ -7,11 +7,12 @@
data-cy="comment-textarea" data-cy="comment-textarea"
class="comment-input__textarea" class="comment-input__textarea"
placeholder="Kommentar erfassen" placeholder="Kommentar erfassen"
@input="updateValue($event.target.value)"
/> />
<a <a
data-cy="submit-comment" data-cy="submit-comment"
class="button button--primary" class="button button--primary"
@click="$emit('input', $event.target.value)">Kommentar teilen</a> @click="$emit('submit', text)">Kommentar teilen</a>
</div> </div>
</template> </template>
@ -28,6 +29,16 @@
components: { components: {
EmojiBar, EmojiBar,
}, },
data() {
return {
text: ''
};
},
methods: {
updateValue(text) {
this.text = text;
}
},
}; };
</script> </script>

View File

@ -92,6 +92,7 @@ export default function (uri, networkErrorCallback) {
switch (obj.__typename) { switch (obj.__typename) {
case 'InstrumentNode': case 'InstrumentNode':
case 'ModuleNode': case 'ModuleNode':
case 'RoomEntryNode':
return `${obj.__typename}:${obj.slug}`; return `${obj.__typename}:${obj.slug}`;
default: default:
return defaultDataIdFromObject(obj); return defaultDataIdFromObject(obj);

View File

@ -1,5 +1,14 @@
mutation AddComment($input: AddCommentInput!) { mutation AddComment($input: AddCommentInput!) {
addComment(input: $input) { addComment(input: $input) {
success success
comment {
text
id
owner {
firstName
lastName
}
created
}
} }
} }

View File

@ -2,5 +2,17 @@
query RoomEntryQuery($slug: String!) { query RoomEntryQuery($slug: String!) {
roomEntry(slug: $slug) { roomEntry(slug: $slug) {
...RoomEntryParts ...RoomEntryParts
comments {
edges {
node {
text
owner {
firstName
lastName
}
created
}
}
}
} }
} }

View File

@ -131,7 +131,7 @@ function redirectUsersWithoutValidLicense(to) {
function redirectStudentsWithoutClass() { function redirectStudentsWithoutClass() {
return privateApolloClient.query({ return privateApolloClient.query({
query: ME_QUERY, query: ME_QUERY,
}).then(({data}) => data.me.schoolClasses.edges.length === 0 && data.me.permissions.length === 0); }).then(({data}) => data.me.schoolClasses.edges.length === 0 && !data.me.isTeacher);
} }
function redirectUsersToOnboarding(to) { function redirectUsersToOnboarding(to) {
@ -169,21 +169,27 @@ router.beforeEach(async (to, from, next) => {
localStorage.setItem(postLoginRedirectUrlKey, postLoginRedirectionUrl); localStorage.setItem(postLoginRedirectUrlKey, postLoginRedirectionUrl);
} }
Vue.$log.debug('redirecting to hello', to);
next(redirectUrl); next(redirectUrl);
return; return;
} }
if (to.name && to.name !== 'licenseActivation' && loginRequired(to) && await redirectUsersWithoutValidLicense()) { if (to.name && to.name !== 'licenseActivation' && loginRequired(to) && await redirectUsersWithoutValidLicense()) {
Vue.$log.debug('redirecting to licenseActivation', to, null);
console.log('redirecting to licenseActivation', to, null);
next({name: 'licenseActivation'}); next({name: 'licenseActivation'});
return; return;
} }
if (!joiningClass(to) && loginRequired(to) && await redirectStudentsWithoutClass()) { if (!joiningClass(to) && loginRequired(to) && await redirectStudentsWithoutClass()) {
Vue.$log.debug('redirecting to join-class', to);
Vue.$log.debug('await redirectStudentsWithoutClass()', await redirectStudentsWithoutClass());
next({name: 'join-class'}); next({name: 'join-class'});
return; return;
} }
if ((to.name && to.name.indexOf('onboarding') === -1) && !joiningClass(to) && loginRequired(to) && await redirectUsersToOnboarding()) { if ((to.name && to.name.indexOf('onboarding') === -1) && !joiningClass(to) && loginRequired(to) && await redirectUsersToOnboarding()) {
Vue.$log.debug('redirecting to onboarding-start', to);
next({name: 'onboarding-start'}); next({name: 'onboarding-start'});
return; return;
} }

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,18 @@ schema {
mutation: CustomMutation mutation: CustomMutation
} }
input AddCommentInput {
comment: String!
roomEntry: ID!
clientMutationId: String
}
type AddCommentPayload {
success: Boolean
comment: CommentNode
clientMutationId: String
}
input AddContentBlockInput { input AddContentBlockInput {
contentBlock: ContentBlockInput contentBlock: ContentBlockInput
parent: ID parent: ID
@ -255,6 +267,23 @@ type ClassMemberNode {
isMe: Boolean isMe: Boolean
} }
type CommentNode implements Node {
text: String!
owner: PublicUserNode
created: DateTime!
id: ID!
}
type CommentNodeConnection {
pageInfo: PageInfo!
edges: [CommentNodeEdge]!
}
type CommentNodeEdge {
node: CommentNode
cursor: String!
}
type ContentBlockBookmarkNode implements Node { type ContentBlockBookmarkNode implements Node {
id: ID! id: ID!
user: PrivateUserNode! user: PrivateUserNode!
@ -411,6 +440,7 @@ type CustomMutation {
addRoomEntry(input: AddRoomEntryInput!): AddRoomEntryPayload addRoomEntry(input: AddRoomEntryInput!): AddRoomEntryPayload
deleteRoomEntry(input: DeleteRoomEntryInput!): DeleteRoomEntryPayload deleteRoomEntry(input: DeleteRoomEntryInput!): DeleteRoomEntryPayload
updateRoomEntry(input: UpdateRoomEntryInput!): UpdateRoomEntryPayload updateRoomEntry(input: UpdateRoomEntryInput!): UpdateRoomEntryPayload
addComment(input: AddCommentInput!): AddCommentPayload
mutateContentBlock(input: MutateContentBlockInput!): MutateContentBlockPayload mutateContentBlock(input: MutateContentBlockInput!): MutateContentBlockPayload
addContentBlock(input: AddContentBlockInput!): AddContentBlockPayload addContentBlock(input: AddContentBlockInput!): AddContentBlockPayload
deleteContentBlock(input: DeleteContentBlockInput!): DeleteContentBlockPayload deleteContentBlock(input: DeleteContentBlockInput!): DeleteContentBlockPayload
@ -854,6 +884,7 @@ type ProjectNode implements Node {
appearance: String! appearance: String!
student: PrivateUserNode! student: PrivateUserNode!
final: Boolean! final: Boolean!
schoolClass: SchoolClassNode
entries(offset: Int, before: String, after: String, first: Int, last: Int): ProjectEntryNodeConnection! entries(offset: Int, before: String, after: String, first: Int, last: Int): ProjectEntryNodeConnection!
pk: Int pk: Int
entriesCount: Int entriesCount: Int
@ -886,6 +917,7 @@ type RoomEntryNode implements Node {
room: RoomNode! room: RoomNode!
author: PublicUserNode author: PublicUserNode
contents: GenericStreamFieldType contents: GenericStreamFieldType
comments(offset: Int, before: String, after: String, first: Int, last: Int, owner: ID): CommentNodeConnection
pk: Int pk: Int
} }
@ -928,20 +960,9 @@ input SchoolClassInput {
} }
type SchoolClassNode implements Node { type SchoolClassNode implements Node {
id: ID!
name: String! name: String!
isDeleted: Boolean!
code: String code: String
users(offset: Int, before: String, after: String, first: Int, last: Int, username: String, email: String): PrivateUserNodeConnection! id: ID!
moduleSet(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection!
hiddenChapterTitles(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
hiddenChapterDescriptions(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
hiddenContentBlocks(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ContentBlockNodeConnection!
visibleContentBlocks(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ContentBlockNodeConnection!
hiddenObjectiveGroups(offset: Int, before: String, after: String, first: Int, last: Int, title: String, module_Slug: String): ObjectiveGroupNodeConnection!
hiddenObjectives(offset: Int, before: String, after: String, first: Int, last: Int, text: String): ObjectiveNodeConnection!
visibleObjectives(offset: Int, before: String, after: String, first: Int, last: Int, text: String): ObjectiveNodeConnection!
rooms(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, appearance: String): RoomNodeConnection!
pk: Int pk: Int
members: [ClassMemberNode] members: [ClassMemberNode]
readOnly: Boolean readOnly: Boolean
@ -1128,9 +1149,9 @@ type SyncModuleVisibilityPayload {
type TeamNode implements Node { type TeamNode implements Node {
name: String! name: String!
isDeleted: Boolean!
code: String code: String
id: ID! id: ID!
isDeleted: Boolean!
creator: PrivateUserNode creator: PrivateUserNode
members: [PublicUserNode] members: [PublicUserNode]
pk: Int pk: Int

View File

@ -24,6 +24,7 @@ class SchoolClassNode(DjangoObjectType):
class Meta: class Meta:
model = SchoolClass model = SchoolClass
only_fields = ['name', 'code', 'members', 'pk', 'read_only']
filter_fields = ['name'] filter_fields = ['name']
interfaces = (relay.Node,) interfaces = (relay.Node,)