diff --git a/client/cypress/fixtures/mocks.js b/client/cypress/fixtures/mocks.js
index 8e36001f..18bbc97a 100644
--- a/client/cypress/fixtures/mocks.js
+++ b/client/cypress/fixtures/mocks.js
@@ -44,7 +44,7 @@ export default {
id: getChapterId(),
title: 'chapter-title',
description: 'chapter-description',
-
+ bookmark: null
}),
ContentBlockNode: () => ({
contents: [],
diff --git a/client/cypress/fixtures/module.minimal.js b/client/cypress/fixtures/module.minimal.js
index 80900ba9..27946e89 100644
--- a/client/cypress/fixtures/module.minimal.js
+++ b/client/cypress/fixtures/module.minimal.js
@@ -4,7 +4,7 @@ export default {
heroImage: 'heroImage',
teaser: 'A Module Mock Teaser',
intro: 'intro',
- assignments: {},
+ assignments: [],
objectiveGroups: [],
id: 'TW9kdWxlTm9kZToxMjM=',
chapters: [],
diff --git a/client/cypress/integration/e2e/bookmarks.spec.js b/client/cypress/integration/e2e/bookmarks.spec.js
deleted file mode 100644
index 6f154431..00000000
--- a/client/cypress/integration/e2e/bookmarks.spec.js
+++ /dev/null
@@ -1,36 +0,0 @@
-describe('Bookmarks', () => {
- beforeEach(() => {
- // todo: mock all the graphql queries and mutations
- cy.exec('python ../server/manage.py prepare_bookmarks_for_cypress');
-
- cy.viewport('macbook-15');
- cy.apolloLogin('rachel.green', 'test');
- });
-
- it('should bookmark content block', () => {
- cy.visit('/module/lohn-und-budget/');
-
- cy.get('.content-component').contains('Das folgende Interview').parent().parent().as('interviewContent');
-
- cy.get('@interviewContent').within(() => {
- cy.get('.bookmark-actions__bookmark').click();
- cy.get('.bookmark-actions__add-note').click();
- });
-
- cy.get('[data-cy=bookmark-note]').within(() => {
- cy.get('.skillbox-input').type('Hallo Velo');
- });
-
- cy.get('[data-cy=modal-save-button]').click();
-
- cy.get('@interviewContent').within(() => {
- cy.get('.bookmark-actions__edit-note').click();
- });
-
- cy.get('[data-cy=bookmark-note]').within(() => {
- cy.get('.skillbox-input').clear().type('Hello Bike');
- });
-
- cy.get('[data-cy=modal-save-button]').click();
- });
-});
diff --git a/client/cypress/integration/frontend/bookmarks.spec.js b/client/cypress/integration/frontend/bookmarks.spec.js
new file mode 100644
index 00000000..9dcc3e54
--- /dev/null
+++ b/client/cypress/integration/frontend/bookmarks.spec.js
@@ -0,0 +1,124 @@
+import {getMinimalMe} from '../../support/helpers';
+import minimalModule from '../../fixtures/module.minimal';
+
+const {me: minimalMe} = getMinimalMe({});
+
+
+describe('Bookmarks', () => {
+ beforeEach(() => {
+ cy.setup();
+ cy.mockGraphqlOps({
+ operations: {
+ MeQuery: {
+ me: minimalMe
+ },
+ ModuleDetailsQuery: {
+ module: {
+ ...minimalModule,
+ chapters: [
+ {
+ title: 'My super Chapter',
+ contentBlocks: [
+ {
+ contents: [
+ {
+ type: 'text_block',
+ value: {
+ text: 'Das folgende Interview'
+ },
+ id: "df8212ee-3e82-49fa-977e-c4b60789163e"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ },
+ UpdateLastModule: {},
+ UpdateContentBookmark: {
+ updateContentBookmark: {
+ success: true
+ }
+ },
+ UpdateChapterBookmark: {
+ updateChapterBookmark: {
+ success: true
+ }
+ },
+ AddNote: ({input: {note}}) => ({
+ addNote: {
+ note
+ }
+ }),
+ UpdateNote: ({input: {note}}) => ({
+ updateNote: {
+ note
+ }
+ })
+ }
+ });
+ });
+
+ it('should bookmark instrument', () => {
+ cy.visit();
+ });
+
+ it('should bookmark module', () => {
+ cy.visit();
+ });
+
+ it('should bookmark chapter', () => {
+ cy.visit('/module/lohn-und-budget/');
+
+ cy.getByDataCy('chapter-bookmark-actions').as('chapterBookmark');
+
+ cy.get('@chapterBookmark').within(() => {
+ cy.getByDataCy('bookmark-action').click();
+ cy.getByDataCy('add-note-action').click();
+ });
+
+ cy.get('[data-cy=bookmark-note]').within(() => {
+ cy.get('.skillbox-input').type('Hallo Velo');
+ });
+
+ cy.get('[data-cy=modal-save-button]').click();
+
+ cy.get('@chapterBookmark').within(() => {
+ cy.getByDataCy('edit-note-action').click();
+ });
+
+ cy.get('[data-cy=bookmark-note]').within(() => {
+ cy.get('.skillbox-input').clear().type('Hello Bike');
+ });
+
+ cy.get('[data-cy=modal-save-button]').click();
+ });
+
+ it('should bookmark content block', () => {
+ cy.visit('/module/lohn-und-budget/');
+
+ cy.getByDataCy('content-component').contains('Das folgende Interview').parent().parent().as('interviewContent');
+
+ cy.get('@interviewContent').within(() => {
+ cy.get('.bookmark-actions__bookmark').click();
+ cy.get('.bookmark-actions__add-note').click();
+ });
+
+ cy.get('[data-cy=bookmark-note]').within(() => {
+ cy.get('.skillbox-input').type('Hallo Velo');
+ });
+
+ cy.get('[data-cy=modal-save-button]').click();
+
+ cy.get('@interviewContent').within(() => {
+ cy.get('.bookmark-actions__edit-note').click();
+ });
+
+ cy.get('[data-cy=bookmark-note]').within(() => {
+ cy.get('.skillbox-input').clear().type('Hello Bike');
+ });
+
+ cy.get('[data-cy=modal-save-button]').click();
+ });
+});
diff --git a/client/src/components/Chapter.vue b/client/src/components/Chapter.vue
index aa44d271..02bc76a2 100644
--- a/client/src/components/Chapter.vue
+++ b/client/src/components/Chapter.vue
@@ -2,6 +2,7 @@
{
const query = CHAPTER_QUERY;
const variables = {id};
- const data = store.readQuery({
+ const {chapter} = store.readQuery({
query,
variables,
});
- const chapter = data.chapter;
+ let bookmark;
if (bookmarked) {
- chapter.bookmark = {
+ bookmark = {
__typename: 'ChapterBookmarkNode',
note: null,
};
} else {
- chapter.bookmark = null;
+ bookmark = null;
}
- data.chapter = chapter;
+ const data = {
+ chapter: {
+ ...chapter,
+ bookmark
+ }
+ };
store.writeQuery({
data,
diff --git a/client/src/components/content-blocks/ContentComponent.vue b/client/src/components/content-blocks/ContentComponent.vue
index b901e381..48d1e4b8 100644
--- a/client/src/components/content-blocks/ContentComponent.vue
+++ b/client/src/components/content-blocks/ContentComponent.vue
@@ -2,6 +2,7 @@
@@ -19,6 +21,7 @@
getCacheKey({__typename: 'ContentBlockNode', id: args.id}),
- contentBlock: {
- read: idToRefFactory('ContentBlockNode')
- // read(_, {args, toReference}) {
- // return toReference({
- // __typename: 'ContentBlockNode',
- // id: args.id
- // });
- // }
- }
- },
- // chapter: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ChapterNode', id: args.id}),
- chapter: {read: idToRefFactory('ChapterNode')},
- assignment: {read: idToRefFactory('AssignmentNode')},
- objective: {read: idToRefFactory('ObjectiveNode')},
- objectiveGroup: {read: idToRefFactory('ObjectiveGroupNode')},
- projectEntry: {read: idToRefFactory('ProjectEntryNode')},
- project: {
- read(_, {args: {slug, id}, toReference}) {
- console.log(`Trying to reference project with slug ${slug}, id ${id}`);
- if (slug) {
- return toReference({
- __typename: 'ProjectNode',
- slug
- });
- } else {
- return toReference({
- __typename: 'ProjectNode',
- id
- });
- }
- }
- },
- // assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id}),
- // objective: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveNode', id: args.id}),
- // objectiveGroup: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveGroupNode', id: args.id}),
- // projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}),
+ // these used to be in cacheRedirects, now here
+ contentBlock: { read: idToRefFactory('ContentBlockNode') },
+ chapter: {read: idToRefFactory('ChapterNode')},
+ assignment: {read: idToRefFactory('AssignmentNode')},
+ objective: {read: idToRefFactory('ObjectiveNode')},
+ objectiveGroup: {read: idToRefFactory('ObjectiveGroupNode')},
+ projectEntry: {read: idToRefFactory('ProjectEntryNode')},
+ project: {
+ read(_, {args: {slug, id}, toReference}) {
+ console.log(`Trying to reference project with slug ${slug}, id ${id}`);
+ if (slug) {
+ return toReference({
+ __typename: 'ProjectNode',
+ slug
+ });
+ } else {
+ return toReference({
+ __typename: 'ProjectNode',
+ id
+ });
+ }
+ }
+ },
+ }
},
};
diff --git a/client/src/helpers/new-note-mutation.js b/client/src/helpers/new-note-mutation.js
index 39499d89..5c2ccba9 100644
--- a/client/src/helpers/new-note-mutation.js
+++ b/client/src/helpers/new-note-mutation.js
@@ -16,22 +16,35 @@ export const constructNoteMutation = (n) => {
if (n.type === 'ContentBlockNode') {
const query = CONTENT_BLOCK_QUERY;
const variables = {id: n.block};
- const data = store.readQuery({
+ const {contentBlock} = store.readQuery({
query,
variables
});
- const bookmarks = data.contentBlock.bookmarks;
+ let bookmarks;
- let index = bookmarks.findIndex(compareUuid(n));
+ let index = contentBlock.bookmarks.findIndex(compareUuid(n));
if (index > -1) {
- let el = bookmarks[index];
- el.note = note;
- bookmarks.splice(index, 1, el);
+ const el = {
+ ...contentBlock.bookmarks[index],
+ note
+ };
+ bookmarks = [
+ ...contentBlock.bookmarks.slice(0, index),
+ el,
+ ...contentBlock.bookmarks.slice(index + 1)
+ ];
+ } else {
+ bookmarks = [...contentBlock.bookmarks];
}
- data.contentBlock.bookmarks = bookmarks;
+ const data = {
+ contentBlock: {
+ ...contentBlock,
+ bookmarks
+ }
+ };
store.writeQuery({
data,
@@ -70,16 +83,23 @@ export const constructNoteMutation = (n) => {
const type = getBlockType(n.parent) === 'ChapterNode' ? 'chapter' : 'module';
const query = type === 'chapter' ? CHAPTER_QUERY : MODULE_QUERY;
const variables = {id: n.parent};
- const data = store.readQuery({
+ const fromStore = store.readQuery({
query,
variables
});
- const bookmark = data[type].bookmark;
+ const entity = fromStore[type];
+ let bookmark = {
+ ...entity.bookmark,
+ note
+ };
- bookmark.note = note;
-
- data[type].bookmark = bookmark;
+ const data = {
+ [type]: {
+ ...entity,
+ bookmark
+ }
+ };
store.writeQuery({
data,
diff --git a/client/src/helpers/update-content-bookmark-mutation.js b/client/src/helpers/update-content-bookmark-mutation.js
index 76592747..81e19f1c 100644
--- a/client/src/helpers/update-content-bookmark-mutation.js
+++ b/client/src/helpers/update-content-bookmark-mutation.js
@@ -70,27 +70,40 @@ export const constructContentComponentBookmarkMutation = (uuid, bookmarked, pare
update: (store) => {
const query = CONTENT_BLOCK_QUERY;
const variables = {id: root};
- const data = store.readQuery({
+ const {contentBlock} = store.readQuery({
query,
variables
});
- const bookmarks = data.contentBlock.bookmarks;
+ // const bookmarks = data.contentBlock.bookmarks;
+ let bookmarks;
if (bookmarked) {
- bookmarks.push({
+ bookmarks = [
+ ...contentBlock.bookmarks,
+ {
note: null,
uuid,
__typename: 'ContentBlockBookmarkNode'
- });
+ }
+ ];
} else {
let index = bookmarks.findIndex(compareUuid(uuid));
if (index > -1) {
bookmarks.splice(index, 1);
}
+ bookmarks = [
+ ...contentBlock.bookmarks.slice(0, index),
+ ...contentBlock.bookmarks.slice(index + 1)
+ ];
}
- data.contentBlock.bookmarks = bookmarks;
+ const data = {
+ contentBlock: {
+ ...contentBlock,
+ bookmarks
+ }
+ };
store.writeQuery({
data,