Fix some cypress tests
This commit is contained in:
parent
6b4cff9760
commit
3f07a91d5c
|
|
@ -2,26 +2,52 @@ import module from '../../../fixtures/module.minimal';
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
import {getMinimalMe} from '../../../support/helpers';
|
||||||
import {hasOperationName} from '../../../support/graphql';
|
import {hasOperationName} from '../../../support/graphql';
|
||||||
|
|
||||||
|
let snapshotTitle;
|
||||||
|
let deleteSuccess;
|
||||||
|
let page;
|
||||||
|
|
||||||
|
const moduleWithSnapshots = {
|
||||||
|
...module,
|
||||||
|
snapshots: [
|
||||||
|
{
|
||||||
|
id: 'U25hcHNob3ROb2RlOjQ=',
|
||||||
|
title: 'Old Title',
|
||||||
|
created: '2020-01-01',
|
||||||
|
mine: true,
|
||||||
|
shared: false,
|
||||||
|
creator: 'me',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'U25hcHNob3ROb2RlOjU=',
|
||||||
|
title: 'Shared snapshot',
|
||||||
|
created: '2020-01-02',
|
||||||
|
mine: false,
|
||||||
|
shared: true,
|
||||||
|
creator: 'someone else',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const mockDeleteSnapshot = (success) => {
|
const mockDeleteSnapshot = (success) => {
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
cy.intercept('POST', '/api/graphql', (req) => {
|
||||||
if (hasOperationName(req, 'DeleteSnapshot')) {
|
if (hasOperationName(req, 'DeleteSnapshot')) {
|
||||||
let result;
|
let result;
|
||||||
if (success) {
|
if (success) {
|
||||||
result = {
|
result = {
|
||||||
message: 'yay!',
|
message: 'yay!',
|
||||||
__typename: 'Success'
|
__typename: 'Success',
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
result = {
|
result = {
|
||||||
reason: 'Not the owner',
|
reason: 'Not the owner',
|
||||||
__typename: 'NotOwner'
|
__typename: 'NotOwner',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
req.reply({
|
req.reply({
|
||||||
data: {
|
data: {
|
||||||
deleteSnapshot: {
|
deleteSnapshot: {
|
||||||
result
|
result,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -42,7 +68,7 @@ const mockUpdateSnapshot = (title) => {
|
||||||
} else {
|
} else {
|
||||||
snapshot = {
|
snapshot = {
|
||||||
__typename: 'NotOwner',
|
__typename: 'NotOwner',
|
||||||
reason: 'Not the owner'
|
reason: 'Not the owner',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
req.reply({
|
req.reply({
|
||||||
|
|
@ -57,10 +83,57 @@ const mockUpdateSnapshot = (title) => {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// wait for the specified amount of requests in the test, so they don't spill over to the next test
|
||||||
|
const waitNTimes = (n) => {
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
cy.wait('@graphqlRequest');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
describe('Snapshot', () => {
|
describe('Snapshot', () => {
|
||||||
const operations = isTeacher => ({
|
const operations = isTeacher => ({
|
||||||
operations: {
|
operations: {
|
||||||
|
UpdateSnapshot: {
|
||||||
|
updateSnapshot: {
|
||||||
|
snapshot() {
|
||||||
|
let result;
|
||||||
|
if (snapshotTitle) {
|
||||||
|
result = {
|
||||||
|
__typename: 'SnapshotNode',
|
||||||
|
id: 'U25hcHNob3ROb2RlOjQ=',
|
||||||
|
title: snapshotTitle,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
result = {
|
||||||
|
__typename: 'NotOwner',
|
||||||
|
reason: 'Not the owner',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
DeleteSnapshot: {
|
||||||
|
deleteSnapshot: {
|
||||||
|
result() {
|
||||||
|
let result;
|
||||||
|
if (deleteSuccess) {
|
||||||
|
result = {
|
||||||
|
message: 'yay!',
|
||||||
|
__typename: 'Success',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
result = {
|
||||||
|
reason: 'Not the owner',
|
||||||
|
__typename: 'NotOwner',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
MeQuery: getMinimalMe({isTeacher}),
|
MeQuery: getMinimalMe({isTeacher}),
|
||||||
ModuleDetailsQuery: {
|
ModuleDetailsQuery: {
|
||||||
module,
|
module,
|
||||||
|
|
@ -77,6 +150,11 @@ describe('Snapshot', () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
UpdateLastModule: {},
|
UpdateLastModule: {},
|
||||||
|
ModuleEditModeQuery: {
|
||||||
|
module: {
|
||||||
|
slug: module.slug,
|
||||||
|
},
|
||||||
|
},
|
||||||
ModuleSnapshotsQuery: {
|
ModuleSnapshotsQuery: {
|
||||||
module: {
|
module: {
|
||||||
...module,
|
...module,
|
||||||
|
|
@ -103,18 +181,21 @@ describe('Snapshot', () => {
|
||||||
SnapshotDetail: {
|
SnapshotDetail: {
|
||||||
snapshot: {
|
snapshot: {
|
||||||
chapters: [],
|
chapters: [],
|
||||||
module: {}
|
module: {},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
ApplySnapshot: {
|
ApplySnapshot: {
|
||||||
applySnapshot: {
|
applySnapshot: {
|
||||||
success: true
|
success: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
snapshotTitle = false;
|
||||||
|
deleteSuccess = false;
|
||||||
|
page = moduleWithSnapshots;
|
||||||
cy.setup();
|
cy.setup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -122,6 +203,7 @@ describe('Snapshot', () => {
|
||||||
cy.mockGraphqlOps(operations(true));
|
cy.mockGraphqlOps(operations(true));
|
||||||
cy.visit('module/miteinander-reden/');
|
cy.visit('module/miteinander-reden/');
|
||||||
cy.getByDataCy('snapshot-menu').should('be.visible');
|
cy.getByDataCy('snapshot-menu').should('be.visible');
|
||||||
|
waitNTimes(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Menu is not visible for student', () => {
|
it('Menu is not visible for student', () => {
|
||||||
|
|
@ -130,6 +212,7 @@ describe('Snapshot', () => {
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('be.visible');
|
cy.getByDataCy('module-title').should('be.visible');
|
||||||
cy.getByDataCy('snapshot-menu').should('not.exist');
|
cy.getByDataCy('snapshot-menu').should('not.exist');
|
||||||
|
waitNTimes(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Creates Snapshot', () => {
|
it('Creates Snapshot', () => {
|
||||||
|
|
@ -141,6 +224,7 @@ describe('Snapshot', () => {
|
||||||
cy.getByDataCy('snapshot-list').should('exist').within(() => {
|
cy.getByDataCy('snapshot-list').should('exist').within(() => {
|
||||||
cy.get('.snapshots__snapshot').should('have.length', 1);
|
cy.get('.snapshots__snapshot').should('have.length', 1);
|
||||||
});
|
});
|
||||||
|
waitNTimes(7);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Applies Snapshot', () => {
|
it('Applies Snapshot', () => {
|
||||||
|
|
@ -152,28 +236,33 @@ describe('Snapshot', () => {
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('exist');
|
cy.getByDataCy('module-title').should('exist');
|
||||||
cy.getByDataCy('snapshot-header').should('not.exist');
|
cy.getByDataCy('snapshot-header').should('not.exist');
|
||||||
|
waitNTimes(9);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Renames Snapshot', () => {
|
it('Renames Snapshot', () => {
|
||||||
cy.mockGraphqlOps(operations(true));
|
cy.mockGraphqlOps(operations(true));
|
||||||
const newTitle = 'New Title';
|
const newTitle = 'New Title';
|
||||||
mockUpdateSnapshot(newTitle);
|
snapshotTitle = newTitle;
|
||||||
|
// mockUpdateSnapshot(newTitle);
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
cy.visit('module/miteinander-reden/snapshots');
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
|
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
|
||||||
cy.getByDataCy('rename-snapshot-button').click();
|
cy.getByDataCy('rename-snapshot-button').click();
|
||||||
cy.getByDataCy('edit-name-input').clear().type(newTitle);
|
cy.getByDataCy('edit-name-input').clear().type(newTitle);
|
||||||
cy.getByDataCy('modal-save-button').click();
|
cy.getByDataCy('modal-save-button').click();
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'New Title');
|
cy.getByDataCy('snapshot-link').should('have.text', 'New Title');
|
||||||
|
waitNTimes(5);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Deletes Snapshot', () => {
|
it('Deletes Snapshot', () => {
|
||||||
cy.mockGraphqlOps(operations(true));
|
cy.mockGraphqlOps(operations(true));
|
||||||
mockDeleteSnapshot(true);
|
deleteSuccess = true;
|
||||||
|
// mockDeleteSnapshot(true);
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
cy.visit('module/miteinander-reden/snapshots');
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 1);
|
cy.getByDataCy('snapshot-entry').should('have.length', 1);
|
||||||
cy.getByDataCy('delete-snapshot-button').click();
|
cy.getByDataCy('delete-snapshot-button').click();
|
||||||
cy.getByDataCy('modal-save-button').click();
|
cy.getByDataCy('modal-save-button').click();
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 0);
|
cy.getByDataCy('snapshot-entry').should('have.length', 0);
|
||||||
|
waitNTimes(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays the Snapshot list correcly', () => {
|
it('Displays the Snapshot list correcly', () => {
|
||||||
|
|
@ -188,5 +277,9 @@ describe('Snapshot', () => {
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'Shared snapshot');
|
cy.getByDataCy('snapshot-link').should('have.text', 'Shared snapshot');
|
||||||
cy.getByDataCy('delete-snapshot-button').should('not.exist');
|
cy.getByDataCy('delete-snapshot-button').should('not.exist');
|
||||||
cy.getByDataCy('rename-snapshot-button').should('not.exist');
|
cy.getByDataCy('rename-snapshot-button').should('not.exist');
|
||||||
|
waitNTimes(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import {getMinimalMe} from '../../../support/helpers';
|
||||||
|
|
||||||
const SELECTED_CLASS_ID = 'selectedClassId';
|
const SELECTED_CLASS_ID = 'selectedClassId';
|
||||||
|
|
||||||
|
const slug = 'some-room';
|
||||||
const getOperations = ({readOnly, classReadOnly}) => {
|
const getOperations = ({readOnly, classReadOnly}) => {
|
||||||
const {me} = getMinimalMe({readOnly, classReadOnly, isTeacher: true});
|
const {me} = getMinimalMe({readOnly, classReadOnly, isTeacher: true});
|
||||||
return {
|
return {
|
||||||
|
|
@ -18,7 +19,7 @@ const getOperations = ({readOnly, classReadOnly}) => {
|
||||||
RoomEntriesQuery: {
|
RoomEntriesQuery: {
|
||||||
room: {
|
room: {
|
||||||
id: 'roomId',
|
id: 'roomId',
|
||||||
slug: '',
|
slug,
|
||||||
title: 'room title',
|
title: 'room title',
|
||||||
entryCount: 3,
|
entryCount: 3,
|
||||||
appearance: 'blue',
|
appearance: 'blue',
|
||||||
|
|
@ -32,7 +33,7 @@ const getOperations = ({readOnly, classReadOnly}) => {
|
||||||
{
|
{
|
||||||
node: {
|
node: {
|
||||||
id: 'entryId',
|
id: 'entryId',
|
||||||
slug: '',
|
slug: 'room-entry-slug',
|
||||||
title: 'entry title',
|
title: 'entry title',
|
||||||
contents: [],
|
contents: [],
|
||||||
author: {
|
author: {
|
||||||
|
|
@ -58,7 +59,7 @@ const checkRoomReadOnly = ({editable, readOnly, classReadOnly = false}) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const exist = editable ? 'exist' : 'not.exist';
|
const exist = editable ? 'exist' : 'not.exist';
|
||||||
cy.visit('room/some-room');
|
cy.visit(`room/${slug}`);
|
||||||
cy.get('.room-entry').should('exist');
|
cy.get('.room-entry').should('exist');
|
||||||
cy.getByDataCy('add-room-entry-button').should(exist);
|
cy.getByDataCy('add-room-entry-button').should(exist);
|
||||||
cy.getByDataCy('room-actions').should(exist);
|
cy.getByDataCy('room-actions').should(exist);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@ export default {
|
||||||
chapters: [],
|
chapters: [],
|
||||||
topic: {
|
topic: {
|
||||||
title: 'A Topic Mock Title',
|
title: 'A Topic Mock Title',
|
||||||
description: 'A Topic Mock Description'
|
description: 'A Topic Mock Description',
|
||||||
}
|
slug: 'a-topic-slug'
|
||||||
|
},
|
||||||
|
slug: 'a-module-slug',
|
||||||
|
solutionsEnabled: false,
|
||||||
|
bookmark: null,
|
||||||
|
__typename: 'ModuleNode'
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
// todo: reenable with a script that does the mutations, or with a workaround for fetch request checking in cypress
|
|
||||||
describe('Solutions', () => {
|
|
||||||
// todo: mock all the graphql queries and mutations
|
|
||||||
// todo: enable again
|
|
||||||
|
|
||||||
// // it('does not display the solution at first, then displays them after clicking', () => {
|
|
||||||
// // cy.viewport('macbook-15');
|
|
||||||
// // cy.login('ross.geller', 'test');
|
|
||||||
// //
|
|
||||||
// // cy.visit('/module/lohn-und-budget');
|
|
||||||
// // });
|
|
||||||
//
|
|
||||||
it('toggles the solution as teacher, then the student can display it', () => {
|
|
||||||
// cy.exec("python ../server/manage.py hidesolutions");
|
|
||||||
// cy.startGraphQLCapture();
|
|
||||||
// cy.route('POST', '/api/graphql/').as('graphQL');
|
|
||||||
// // does not work with cypress yet, because of the fetch api
|
|
||||||
// // https://github.com/cypress-io/cypress/issues/95
|
|
||||||
// // cy.get('[data-cy=toggle-enable-solutions]').within(() => {
|
|
||||||
// // cy.get('input[type=checkbox]').uncheck({force: true});
|
|
||||||
// // // cy.wait(2000);
|
|
||||||
// // cy.wait('@graphQL');
|
|
||||||
// // });
|
|
||||||
// // cy.logout();
|
|
||||||
// cy.viewport('macbook-15');
|
|
||||||
//
|
|
||||||
// cy.visit('/module/lohn-und-budget');
|
|
||||||
// cy.login('rachel.green', 'test');
|
|
||||||
// cy.get('[data-cy=module-title]').should('be.visible');
|
|
||||||
// cy.get('[data-cy=toggle-enable-solutions]')
|
|
||||||
// .should('not.exist');
|
|
||||||
// cy.get('[data-cy=solution]').should('not.exist');
|
|
||||||
//
|
|
||||||
// cy.visit('/survey/U3VydmV5Tm9kZTox');
|
|
||||||
//
|
|
||||||
// cy.get('.survey__page').should('exist');
|
|
||||||
// cy.get('[data-cy=solution]').should('not.exist');
|
|
||||||
// cy.get('.close-button').click();
|
|
||||||
//
|
|
||||||
// cy.logout();
|
|
||||||
//
|
|
||||||
// cy.visit('/module/lohn-und-budget');
|
|
||||||
// cy.login('ross.geller, 'test');
|
|
||||||
// cy.get('[data-cy=toggle-enable-solutions]').click();
|
|
||||||
// cy.waitFor('UpdateSolutionVisibility');
|
|
||||||
// cy.get('[data-cy=toggle-enable-solutions]').within(() => {
|
|
||||||
// cy.get('input[type=checkbox]').should('be.checked');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// cy.logout();
|
|
||||||
//
|
|
||||||
// cy.visit('/module/lohn-und-budget');
|
|
||||||
// cy.login('rachel.green', 'test');
|
|
||||||
// // cy.get('[data-cy=solution]').should('exist');
|
|
||||||
// cy.get('[data-cy=solution]').first()
|
|
||||||
// .should('contain', 'anzeigen')
|
|
||||||
// .should('not.contain', 'Lösungssatz')
|
|
||||||
// .then($solution => {
|
|
||||||
// cy.wrap($solution).within(() => {
|
|
||||||
// cy.get('[data-cy=show-solution]').click();
|
|
||||||
// });
|
|
||||||
// cy.wrap($solution)
|
|
||||||
// .should('contain', 'Lösungssatz')
|
|
||||||
// .should('contain', 'ausblenden');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// cy.visit('/survey/U3VydmV5Tm9kZTox');
|
|
||||||
//
|
|
||||||
// cy.get('.survey__page').should('exist');
|
|
||||||
// cy.get('[data-cy=solution]').should('exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
describe('The Login Page', () => {
|
|
||||||
// it('login and redirect to main page', () => {
|
|
||||||
// const username = 'test';
|
|
||||||
// const password = 'test';
|
|
||||||
//
|
|
||||||
// cy.visit('/beta-login');
|
|
||||||
// cy.login(username, password, true);
|
|
||||||
// cy.assertStartPage();
|
|
||||||
// });
|
|
||||||
|
|
||||||
it('user sees error message if username is omitted', () => {
|
|
||||||
const username = '';
|
|
||||||
const password = 'test';
|
|
||||||
|
|
||||||
cy.visit('/beta-login');
|
|
||||||
cy.login(username, password);
|
|
||||||
cy.get('[data-cy=email-local-errors]').contains('E-Mail ist ein Pflichtfeld');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('user sees error message if password is omitted', () => {
|
|
||||||
const username = 'test';
|
|
||||||
const password = '';
|
|
||||||
|
|
||||||
cy.visit('/beta-login');
|
|
||||||
cy.login(username, password);
|
|
||||||
cy.get('[data-cy=password-local-errors]').contains('Passwort ist ein Pflichtfeld');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('user sees error message if credentials are invalid', () => {
|
|
||||||
const username = 'test';
|
|
||||||
const password = '12345';
|
|
||||||
|
|
||||||
cy.visit('/beta-login');
|
|
||||||
cy.login(username, password);
|
|
||||||
cy.get('[data-cy=login-error]').contains('Die E-Mail oder das Passwort ist falsch. Bitte versuchen Sie nochmals.');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('logs out then logs in again', () => {
|
|
||||||
const user = 'rachel.green';
|
|
||||||
const pw = 'test';
|
|
||||||
|
|
||||||
cy.viewport('macbook-15');
|
|
||||||
cy.apolloLogin(user, pw);
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
cy.get('[data-cy=header-user-widget]').should('exist').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').should('exist').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('[data-cy=logout]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=oauth-login]').should('exist').within(() => {
|
|
||||||
cy.visit('/beta-login');
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.login(user, pw);
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').should('exist').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').should('exist').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('.profile-sidebar').should('be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import { GraphQLError } from 'graphql';
|
|
||||||
import {assertStartPage} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const schema = require('../../../fixtures/schema.json');
|
|
||||||
|
|
||||||
const redeemCoupon = coupon => {
|
|
||||||
if (coupon !== '') {
|
|
||||||
cy.get('[data-cy="coupon-input"]').type(coupon);
|
|
||||||
}
|
|
||||||
cy.get('[data-cy="coupon-button"]').click();
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Email Verification', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.server();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('forwards to homepage if confirmation key is correct', () => {
|
|
||||||
cy.viewport('macbook-15');
|
|
||||||
cy.mockGraphql({
|
|
||||||
schema: schema,
|
|
||||||
operations: {
|
|
||||||
Coupon: {
|
|
||||||
coupon: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cy.apolloLogin('rachel.green', 'test');
|
|
||||||
|
|
||||||
cy.visit('/license-activation');
|
|
||||||
redeemCoupon('12345asfd');
|
|
||||||
assertStartPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays error if input is missing', () => {
|
|
||||||
cy.viewport('macbook-15');
|
|
||||||
cy.apolloLogin('rachel.green', 'test');
|
|
||||||
|
|
||||||
cy.visit('/license-activation');
|
|
||||||
redeemCoupon('');
|
|
||||||
cy.get('[data-cy="coupon-local-errors"]').contains('Coupon-Code ist ein Pflichtfeld');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays error if coupon input is wrong', () => {
|
|
||||||
cy.viewport('macbook-15');
|
|
||||||
cy.mockGraphql({
|
|
||||||
schema: schema,
|
|
||||||
operations: {
|
|
||||||
Coupon: new GraphQLError('invalid_coupon')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cy.apolloLogin('rachel.green', 'test');
|
|
||||||
|
|
||||||
cy.visit('/license-activation');
|
|
||||||
redeemCoupon('12345asfd');
|
|
||||||
cy.get('[data-cy="coupon-remote-errors"]').contains('Der angegebene Coupon-Code ist ungültig.');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays error if an error occures', () => {
|
|
||||||
cy.viewport('macbook-15');
|
|
||||||
cy.mockGraphql({
|
|
||||||
schema: schema,
|
|
||||||
operations: {
|
|
||||||
Coupon: new GraphQLError('unknown_error')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cy.apolloLogin('rachel.green', 'test');
|
|
||||||
|
|
||||||
cy.visit('/license-activation');
|
|
||||||
redeemCoupon('12345asfd');
|
|
||||||
cy.get('[data-cy="coupon-remote-errors"]').contains('Es ist ein Fehler aufgetreten. Bitte versuchen Sie es nochmals oder kontaktieren Sie den Administrator.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
describe('Assignments', () => {
|
|
||||||
const studentSubmission = {
|
|
||||||
id: 'submission-id',
|
|
||||||
text: '',
|
|
||||||
document: '',
|
|
||||||
assignment: {},
|
|
||||||
submissionFeedback: {
|
|
||||||
id: 'feedback-id',
|
|
||||||
text: '',
|
|
||||||
final: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
ModulesQuery: {},
|
|
||||||
AssignmentWithSubmissions: {
|
|
||||||
assignment: {
|
|
||||||
title: 'Ein Auftragstitel',
|
|
||||||
solution: '<p>Eine Lösung</p>',
|
|
||||||
assignment: '<p>Ein <b>Auftrag</b></p>',
|
|
||||||
submissions: [studentSubmission],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MeQuery: {
|
|
||||||
me: {},
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {},
|
|
||||||
StudentSubmissions: {
|
|
||||||
studentSubmission,
|
|
||||||
},
|
|
||||||
UpdateSubmissionFeedback({input: {submissionFeedback}}) {
|
|
||||||
return {
|
|
||||||
updateSubmissionFeedback: {
|
|
||||||
successful: true,
|
|
||||||
updatedSubmissionFeedback: submissionFeedback,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('it does not display HTML tags', () => {
|
|
||||||
cy.visit('/module/lohn-und-budget/submissions/QXNzaWdubWVudE5vZGU6MQ==');
|
|
||||||
cy.getByDataCy('assignment-main-text').should('have.text', 'Ein Auftrag');
|
|
||||||
cy.getByDataCy('assignment-solution').should('have.text', 'Eine Lösung');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('gives feedback as teacher (with Emojis 🧐)', () => {
|
|
||||||
const finalText = 'This is a feedback 🖐️';
|
|
||||||
cy.visit('/submission/submission-id');
|
|
||||||
cy.getByDataCy('submission-textarea').type('This is a feedback ');
|
|
||||||
cy.getByDataCy('emoji-button').should('have.length', 9).first().click();
|
|
||||||
cy.getByDataCy('submission-textarea').should('have.value', finalText);
|
|
||||||
cy.getByDataCy('submission-form-submit').click();
|
|
||||||
cy.getByDataCy('submission-form-submit').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,194 +0,0 @@
|
||||||
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,
|
|
||||||
slug: 'my-module-slug',
|
|
||||||
chapters: [
|
|
||||||
{
|
|
||||||
title: 'My super Chapter',
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Das folgende Interview'
|
|
||||||
},
|
|
||||||
id: "df8212ee-3e82-49fa-977e-c4b60789163e"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
InstrumentQuery: {
|
|
||||||
instrument: {
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Hallo Sam'
|
|
||||||
},
|
|
||||||
id: "df8212ee-3e82-49fa-977e-c4b60789163e"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpdateLastModule: {},
|
|
||||||
UpdateContentBookmark: {
|
|
||||||
updateContentBookmark: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpdateModuleBookmark: {
|
|
||||||
updateModuleBookmark: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpdateInstrumentBookmark: {
|
|
||||||
updateModuleBookmark: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpdateChapterBookmark: {
|
|
||||||
updateChapterBookmark: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
AddNote: ({input: {note}}) => ({
|
|
||||||
addNote: {
|
|
||||||
note
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
UpdateNote: ({input: {note}}) => ({
|
|
||||||
updateNote: {
|
|
||||||
note
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should bookmark instrument', () => {
|
|
||||||
cy.visit('/instrument/an-instrument');
|
|
||||||
|
|
||||||
cy.getByDataCy('content-component').first().as('contentComponent');
|
|
||||||
|
|
||||||
cy.get('@contentComponent').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('@contentComponent').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();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should bookmark module', () => {
|
|
||||||
cy.visit('/module/lohn-und-budget/');
|
|
||||||
cy.getByDataCy('module-bookmark-actions').as('moduleBookmark');
|
|
||||||
|
|
||||||
cy.get('@moduleBookmark').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('@moduleBookmark').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 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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
describe('Instruments Page', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('opens the instruments page', () => {
|
|
||||||
// cy.mockGraphqlOps({
|
|
||||||
// operations: {
|
|
||||||
// MeQuery: {},
|
|
||||||
// InstrumentQuery: {
|
|
||||||
// instrument: {
|
|
||||||
// title: 'A Guitar',
|
|
||||||
// intro: 'Money for Nothing',
|
|
||||||
// contents: ''
|
|
||||||
// // id: ID!
|
|
||||||
// // bookmarks: [InstrumentBookmarkNode]
|
|
||||||
// // type: InstrumentTypeNode
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
cy.visit('instrument/blabliblablub');
|
|
||||||
|
|
||||||
cy.getByDataCy('instrument-title').should('exist').should('contain', 'A Guitar');
|
|
||||||
cy.getByDataCy('instrument-intro').should('exist').should('contain', 'Money for Nothing');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
const LANGUAGE_COMMUNICATION = 'LANGUAGE_COMMUNICATION';
|
|
||||||
const LANGUAGE_COMMUNICATION_VALUE = 'Sprache & Kommunikation';
|
|
||||||
const SOCIETY = 'SOCIETY';
|
|
||||||
const SOCIETY_VALUE = 'Gesellschaft';
|
|
||||||
const INTERDISCIPLINARY = 'INTERDISCIPLINARY';
|
|
||||||
const INTERDISCIPLINARY_VALUE = 'Überfachliche Instrumente';
|
|
||||||
|
|
||||||
describe('Instruments Page', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
|
|
||||||
|
|
||||||
const languageCategory = {
|
|
||||||
name: LANGUAGE_COMMUNICATION_VALUE,
|
|
||||||
id: LANGUAGE_COMMUNICATION,
|
|
||||||
foreground: '#000000',
|
|
||||||
background: '#00ffff',
|
|
||||||
};
|
|
||||||
const societyCategory = {
|
|
||||||
name: SOCIETY_VALUE,
|
|
||||||
id: SOCIETY,
|
|
||||||
foreground: '#ffffff',
|
|
||||||
background: '#000fff',
|
|
||||||
};
|
|
||||||
const ANALYSE = 'analyse';
|
|
||||||
const ARGUMENTATION = 'argumentation';
|
|
||||||
const ETHIK = 'ethik';
|
|
||||||
|
|
||||||
const analyse = {
|
|
||||||
name: 'Analyse',
|
|
||||||
category: languageCategory,
|
|
||||||
type: ANALYSE,
|
|
||||||
id: ANALYSE
|
|
||||||
};
|
|
||||||
|
|
||||||
const argumentation = {
|
|
||||||
name: 'Argumentation',
|
|
||||||
category: languageCategory,
|
|
||||||
type: ARGUMENTATION,
|
|
||||||
id: ARGUMENTATION
|
|
||||||
};
|
|
||||||
|
|
||||||
const ethik = {
|
|
||||||
name: 'Ethik',
|
|
||||||
category: societyCategory,
|
|
||||||
type: ETHIK,
|
|
||||||
id: ETHIK
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {},
|
|
||||||
InstrumentsQuery: {
|
|
||||||
instruments: [
|
|
||||||
{
|
|
||||||
type: analyse,
|
|
||||||
title: 'Instrument: Analyse',
|
|
||||||
slug: 'analyse',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: argumentation,
|
|
||||||
title: 'Instrument: Argumentation',
|
|
||||||
slug: 'argumentation',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: ethik,
|
|
||||||
title: 'Instrument: Ethik',
|
|
||||||
slug: 'ethik',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
InstrumentCategoriesQuery: {
|
|
||||||
instrumentCategories: [
|
|
||||||
{
|
|
||||||
name: 'Sprache & Kommunikation',
|
|
||||||
id: LANGUAGE_COMMUNICATION,
|
|
||||||
types: [
|
|
||||||
analyse,
|
|
||||||
argumentation,
|
|
||||||
{
|
|
||||||
name: 'Beschreibung',
|
|
||||||
category: languageCategory,
|
|
||||||
type: 'beschreibung',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: SOCIETY_VALUE,
|
|
||||||
id: SOCIETY,
|
|
||||||
types: [
|
|
||||||
ethik,
|
|
||||||
{
|
|
||||||
name: 'Identität und Sozialisation',
|
|
||||||
category: societyCategory,
|
|
||||||
type: 'identitt-und-sozialisation',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: INTERDISCIPLINARY_VALUE,
|
|
||||||
id: INTERDISCIPLINARY,
|
|
||||||
types: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('opens the instruments page', () => {
|
|
||||||
cy.visit('instruments/');
|
|
||||||
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 3);
|
|
||||||
|
|
||||||
cy.contains(LANGUAGE_COMMUNICATION_VALUE).click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 2);
|
|
||||||
|
|
||||||
cy.contains(SOCIETY_VALUE).click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.contains(INTERDISCIPLINARY_VALUE).click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 0);
|
|
||||||
|
|
||||||
cy.contains('Analyse').click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.contains('Ethik').click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.getByDataCy('filter-all-instruments').click();
|
|
||||||
cy.getByDataCy('instrument').should('have.length', 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the correct instrument label', () => {
|
|
||||||
cy.visit('instruments/');
|
|
||||||
cy.getByDataCy('instrument').first().within(() => {
|
|
||||||
cy.getByDataCy('instrument-subheader').should('contain', 'Instrumente - Sprache & Kommunikation');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
import minimalModule from '../../../fixtures/module.minimal';
|
|
||||||
|
|
||||||
const {me: minimalMe} = getMinimalMe({});
|
|
||||||
|
|
||||||
describe('Instruments on Module page', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
console.log('setting up');
|
|
||||||
cy.setup();
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
UpdateLastModule: {
|
|
||||||
updateLastModule: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MeQuery: {
|
|
||||||
me: minimalMe,
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {
|
|
||||||
...minimalModule,
|
|
||||||
slug: 'module-with-instrument',
|
|
||||||
chapters: [
|
|
||||||
{
|
|
||||||
title: 'Some Chapter',
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
'type': 'instrument',
|
|
||||||
instrumentCategory: {
|
|
||||||
id: 'category-id',
|
|
||||||
name: 'Sprache & Kommunikation'
|
|
||||||
},
|
|
||||||
'title': 'Das Interview',
|
|
||||||
'contents': [
|
|
||||||
{
|
|
||||||
'type': 'basic_knowledge',
|
|
||||||
'value': {
|
|
||||||
'description': '<p>Ein Interview dient dazu, durch Befragung Informationen zu ermitteln. Bei journalistischen Interviews werden oft Expertinnen und Experten befragt, aber auch Personen.</p>',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'type': 'normal',
|
|
||||||
'title': 'Normaler Block',
|
|
||||||
instrumentCategory: null,
|
|
||||||
'contents': [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Some text, not an instrument'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('shows the correct instrument label', () => {
|
|
||||||
cy.visit('module/module-with-instrument');
|
|
||||||
cy.getByDataCy('content-block').first().within(() => {
|
|
||||||
cy.getByDataCy('instrument-label').should('contain', 'Instrumente - Sprache & Kommunikation');
|
|
||||||
});
|
|
||||||
cy.getByDataCy('content-block').eq(1).within(() => {
|
|
||||||
cy.getByDataCy('instrument-label').should('not.exist');
|
|
||||||
});
|
|
||||||
// also check that other content blocks don't have the label
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
import {getModules, getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('Apply module visibility', () => {
|
|
||||||
const schoolClasses = [
|
|
||||||
{
|
|
||||||
name: 'FLID2018a',
|
|
||||||
id: btoa('SchoolClassNode:1')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Andere Klasse',
|
|
||||||
id: btoa('SchoolClassNode:2')
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const {me: minimalMe} = getMinimalMe({});
|
|
||||||
const me = {
|
|
||||||
...minimalMe,
|
|
||||||
schoolClasses
|
|
||||||
};
|
|
||||||
// name: '[\'FLID2018a\', \'Andere Klasse\']'
|
|
||||||
const operations = {
|
|
||||||
MeQuery: {
|
|
||||||
me
|
|
||||||
},
|
|
||||||
ModulesQuery: getModules,
|
|
||||||
UpdateSettings: {
|
|
||||||
updateSettings: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me,
|
|
||||||
},
|
|
||||||
UpdateLastModule: {
|
|
||||||
updateLastModule: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SyncModuleVisibility: {
|
|
||||||
syncModuleVisibility: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {
|
|
||||||
id: 'some-module-id'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('clicks through the UI', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations
|
|
||||||
});
|
|
||||||
|
|
||||||
// go to module
|
|
||||||
cy.visit('/module/lohn-und-budget');
|
|
||||||
cy.selectClass('Andere Klasse');
|
|
||||||
// click on settings
|
|
||||||
cy.getByDataCy('module-settings-button').click();
|
|
||||||
// click on select button
|
|
||||||
cy.getByDataCy('select-school-class-button').click();
|
|
||||||
// select schoolclass
|
|
||||||
cy.getByDataCy('school-class-visibility-dropdown').select('FLID2018a');
|
|
||||||
// save changes
|
|
||||||
cy.getByDataCy('save-visibility-button').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
// const operations = {
|
|
||||||
// MeQuery: getMinimalMe({isTeacher: false}),
|
|
||||||
// };
|
|
||||||
const MeQuery = getMinimalMe();
|
|
||||||
|
|
||||||
describe('Content Blocks', () => {
|
|
||||||
const slug = 'some-module';
|
|
||||||
const assignment = {
|
|
||||||
id: 'abc',
|
|
||||||
title: 'Some assignment',
|
|
||||||
assignment: 'Please write down your thoughts',
|
|
||||||
submission: null,
|
|
||||||
};
|
|
||||||
const module = {
|
|
||||||
title: 'Hello world',
|
|
||||||
slug,
|
|
||||||
solutionsEnabled: false,
|
|
||||||
chapters: [{
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
title: 'A content block',
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Ein Text',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'assignment',
|
|
||||||
value: assignment,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
const operations = {
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module,
|
|
||||||
},
|
|
||||||
MeQuery,
|
|
||||||
ModuleEditModeQuery: {
|
|
||||||
module: {
|
|
||||||
slug,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateLastModule: {
|
|
||||||
module,
|
|
||||||
},
|
|
||||||
AssignmentQuery: {
|
|
||||||
assignment,
|
|
||||||
},
|
|
||||||
UpdateAssignmentWithSuccess: {
|
|
||||||
updateAssignment: {
|
|
||||||
successful: true,
|
|
||||||
updatedAssignment: assignment
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
cy.mockGraphqlOps({operations});
|
|
||||||
cy.visit(`module/${slug}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('types into the assignment input', () => {
|
|
||||||
cy.getByDataCy('submission-textarea').should('exist').type('My Solution');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not see assignment input on mobile', () => {
|
|
||||||
cy.viewport('iphone-8');
|
|
||||||
cy.getByDataCy('submission-textarea').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const MeQuery = getMinimalMe();
|
|
||||||
|
|
||||||
describe('Create Content Block', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery,
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {},
|
|
||||||
},
|
|
||||||
AddContentBlock: {
|
|
||||||
addContentBlock: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('visits the page', () => {
|
|
||||||
// todo:
|
|
||||||
// add mocks
|
|
||||||
cy.visit('/module/some-module/add-after/bliblablub');
|
|
||||||
// add title
|
|
||||||
cy.getByDataCy('content-block-form-heading').should('exist');
|
|
||||||
cy.getByDataCy('content-list').should('not.exist');
|
|
||||||
cy.getByDataCy('save-button').should('exist').should('be.disabled');
|
|
||||||
cy.getByDataCy('content-block-title').within(() => {
|
|
||||||
cy.getByDataCy('input-with-label-input').type('Title of my book');
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.getByDataCy('add-content-link').click();
|
|
||||||
cy.getByDataCy('chooser-heading').should('contain', 'Neuer Inhalt');
|
|
||||||
// add text element
|
|
||||||
cy.getByDataCy('choose-text-widget').click();
|
|
||||||
cy.get('.tip-tap__editor').last().type('Hallo Sam');
|
|
||||||
|
|
||||||
// add list item
|
|
||||||
cy.getByDataCy('add-content-link').last().click();
|
|
||||||
cy.getByDataCy('convert-to-list-checkbox').click();
|
|
||||||
// add text element to list item
|
|
||||||
cy.getByDataCy('choose-text-widget').click();
|
|
||||||
cy.getByDataCy('content-list').within(() => {
|
|
||||||
cy.get('.tip-tap__editor').last().type('Hallo Velo');
|
|
||||||
// add second list item
|
|
||||||
cy.getByDataCy('add-content-link').click();
|
|
||||||
// add text element to second list item
|
|
||||||
cy.getByDataCy('choose-text-widget').click();
|
|
||||||
cy.get('.tip-tap__editor').last().type('Hallo Velo');
|
|
||||||
// add another text element to second list item
|
|
||||||
cy.getByDataCy('add-content-link').last().click();
|
|
||||||
cy.getByDataCy('choose-text-widget').click();
|
|
||||||
cy.get('.tip-tap__editor').last().type('Hallo Outo');
|
|
||||||
});
|
|
||||||
// save
|
|
||||||
cy.getByDataCy('save-button').should('exist').should('not.be.disabled').click();
|
|
||||||
|
|
||||||
// another test
|
|
||||||
// go to page
|
|
||||||
// click cancel, go back
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// todo: another test
|
|
||||||
// edit existing content block
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
const topics = [
|
|
||||||
{
|
|
||||||
id: 'VG9waWNOb2RlOjU=',
|
|
||||||
order: 1,
|
|
||||||
title: 'Geld und Kauf',
|
|
||||||
slug: 'geld-und-kauf',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'VG9waWNOb2RlOjUz',
|
|
||||||
order: 2,
|
|
||||||
title: 'Berufliche Grundbildung',
|
|
||||||
slug: 'berufliche-grundbildung',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let recentModules = [];
|
|
||||||
|
|
||||||
const getId = (id) => btoa(`ModuleNode:${id}`);
|
|
||||||
|
|
||||||
const modules = {
|
|
||||||
[getId(1)]: {
|
|
||||||
title: 'Lohn und Budget',
|
|
||||||
metaTitle: 'Modul 1',
|
|
||||||
slug: 'lohn-und-budget',
|
|
||||||
id: getId(1),
|
|
||||||
},
|
|
||||||
[getId(2)]: {
|
|
||||||
title: 'Geld',
|
|
||||||
metaTitle: 'Modul 2',
|
|
||||||
slug: 'geld',
|
|
||||||
id: getId(2),
|
|
||||||
},
|
|
||||||
[getId(3)]: {
|
|
||||||
title: 'Lerntipps',
|
|
||||||
metaTitle: 'Modul 4',
|
|
||||||
slug: 'lerntipps',
|
|
||||||
id: getId(3),
|
|
||||||
},
|
|
||||||
[getId(4)]: {
|
|
||||||
title: 'Random',
|
|
||||||
metaTitle: 'Modul 5',
|
|
||||||
slug: 'random',
|
|
||||||
id: getId(4),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const slugs = {
|
|
||||||
'lohn-und-budget': getId(1),
|
|
||||||
'geld': getId(2),
|
|
||||||
'lerntipps': getId(3),
|
|
||||||
'random': getId(4),
|
|
||||||
};
|
|
||||||
|
|
||||||
const getModuleBySlug = (slug) => {
|
|
||||||
console.log('getModuleBySlug', slug);
|
|
||||||
const id = slugs[slug];
|
|
||||||
console.log(id);
|
|
||||||
return modules[id];
|
|
||||||
};
|
|
||||||
|
|
||||||
const moduleNodes = Object.values(modules).map(module => ({
|
|
||||||
node: module,
|
|
||||||
}));
|
|
||||||
console.log(moduleNodes);
|
|
||||||
|
|
||||||
const getTopic = () => {
|
|
||||||
console.info('calling getTopic');
|
|
||||||
return {
|
|
||||||
topic: {
|
|
||||||
title: 'Geld und Kauf',
|
|
||||||
id: 'VG9waWNOb2RlOjU=',
|
|
||||||
teaser: 'Topic 2',
|
|
||||||
modules: {
|
|
||||||
edges: moduleNodes,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkHome = (n, skipHome) => {
|
|
||||||
cy.log(`Checking if home has ${n} teasers`);
|
|
||||||
if (!skipHome) {
|
|
||||||
cy.get('[data-cy="home-link"]').click();
|
|
||||||
}
|
|
||||||
cy.get('[data-cy=start-modules-list]').should('exist');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').should('have.length', n);
|
|
||||||
};
|
|
||||||
|
|
||||||
const goToModule = (topicTitle, moduleMetaTitle) => {
|
|
||||||
cy.log(`Going to module ${moduleMetaTitle} in topic ${topicTitle}`);
|
|
||||||
cy.get('[data-cy=open-sidebar-link]').click();
|
|
||||||
cy.contains(topicTitle).click();
|
|
||||||
cy.get('[data-cy=topic-title]').should('exist').should('contain', topicTitle);
|
|
||||||
cy.contains(moduleMetaTitle).click();
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Current Module', () => {
|
|
||||||
const me = {
|
|
||||||
lastModule: {
|
|
||||||
slug: 'lohn-und-budget',
|
|
||||||
id: 'last-module-id',
|
|
||||||
},
|
|
||||||
lastTopic: {
|
|
||||||
id: 'VG9waWNOb2RlOjU=',
|
|
||||||
slug: 'geld-und-kauf',
|
|
||||||
},
|
|
||||||
recentModules: {
|
|
||||||
edges: recentModules,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery: {
|
|
||||||
me,
|
|
||||||
},
|
|
||||||
AssignmentsQuery: {
|
|
||||||
assignments: [],
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: variables => {
|
|
||||||
console.log('calling ModuleDetailsQuery', getModuleBySlug(variables.slug));
|
|
||||||
return {
|
|
||||||
module: getModuleBySlug(variables.slug)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
TopicsQuery: {
|
|
||||||
topics: {
|
|
||||||
edges: topics.map(topic => ({node: topic})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Topic: getTopic(),
|
|
||||||
UpdateLastTopic: () => {
|
|
||||||
const Topic = getTopic();
|
|
||||||
const topic = Topic.topic;
|
|
||||||
return {
|
|
||||||
updateLastTopic: {
|
|
||||||
topic,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
NewsTeasers: {
|
|
||||||
newsTeasers: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateLastModule: ({input: {id}}) => {
|
|
||||||
const lastModule = modules[id];
|
|
||||||
return {
|
|
||||||
updateLastModule: {
|
|
||||||
lastModule,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.skip('is set correctly', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
// module list exists, but does not have anything in it
|
|
||||||
checkHome(0, true);
|
|
||||||
cy.get('[data-cy=no-modules-yet]').should('exist').should('contain', 'Sie haben sich noch kein Modul angeschaut. Legen Sie jetzt los!');
|
|
||||||
|
|
||||||
goToModule('Geld und Kauf', 'Modul 2');
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Geld');
|
|
||||||
checkHome(1);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
|
|
||||||
|
|
||||||
goToModule('Geld und Kauf', 'Modul 1');
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
|
||||||
checkHome(2);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lohn und Budget');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
|
|
||||||
|
|
||||||
goToModule('Geld und Kauf', 'Modul 4');
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
|
|
||||||
checkHome(3);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lohn und Budget');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
|
|
||||||
|
|
||||||
// module list is full, should switch only the order around
|
|
||||||
goToModule('Geld und Kauf', 'Modul 2');
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Geld');
|
|
||||||
checkHome(3);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lerntipps');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lohn und Budget');
|
|
||||||
|
|
||||||
goToModule('Geld und Kauf', 'Modul 5');
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Random');
|
|
||||||
checkHome(3);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Random');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lerntipps');
|
|
||||||
|
|
||||||
cy.get('[data-cy=start-module-teaser]').last().click();
|
|
||||||
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
|
|
||||||
checkHome(3);
|
|
||||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Random');
|
|
||||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import module from '../../../fixtures/module.minimal';
|
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const chapters = [{
|
|
||||||
title: 'ABC',
|
|
||||||
description: 'DEF',
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
title: 'A ContentBlock',
|
|
||||||
userCreated: true,
|
|
||||||
mine: true,
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Hello World'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}];
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery: getMinimalMe({isTeacher: true}),
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {
|
|
||||||
chapters,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ModuleEditModeQuery: {
|
|
||||||
module: {
|
|
||||||
slug: 'some-module',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DeleteContentBlock: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
UpdateLastModule: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Custom Content Block', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: fix this test
|
|
||||||
it.skip('Deletes the custom content block and removes it from the view', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('module/some-module');
|
|
||||||
|
|
||||||
cy.log('Toggling Edit Mode');
|
|
||||||
cy.getByDataCy('toggle-editing').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('exist');
|
|
||||||
cy.get('.content-block').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.log('Opening More Menu');
|
|
||||||
cy.getByDataCy('more-options-link').click();
|
|
||||||
|
|
||||||
cy.log('Duplicating Content Block');
|
|
||||||
cy.getByDataCy('duplicate-content-block-link').click();
|
|
||||||
|
|
||||||
cy.get('.content-block').should('have.length', 2);
|
|
||||||
|
|
||||||
cy.log('Opening More Menu');
|
|
||||||
cy.getByDataCy('more-options-link').click();
|
|
||||||
|
|
||||||
// check if content block is still there
|
|
||||||
cy.log('Deleting Content Block');
|
|
||||||
cy.getByDataCy('delete-content-block-link').click();
|
|
||||||
|
|
||||||
cy.get('.content-block').should('have.length', 0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
import module from '../../../fixtures/module.minimal';
|
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
import {hasOperationName} from '../../../support/graphql';
|
|
||||||
|
|
||||||
const mockDeleteSnapshot = (success) => {
|
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
|
||||||
if (hasOperationName(req, 'DeleteSnapshot')) {
|
|
||||||
let result;
|
|
||||||
if (success) {
|
|
||||||
result = {
|
|
||||||
message: 'yay!',
|
|
||||||
__typename: 'Success'
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
result = {
|
|
||||||
reason: 'Not the owner',
|
|
||||||
__typename: 'NotOwner'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
req.reply({
|
|
||||||
data: {
|
|
||||||
deleteSnapshot: {
|
|
||||||
result
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockUpdateSnapshot = (title) => {
|
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
|
||||||
if (hasOperationName(req, 'UpdateSnapshot')) {
|
|
||||||
let snapshot;
|
|
||||||
if (title) {
|
|
||||||
snapshot = {
|
|
||||||
__typename: 'SnapshotNode',
|
|
||||||
id: 'U25hcHNob3ROb2RlOjQ=',
|
|
||||||
title,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
snapshot = {
|
|
||||||
__typename: 'NotOwner',
|
|
||||||
reason: 'Not the owner'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
req.reply({
|
|
||||||
data: {
|
|
||||||
updateSnapshot: {
|
|
||||||
snapshot,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
describe('Snapshot', () => {
|
|
||||||
const operations = isTeacher => ({
|
|
||||||
operations: {
|
|
||||||
MeQuery: getMinimalMe({isTeacher}),
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module,
|
|
||||||
},
|
|
||||||
CreateSnapshot: {
|
|
||||||
createSnapshot: {
|
|
||||||
snapshot: {
|
|
||||||
id: '',
|
|
||||||
title: '',
|
|
||||||
created: '',
|
|
||||||
creator: '',
|
|
||||||
},
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateLastModule: {},
|
|
||||||
ModuleSnapshotsQuery: {
|
|
||||||
module: {
|
|
||||||
...module,
|
|
||||||
snapshots: [
|
|
||||||
{
|
|
||||||
id: 'U25hcHNob3ROb2RlOjQ=',
|
|
||||||
title: 'Old Title',
|
|
||||||
created: '2020-01-01',
|
|
||||||
mine: true,
|
|
||||||
shared: false,
|
|
||||||
creator: 'me',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'U25hcHNob3ROb2RlOjU=',
|
|
||||||
title: 'Shared snapshot',
|
|
||||||
created: '2020-01-02',
|
|
||||||
mine: false,
|
|
||||||
shared: true,
|
|
||||||
creator: 'someone else',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SnapshotDetail: {
|
|
||||||
snapshot: {
|
|
||||||
chapters: [],
|
|
||||||
module: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ApplySnapshot: {
|
|
||||||
applySnapshot: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Menu is visible for teacher', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
cy.visit('module/miteinander-reden/');
|
|
||||||
cy.getByDataCy('snapshot-menu').should('be.visible');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Menu is not visible for student', () => {
|
|
||||||
cy.mockGraphqlOps(operations(false));
|
|
||||||
cy.visit('module/miteinander-reden/');
|
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('be.visible');
|
|
||||||
cy.getByDataCy('snapshot-menu').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Creates Snapshot', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
cy.visit('module/miteinander-reden/');
|
|
||||||
cy.getByDataCy('module-snapshots-button').click();
|
|
||||||
cy.getByDataCy('create-snapshot-button').click();
|
|
||||||
cy.getByDataCy('show-all-snapshots-button').click();
|
|
||||||
cy.getByDataCy('snapshot-list').should('exist').within(() => {
|
|
||||||
cy.get('.snapshots__snapshot').should('have.length', 1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Applies Snapshot', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
|
||||||
cy.getByDataCy('snapshot-link').click();
|
|
||||||
cy.getByDataCy('apply-checkbox').click();
|
|
||||||
cy.getByDataCy('apply-button').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('module-title').should('exist');
|
|
||||||
cy.getByDataCy('snapshot-header').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Renames Snapshot', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
const newTitle = 'New Title';
|
|
||||||
mockUpdateSnapshot(newTitle);
|
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
|
|
||||||
cy.getByDataCy('rename-snapshot-button').click();
|
|
||||||
cy.getByDataCy('edit-name-input').clear().type(newTitle);
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'New Title');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Deletes Snapshot', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
mockDeleteSnapshot(true);
|
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('delete-snapshot-button').click();
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Displays the Snapshot list correcly', () => {
|
|
||||||
cy.mockGraphqlOps(operations(true));
|
|
||||||
cy.visit('module/miteinander-reden/snapshots');
|
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('delete-snapshot-button').should('exist');
|
|
||||||
cy.getByDataCy('rename-snapshot-button').should('exist');
|
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'Old Title');
|
|
||||||
cy.getByDataCy('team-snapshots-link').click();
|
|
||||||
cy.getByDataCy('snapshot-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('snapshot-link').should('have.text', 'Shared snapshot');
|
|
||||||
cy.getByDataCy('delete-snapshot-button').should('not.exist');
|
|
||||||
cy.getByDataCy('rename-snapshot-button').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
import {getMe} from '../../../support/helpers';
|
|
||||||
import mocks from '../../../fixtures/mocks';
|
|
||||||
|
|
||||||
const modules = {
|
|
||||||
'lohn-und-budget': {
|
|
||||||
'objectiveGroups': {
|
|
||||||
'edges': [
|
|
||||||
{
|
|
||||||
'node': {
|
|
||||||
'title': 'LANGUAGE_COMMUNICATION',
|
|
||||||
'objectives': {
|
|
||||||
'edges': [
|
|
||||||
{
|
|
||||||
'node': {
|
|
||||||
'text': 'i-am-an-objective',
|
|
||||||
'hiddenFor': {
|
|
||||||
'edges': [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery() {
|
|
||||||
return getMe({
|
|
||||||
schoolClasses: ['FLID2018a'],
|
|
||||||
teacher: false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
ModulesQuery: modules,
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: {},
|
|
||||||
},
|
|
||||||
UpdateLastModule: {
|
|
||||||
updateLastModule: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SyncModuleVisibility: {
|
|
||||||
syncModuleVisibility: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// const mocks = {
|
|
||||||
// UUID: () => 'Whatever',
|
|
||||||
// GenericStreamFieldType: () => [],
|
|
||||||
// ObjectiveGroup: () => ({}),
|
|
||||||
// Module: () => ({
|
|
||||||
// title: 'title',
|
|
||||||
// slug: 'slug',
|
|
||||||
// metaTitle: 'metaTitle',
|
|
||||||
// teaser: 'teaser',
|
|
||||||
// intro: 'intro',
|
|
||||||
// assignments: {edges: []},
|
|
||||||
// objectiveGroups: {edges: []},
|
|
||||||
// id: 'ID',
|
|
||||||
// }),
|
|
||||||
// };
|
|
||||||
|
|
||||||
describe('Objective Visibility', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.server();
|
|
||||||
cy.task('getSchema').then(schema => {
|
|
||||||
cy.mockGraphql({
|
|
||||||
schema,
|
|
||||||
// endpoint: '/api/graphql'
|
|
||||||
mocks,
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//todo: finish writing this test, this does nothing
|
|
||||||
it.skip('should display the correct objectives', () => {
|
|
||||||
cy.fakeLogin('rachel.green', 'test');
|
|
||||||
|
|
||||||
cy.visit('/module/lohn-und-budget');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('New project', () => {
|
|
||||||
const MeQuery = getMinimalMe({isTeacher: false});
|
|
||||||
const schoolClass = MeQuery.me.selectedClass;
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
id: 'UHJvamVjdE5vZGU6NjY=',
|
|
||||||
title: 'Some random title',
|
|
||||||
appearance: 'blue',
|
|
||||||
description: 'This description rocks',
|
|
||||||
slug: 'some-random-title',
|
|
||||||
objectives: 'Git gud',
|
|
||||||
final: false,
|
|
||||||
schoolClass,
|
|
||||||
student: {
|
|
||||||
firstName: 'Rachel',
|
|
||||||
lastName: 'Green',
|
|
||||||
id: 'VXNlck5vZGU6NQ==',
|
|
||||||
avatarUrl: '',
|
|
||||||
},
|
|
||||||
entriesCount: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
MeQuery,
|
|
||||||
AddProject: variables => ({
|
|
||||||
addProject: {
|
|
||||||
project: Object.assign({}, variables.input.project, {schoolClass}),
|
|
||||||
errors: null,
|
|
||||||
__typename: 'AddProjectPayload',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('creates a new project and displays it', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
|
|
||||||
cy.get('[data-cy=create-project-button]').click();
|
|
||||||
cy.get('[data-cy=page-form-input-titel]').type('Some random title');
|
|
||||||
cy.get('[data-cy=page-form-input-beschreibung]').should('exist').should('be.empty');
|
|
||||||
cy.get('[data-cy=page-form-input-ziele]').should('not.exist');
|
|
||||||
cy.get('[data-cy=save-project-button]').click();
|
|
||||||
cy.getByDataCy('project').contains('random');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,255 +0,0 @@
|
||||||
import {PROJECT_ENTRY_TEMPLATE} from '../../../../src/consts/strings.consts';
|
|
||||||
|
|
||||||
const created = '2021-06-01T11:49:00+00:00';
|
|
||||||
const createdLater = '2021-06-01T12:49:00+00:00';
|
|
||||||
const defaultEntries = [
|
|
||||||
{
|
|
||||||
id: 'UHJvamVjdEVudHJ5Tm9kZTo2NQ==',
|
|
||||||
description: 'Aktivität:\nKill Thanos\n\n\nReflexion:\nHe sucks\n\n\nNächste Schritte:\nGo for the head',
|
|
||||||
documentUrl: '',
|
|
||||||
created,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let entries = [...defaultEntries];
|
|
||||||
|
|
||||||
describe('Project Page', () => {
|
|
||||||
let final = false;
|
|
||||||
|
|
||||||
const project = {
|
|
||||||
id: 'UHJvamVjdE5vZGU6MzY=',
|
|
||||||
title: 'Groot',
|
|
||||||
appearance: 'yellow',
|
|
||||||
description: 'I am Groot',
|
|
||||||
slug: 'groot',
|
|
||||||
objectives: 'Be Groot\nBe awesome',
|
|
||||||
final: false,
|
|
||||||
student: {
|
|
||||||
firstName: 'Rachel',
|
|
||||||
lastName: 'Green',
|
|
||||||
id: 'VXNlck5vZGU6NQ==',
|
|
||||||
avatarUrl: '',
|
|
||||||
},
|
|
||||||
entries,
|
|
||||||
entriesCount: entries.length,
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
id: 'VXNlck5vZGU6NQ==',
|
|
||||||
permissions: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
id: 'UHJvamVjdE5vZGU6MzM=',
|
|
||||||
title: 'Groot',
|
|
||||||
appearance: 'red',
|
|
||||||
description: 'I am Groot',
|
|
||||||
slug: 'groot',
|
|
||||||
objectives: 'Be Groot\nBe awesome',
|
|
||||||
final: false,
|
|
||||||
student: {
|
|
||||||
firstName: 'Rachel',
|
|
||||||
lastName: 'Green',
|
|
||||||
id: 'VXNlck5vZGU6NQ==',
|
|
||||||
avatarUrl: '',
|
|
||||||
},
|
|
||||||
entriesCount: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
ProjectQuery: () => ({
|
|
||||||
project,
|
|
||||||
}),
|
|
||||||
DeleteProject: {
|
|
||||||
deleteProject: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
AddProjectEntry: variables => {
|
|
||||||
const projectEntry = Object.assign({}, variables.input.projectEntry, {
|
|
||||||
created: createdLater,
|
|
||||||
});
|
|
||||||
entries.push(projectEntry);
|
|
||||||
return {
|
|
||||||
addProjectEntry: {
|
|
||||||
projectEntry,
|
|
||||||
errors: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
UpdateProjectEntry: variables => ({
|
|
||||||
updateProjectEntry: {
|
|
||||||
projectEntry: variables.input.projectEntry,
|
|
||||||
errors: null,
|
|
||||||
__typename: 'UpdateProjectEntryPayload',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
DeleteProjectEntry: {
|
|
||||||
deleteProjectEntry: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateProjectShareState: () => {
|
|
||||||
final = !final;
|
|
||||||
return {
|
|
||||||
updateProjectSharedState: {
|
|
||||||
errors: null,
|
|
||||||
success: true,
|
|
||||||
shared: final,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
entries = [...defaultEntries];
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has the correct layout', () => {
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.getByDataCy('project-entry').eq(0).within(() => {
|
|
||||||
cy.getByDataCy('project-entry-date').should('contain', '1. Juni 2021');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('uses the menu', () => {
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.getByDataCy('project-actions').click();
|
|
||||||
cy.getByDataCy('delete-project').should('exist');
|
|
||||||
cy.getByDataCy('edit-project').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('deletes the project', () => {
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('project-link').should('have.length', 1);
|
|
||||||
cy.getByDataCy('project-link').click();
|
|
||||||
cy.getByDataCy('project-actions').click();
|
|
||||||
cy.getByDataCy('delete-project').click();
|
|
||||||
cy.getByDataCy('page-title').should('contain', 'Portfolio');
|
|
||||||
cy.getByDataCy('project-link').should('have.length', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shares and unshares the project', () => {
|
|
||||||
const getOperationsForSharing = () => {
|
|
||||||
let projectForSharing = {
|
|
||||||
...project,
|
|
||||||
final,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
...operations,
|
|
||||||
ProjectQuery: {
|
|
||||||
project: projectForSharing,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperationsForSharing,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
const unsharedText = 'Mit Lehrperson teilen';
|
|
||||||
const sharedText = 'Nicht mehr teilen';
|
|
||||||
cy.getByDataCy('project-share-link').should('contain', unsharedText);
|
|
||||||
cy.getByDataCy('project-share-link').click();
|
|
||||||
cy.getByDataCy('project-share-link').should('contain', sharedText);
|
|
||||||
cy.getByDataCy('project-share-link').click();
|
|
||||||
cy.getByDataCy('project-share-link').should('contain', unsharedText);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('cannot edit or delete the project as a teacher', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
...operations,
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
id: 'not-the-same',
|
|
||||||
isTeacher: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.getByDataCy('project-actions').should('not.exist');
|
|
||||||
cy.getByDataCy('project-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('project-entry-more').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show button on mobile', () => {
|
|
||||||
cy.viewport('iphone-8');
|
|
||||||
cy.getByDataCy('project-title').should('exist');
|
|
||||||
cy.getByDataCy('add-project-entry').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Project Entry', () => {
|
|
||||||
it('should create a new project entry', () => {
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.get('[data-cy=project-link]:first-of-type').click();
|
|
||||||
cy.get('[data-cy=add-project-entry]:first-of-type').click();
|
|
||||||
cy.getByDataCy('activity-input').should('not.exist');
|
|
||||||
cy.getByDataCy('reflection-input').should('not.exist');
|
|
||||||
cy.getByDataCy('next-steps-input').should('not.exist');
|
|
||||||
cy.getByDataCy('modal-title').should('contain', 'Beitrag erfassen');
|
|
||||||
cy.getByDataCy('project-entry-textarea').should('exist');
|
|
||||||
cy.getByDataCy('use-template-button').should('exist').click();
|
|
||||||
cy.getByDataCy('upload-document-button').should('exist');
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
|
|
||||||
cy.get('.project-entry:last-of-type').within(() => {
|
|
||||||
cy.get('.project-entry__paragraph:first-of-type').contains('Schwierigkeiten');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should edit first entry', () => {
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.get('.project-entry__paragraph:first-of-type').contains('Kill Thanos');
|
|
||||||
cy.get('.project-entry:first-of-type').within(() => {
|
|
||||||
cy.get('[data-cy=project-entry-more]').click();
|
|
||||||
cy.get('[data-cy=edit-project-entry]').click();
|
|
||||||
});
|
|
||||||
cy.getByDataCy('activity-input').should('not.exist');
|
|
||||||
|
|
||||||
cy.getByDataCy('project-entry-textarea').clear().type('Defeat Thanos');
|
|
||||||
cy.get('[data-cy=modal-save-button]').click();
|
|
||||||
cy.get('.project-entry__paragraph:first-of-type').contains('Defeat Thanos');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should delete the last entry', () => {
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
|
|
||||||
cy.get('.project-entry').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.get('.project-entry:last-of-type').within(() => {
|
|
||||||
cy.get('[data-cy=project-entry-more]').click();
|
|
||||||
cy.get('[data-cy=delete-project-entry]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('.project-entry').should('have.length', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the template', () => {
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.get('[data-cy=add-project-entry]:first-of-type').click();
|
|
||||||
cy.getByDataCy('use-template-button').click();
|
|
||||||
cy.getByDataCy('project-entry-textarea').should('have.value', PROJECT_ENTRY_TEMPLATE);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not display the entry actions on mobile', () => {
|
|
||||||
cy.viewport('iphone-8') ;
|
|
||||||
cy.visit('/portfolio/groot');
|
|
||||||
cy.getByDataCy('project-entry').should('exist');
|
|
||||||
cy.getByDataCy('project-entry-more').should('not.be.visible');
|
|
||||||
cy.getByDataCy('project-actions').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
;
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('Projects page', () => {
|
|
||||||
const MeQuery = getMinimalMe({});
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
cy.intercept('GET', '/avatars/**', {fixture: 'maxim.png'});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays portfolio onboarding', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('page-title').should('contain', 'Portfolio');
|
|
||||||
cy.getByDataCy('portfolio-onboarding-illustration').should('exist');
|
|
||||||
cy.getByDataCy('portfolio-onboarding-subtitle').should('contain', 'Woran denken Sie gerade');
|
|
||||||
cy.getByDataCy('portfolio-onboarding-text').should('contain', 'Hier können Sie Projekte erstellen');
|
|
||||||
cy.getByDataCy('page-footer').should('not.exist');
|
|
||||||
cy.getByDataCy('create-project-button-onboarding').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays the project list', () => {
|
|
||||||
const projectTitle = 'What is love?';
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
title: projectTitle,
|
|
||||||
student: {
|
|
||||||
firstName: 'Bilbo',
|
|
||||||
lastName: 'Baggins',
|
|
||||||
avatarUrl: '/avatars/bilbo.png',
|
|
||||||
},
|
|
||||||
entriesCount: 0,
|
|
||||||
entries: {
|
|
||||||
nodes: [],
|
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('page-title').should('contain', 'Portfolio');
|
|
||||||
cy.getByDataCy('create-project-button').should('exist');
|
|
||||||
cy.getByDataCy('project-list').should('exist');
|
|
||||||
cy.getByDataCy('project').should('have.length', 1);
|
|
||||||
cy.getByDataCy('owner-name').should('contain', 'Bilbo Baggins');
|
|
||||||
cy.getByDataCy('project-title').should('contain', projectTitle);
|
|
||||||
cy.getByDataCy('entry-count').should('contain', 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('creates a new project', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
title: 'first project',
|
|
||||||
student: {
|
|
||||||
firstName: 'Bilbo',
|
|
||||||
lastName: 'Baggins',
|
|
||||||
avatarUrl: '/avatars/bilbo.png',
|
|
||||||
},
|
|
||||||
entriesCount: 0,
|
|
||||||
entries: {
|
|
||||||
nodes: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
AddProject: variables => {
|
|
||||||
const {input: {project}} = variables;
|
|
||||||
return {
|
|
||||||
addProject: {
|
|
||||||
errors: null,
|
|
||||||
project,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
|
|
||||||
cy.getByDataCy('project').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.getByDataCy('create-project-button').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('page-form-input-titel').type('Titel');
|
|
||||||
cy.getByDataCy('page-form-input-beschreibung').type('Beschreibung');
|
|
||||||
cy.getByDataCy('save-project-button').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('project').should('have.length', 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not display button on mobile', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.viewport('iphone-8');
|
|
||||||
|
|
||||||
cy.getByDataCy('page-title').should('exist');
|
|
||||||
cy.getByDataCy('create-project-button').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
const myText = 'Mein Feedback';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly, classReadOnly = false}) => ({
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
readOnly,
|
|
||||||
selectedClass: {
|
|
||||||
id: 'selectedClassId',
|
|
||||||
readOnly: classReadOnly
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
StudentSubmissions: {
|
|
||||||
studentSubmission: {
|
|
||||||
id: 'id',
|
|
||||||
text: 'Submission Text',
|
|
||||||
document: '',
|
|
||||||
student: {
|
|
||||||
firstName: 'Peter',
|
|
||||||
lastName: 'Student',
|
|
||||||
},
|
|
||||||
assignment: {
|
|
||||||
title: 'Assignment Title',
|
|
||||||
assignment: 'Assignment Text',
|
|
||||||
},
|
|
||||||
submissionFeedback: {
|
|
||||||
id: 'feedback-id',
|
|
||||||
text: myText,
|
|
||||||
final: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Assignment feedback read-only - Teacher', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: true}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('submission/submission-id');
|
|
||||||
|
|
||||||
cy.isSubmissionReadOnly(myText);
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can edit', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: false}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('submission/submission-id');
|
|
||||||
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit for inactive class', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: false, classReadOnly: true}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('submission/submission-id');
|
|
||||||
|
|
||||||
cy.isSubmissionReadOnly(myText);
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
import minimalModule from '../../../fixtures/module.minimal';
|
|
||||||
|
|
||||||
const module = {
|
|
||||||
...minimalModule,
|
|
||||||
chapters: [
|
|
||||||
{
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
type: 'task',
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'hallo velo',
|
|
||||||
},
|
|
||||||
id: 'bla-123',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'assignment',
|
|
||||||
value: {
|
|
||||||
title: 'assignment-title',
|
|
||||||
assignment: 'assignment-assignment',
|
|
||||||
id: 'some-assignment',
|
|
||||||
},
|
|
||||||
id: '123-456',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const myText = 'submission text';
|
|
||||||
|
|
||||||
const getOperations = ({final, readOnly, classReadOnly = false}) => ({
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
readOnly,
|
|
||||||
selectedClass: {
|
|
||||||
id: 'selectedClassId',
|
|
||||||
readOnly: classReadOnly
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module,
|
|
||||||
},
|
|
||||||
UpdateLastModule: {},
|
|
||||||
AssignmentQuery: {
|
|
||||||
assignment: {
|
|
||||||
submission: {
|
|
||||||
text: myText,
|
|
||||||
final,
|
|
||||||
document: '',
|
|
||||||
submissionFeedback: null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Assignments read-only - Student', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can edit and turn in', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({final: false, readOnly: false})
|
|
||||||
});
|
|
||||||
cy.visit('module/module-with-assignment');
|
|
||||||
|
|
||||||
cy.get('.submission-form__textarea').as('textarea');
|
|
||||||
|
|
||||||
cy.get('@textarea').invoke('val').should('contain', myText);
|
|
||||||
cy.get('@textarea').clear().type('Hello');
|
|
||||||
cy.get('@textarea').should('not.have.attr', 'readonly');
|
|
||||||
|
|
||||||
cy.getByDataCy('submission-form-submit').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: very flaky test, fix and re-enable
|
|
||||||
it.skip('can not edit or turn in', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({final: false, readOnly: true})
|
|
||||||
});
|
|
||||||
cy.visit('module/module-with-assignment');
|
|
||||||
|
|
||||||
cy.isSubmissionReadOnly(myText);
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can revoke turn in', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({final: true, readOnly: false})
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('module/module-with-assignment');
|
|
||||||
cy.getByDataCy('final-submission').should('exist');
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not revoke turn in', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({final: true, readOnly: true})
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('module/module-with-assignment');
|
|
||||||
cy.getByDataCy('final-submission').should('exist');
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit or turn in in inactive class', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({final: false, readOnly: false, classReadOnly: true})
|
|
||||||
});
|
|
||||||
cy.visit('module/module-with-assignment');
|
|
||||||
|
|
||||||
cy.isSubmissionReadOnly(myText);
|
|
||||||
cy.getByDataCy('final-submission-reopen').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly, classReadOnly = false}) => ({
|
|
||||||
MeQuery: getMinimalMe({readOnly, classReadOnly}),
|
|
||||||
NewsTeasers: {
|
|
||||||
newsTeasers: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Read Only Banner', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is not shown', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: false}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
cy.getByDataCy('start-page-heading').should('exist');
|
|
||||||
cy.getByDataCy('read-only-banner').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is shown for expired license', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: true}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
cy.getByDataCy('start-page-heading').should('exist');
|
|
||||||
|
|
||||||
cy.getByDataCy('read-only-banner').should('exist').should('contain', 'Lizenz');
|
|
||||||
cy.getByDataCy('license-activation-link')
|
|
||||||
.should('exist')
|
|
||||||
.should('contain', 'Neuen Lizenzcode eingeben')
|
|
||||||
.click();
|
|
||||||
cy.url().should('contain', 'license-activation');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is shown for inactive school class', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: false, classReadOnly: true}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
cy.getByDataCy('start-page-heading').should('exist');
|
|
||||||
|
|
||||||
cy.getByDataCy('read-only-banner').should('exist').should('contain', 'Klasse');
|
|
||||||
cy.getByDataCy('license-activation-link').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = (readOnly = false, classReadOnly = false) => {
|
|
||||||
const MeQuery = getMinimalMe({readOnly, classReadOnly});
|
|
||||||
const me = MeQuery.me;
|
|
||||||
|
|
||||||
return {
|
|
||||||
MeQuery,
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: {
|
|
||||||
...me,
|
|
||||||
id: 'meId',
|
|
||||||
selectedClass: {
|
|
||||||
...me.selectedClass,
|
|
||||||
members: [
|
|
||||||
{
|
|
||||||
id: 'meId',
|
|
||||||
firstName: 'Helge',
|
|
||||||
lastName: 'Schneider',
|
|
||||||
isTeacher: true,
|
|
||||||
isMe: true,
|
|
||||||
active: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'notMeId',
|
|
||||||
firstName: 'Otto',
|
|
||||||
lastName: 'Waalkes',
|
|
||||||
isTeacher: false,
|
|
||||||
isMe: false,
|
|
||||||
active: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'alsoNotMeId',
|
|
||||||
firstName: 'Kaya',
|
|
||||||
lastName: 'Yanar',
|
|
||||||
isTeacher: false,
|
|
||||||
isMe: false,
|
|
||||||
active: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
AddRemoveMember: {
|
|
||||||
addRemoveMember: {
|
|
||||||
success: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Leave School Class', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can leave class', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations(),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/class');
|
|
||||||
|
|
||||||
cy.getByDataCy('remove-from-class').should('exist');
|
|
||||||
cy.getByDataCy('add-to-class').should('exist');
|
|
||||||
cy.getByDataCy('leave-group').click();
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('read-only-banner').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not leave class when license invalid', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations(true),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/class');
|
|
||||||
|
|
||||||
cy.getByDataCy('remove-from-class').should('not.exist');
|
|
||||||
cy.getByDataCy('add-to-class').should('not.exist');
|
|
||||||
cy.getByDataCy('leave-group').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not leave class when class inactive', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations(false, true),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/class');
|
|
||||||
|
|
||||||
cy.getByDataCy('remove-from-class').should('not.exist');
|
|
||||||
cy.getByDataCy('add-to-class').should('not.exist');
|
|
||||||
cy.getByDataCy('leave-group').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
import minimalModule from '../../../fixtures/module.minimal';
|
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly, classReadOnly = false}) => ({
|
|
||||||
MeQuery: getMinimalMe({readOnly, classReadOnly}),
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {
|
|
||||||
...minimalModule,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateLastModule: {}
|
|
||||||
});
|
|
||||||
|
|
||||||
const moduleNavigationTest = ({readOnly, classReadOnly = false, displayMenu}) => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly, classReadOnly}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const shouldMenuExist = displayMenu ? 'exist' : 'not.exist';
|
|
||||||
|
|
||||||
cy.visit('module/module-slug');
|
|
||||||
|
|
||||||
cy.getByDataCy('module-navigation').should('exist');
|
|
||||||
cy.getByDataCy('module-teacher-menu').should(shouldMenuExist);
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Module Navigation - read only', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is shown', () => {
|
|
||||||
moduleNavigationTest({readOnly: false, displayMenu: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is not shown when no valid license', () => {
|
|
||||||
moduleNavigationTest({readOnly: true, displayMenu: false});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is not shown when inactive school class', () => {
|
|
||||||
moduleNavigationTest({readOnly: false, classReadOnly: true, displayMenu: false});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly}) => ({
|
|
||||||
MeQuery: getMinimalMe({readOnly}),
|
|
||||||
NewsTeasers: {
|
|
||||||
newsTeasers: [
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Read Only News', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays the news', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: false}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
cy.getByDataCy('news-navigation-link').should('exist');
|
|
||||||
|
|
||||||
cy.getByDataCy('news-teasers').should('exist');
|
|
||||||
cy.getByDataCy('news-teaser').should('have.length', 2);
|
|
||||||
});
|
|
||||||
it('does not display the news', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly: true}),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
|
|
||||||
cy.getByDataCy('news-navigation-link').should('not.exist');
|
|
||||||
cy.getByDataCy('news-teasers').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly = false, classReadOnly = false}) => ({
|
|
||||||
MeQuery: getMinimalMe({readOnly, classReadOnly}),
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
id: 'projectId',
|
|
||||||
final: false,
|
|
||||||
student: {
|
|
||||||
id: btoa('PrivateUserNode:1'),
|
|
||||||
},
|
|
||||||
entriesCount: 3,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Read Only Portfolio', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Can create and edit project', () => {
|
|
||||||
cy.mockGraphqlOps({operations: getOperations({readOnly: false})});
|
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('project-list').should('exist');
|
|
||||||
cy.getByDataCy('create-project-button').should('exist');
|
|
||||||
cy.getByDataCy('project').should('have.length', 1);
|
|
||||||
cy.getByDataCy('project-actions').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Can not create and edit project when license invalid', () => {
|
|
||||||
cy.mockGraphqlOps({operations: getOperations({readOnly: true})});
|
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('project-list').should('exist');
|
|
||||||
cy.getByDataCy('add-project-button').should('not.exist');
|
|
||||||
cy.getByDataCy('project').should('have.length', 1);
|
|
||||||
cy.getByDataCy('project-actions').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Can not create and edit project when class inactive', () => {
|
|
||||||
cy.mockGraphqlOps({operations: getOperations({readOnly: false, classReadOnly: true})});
|
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('project-list').should('exist');
|
|
||||||
cy.getByDataCy('add-project-button').should('not.exist');
|
|
||||||
cy.getByDataCy('project').should('have.length', 1);
|
|
||||||
cy.getByDataCy('project-actions').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly = false, classReadOnly = false}) => ({
|
|
||||||
MeQuery: getMinimalMe({readOnly, classReadOnly}),
|
|
||||||
ProjectQuery: {
|
|
||||||
project: {
|
|
||||||
id: 'projectId',
|
|
||||||
slug: 'project-name',
|
|
||||||
final: false,
|
|
||||||
student: {
|
|
||||||
id: btoa('PrivateUserNode:1'),
|
|
||||||
},
|
|
||||||
entriesCount: 1,
|
|
||||||
entries: [
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const testProject = (readOnly, shouldActionsExist, classReadOnly = false) => {
|
|
||||||
cy.mockGraphqlOps({operations: getOperations({readOnly, classReadOnly})});
|
|
||||||
|
|
||||||
const exist = shouldActionsExist ? 'exist' : 'not.exist';
|
|
||||||
|
|
||||||
cy.visit('/portfolio/project-name');
|
|
||||||
cy.getByDataCy('project-title').should('exist');
|
|
||||||
cy.getByDataCy('project-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('add-project-entry').should(exist);
|
|
||||||
cy.getByDataCy('project-actions').should(exist);
|
|
||||||
cy.getByDataCy('project-entry-more').should(exist);
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Read Only Project', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Can create and edit project entry', () => {
|
|
||||||
testProject(false, true);
|
|
||||||
});
|
|
||||||
it('Can not create and edit project entry when license expired', () => {
|
|
||||||
testProject(true, false);
|
|
||||||
});
|
|
||||||
it('Can not create and edit project entry when class inactive', () => {
|
|
||||||
testProject(false, false, true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
const SELECTED_CLASS_ID = 'selectedClassId';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly, classReadOnly}) => {
|
|
||||||
const {me} = getMinimalMe({readOnly, classReadOnly, isTeacher: true});
|
|
||||||
return {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
...me,
|
|
||||||
readOnly,
|
|
||||||
selectedClass: {
|
|
||||||
id: SELECTED_CLASS_ID,
|
|
||||||
readOnly: classReadOnly,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RoomEntriesQuery: {
|
|
||||||
room: {
|
|
||||||
id: 'roomId',
|
|
||||||
slug: '',
|
|
||||||
title: 'room title',
|
|
||||||
entryCount: 3,
|
|
||||||
appearance: 'blue',
|
|
||||||
description: 'room description',
|
|
||||||
schoolClass: {
|
|
||||||
id: SELECTED_CLASS_ID,
|
|
||||||
name: 'selected class',
|
|
||||||
},
|
|
||||||
roomEntries: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: {
|
|
||||||
id: 'entryId',
|
|
||||||
slug: '',
|
|
||||||
title: 'entry title',
|
|
||||||
contents: [],
|
|
||||||
author: {
|
|
||||||
id: btoa('PublicUserNode:authorId'),
|
|
||||||
firstName: 'first',
|
|
||||||
lastName: 'last',
|
|
||||||
avatarUrl: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkRoomReadOnly = ({editable, readOnly, classReadOnly = false}) => {
|
|
||||||
const operations = getOperations({readOnly, classReadOnly});
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
const exist = editable ? 'exist' : 'not.exist';
|
|
||||||
cy.visit('room/some-room');
|
|
||||||
cy.get('.room-entry').should('exist');
|
|
||||||
cy.getByDataCy('add-room-entry-button').should(exist);
|
|
||||||
cy.getByDataCy('room-actions').should(exist);
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Room Team Management - Read only', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can edit room', () => {
|
|
||||||
checkRoomReadOnly({editable: true, readOnly: false});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit room', () => {
|
|
||||||
checkRoomReadOnly({editable: false, readOnly: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit room of inactive class', () => {
|
|
||||||
checkRoomReadOnly({editable: false, readOnly: false, classReadOnly: true});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
describe('Room Team Management - Read only', () => {
|
|
||||||
const SELECTED_CLASS_ID = 'selectedClassId';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly, classReadOnly}) => ({
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
readOnly,
|
|
||||||
isTeacher: true,
|
|
||||||
selectedClass: {
|
|
||||||
id: SELECTED_CLASS_ID,
|
|
||||||
readOnly: classReadOnly,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RoomsQuery: {
|
|
||||||
rooms: [{
|
|
||||||
id: '',
|
|
||||||
slug: '',
|
|
||||||
title: 'some room',
|
|
||||||
entryCount: 3,
|
|
||||||
appearance: 'red',
|
|
||||||
description: 'some description',
|
|
||||||
schoolClass: {
|
|
||||||
id: SELECTED_CLASS_ID,
|
|
||||||
name: 'bla',
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const checkRoomsReadOnly = ({editable, readOnly, classReadOnly = false}) => {
|
|
||||||
const operations = getOperations({readOnly, classReadOnly});
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
const exist = editable ? 'exist' : 'not.exist';
|
|
||||||
cy.visit('rooms');
|
|
||||||
cy.log('visit');
|
|
||||||
cy.get('.room-widget').should('exist');
|
|
||||||
cy.getByDataCy('add-room').should(exist);
|
|
||||||
cy.getByDataCy('widget-footer').should(exist);
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can edit room', () => {
|
|
||||||
checkRoomsReadOnly({editable: true, readOnly: false});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit room', () => {
|
|
||||||
checkRoomsReadOnly({editable: false, readOnly: true});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not edit room of inactive class', () => {
|
|
||||||
checkRoomsReadOnly({editable: false, readOnly: false, classReadOnly: true});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
import mocks from '../../../fixtures/mocks';
|
|
||||||
|
|
||||||
const selectedClassName = 'My Class';
|
|
||||||
|
|
||||||
const getOperations = ({readOnly}) => ({
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
readOnly,
|
|
||||||
isTeacher: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: {
|
|
||||||
readOnly,
|
|
||||||
isTeacher: true,
|
|
||||||
selectedClass: {
|
|
||||||
name: selectedClassName,
|
|
||||||
code: 'XXXX',
|
|
||||||
members: [
|
|
||||||
{
|
|
||||||
id: 'id',
|
|
||||||
firstName: 'Me',
|
|
||||||
lastName: 'Myson',
|
|
||||||
isTeacher: true,
|
|
||||||
active: true,
|
|
||||||
isMe: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const checkSchoolClassTeamReadOnly = (readOnly) => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOperations({readOnly}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const exist = readOnly ? 'not.exist' : 'exist';
|
|
||||||
cy.visit('me/class');
|
|
||||||
cy.getByDataCy('group-list-name').should('exist').should('contain', selectedClassName);
|
|
||||||
cy.getByDataCy('show-code-button').should(exist);
|
|
||||||
cy.getByDataCy('edit-group-name-link').should(exist);
|
|
||||||
cy.openSidebar();
|
|
||||||
cy.getByDataCy('class-selection').click();
|
|
||||||
cy.getByDataCy('current-class-name').should('exist');
|
|
||||||
cy.getByDataCy('create-class-link').should(exist);
|
|
||||||
cy.getByDataCy('my-team-link').should(exist);
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('School Class and Team Management - Read only', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.fakeLogin('rachel.green', 'test');
|
|
||||||
cy.server();
|
|
||||||
cy.task('getSchema').then(schema => {
|
|
||||||
cy.mockGraphql({
|
|
||||||
schema,
|
|
||||||
mocks,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can see menu items', () => {
|
|
||||||
checkSchoolClassTeamReadOnly(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can not see menu items', () => {
|
|
||||||
checkSchoolClassTeamReadOnly(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('Article page', () => {
|
|
||||||
const slug = 'this-article-has-a-slug';
|
|
||||||
const roomEntry = {
|
|
||||||
slug,
|
|
||||||
id: 'room-entry-id',
|
|
||||||
title: 'Some Room Entry, yay!',
|
|
||||||
comments: [],
|
|
||||||
contents: [{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'Ein Text',
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
type: 'subtitle',
|
|
||||||
value: {
|
|
||||||
text: 'Ein Untertitel'
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery: getMinimalMe({}),
|
|
||||||
RoomEntryQuery: {
|
|
||||||
roomEntry,
|
|
||||||
},
|
|
||||||
AddComment({input}) {
|
|
||||||
return {
|
|
||||||
addComment: {
|
|
||||||
success: true,
|
|
||||||
comment: {
|
|
||||||
text: input.comment,
|
|
||||||
roomEntry: roomEntry,
|
|
||||||
owner: {
|
|
||||||
firstName: 'Matt',
|
|
||||||
lastName: 'Damon',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the article with contents', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/article/${slug}`);
|
|
||||||
cy.getByDataCy('text-block').should('contain.text', 'Ein Text');
|
|
||||||
cy.getByDataCy('subtitle-block').should('contain.text', 'Ein Untertitel');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('goes to article and leaves a comment', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
const commentText = 'First! ';
|
|
||||||
const emoji = '🖐';
|
|
||||||
cy.visit(`/article/${slug}`);
|
|
||||||
cy.getByDataCy('comment-textarea').type(commentText);
|
|
||||||
cy.getByDataCy('emoji-button').should('have.length', 9).first().click();
|
|
||||||
cy.getByDataCy('submit-comment').should('contain', 'Kommentar teilen').click();
|
|
||||||
cy.getByDataCy('comment').first().should('contain', commentText + emoji);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show input field on mobile', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.viewport('iphone-8');
|
|
||||||
cy.visit(`/article/${slug}`);
|
|
||||||
cy.getByDataCy('article-title').should('exist');
|
|
||||||
cy.getByDataCy('comment-textarea').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,403 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('The Room Page (Teacher)', () => {
|
|
||||||
const MeQuery = getMinimalMe();
|
|
||||||
const selectedClass = MeQuery.me.selectedClass;
|
|
||||||
const entryText = 'something should be here';
|
|
||||||
const entryTitle = 'some title';
|
|
||||||
const slug = 'ein-historisches-festival';
|
|
||||||
const id = btoa('RoomNode:1');
|
|
||||||
const room = {
|
|
||||||
id,
|
|
||||||
slug,
|
|
||||||
schoolClass: selectedClass,
|
|
||||||
restricted: false,
|
|
||||||
roomEntries: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const RoomEntriesQuery = {
|
|
||||||
room,
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery,
|
|
||||||
AddRoomEntry: {
|
|
||||||
addRoomEntry: {
|
|
||||||
roomEntry: {
|
|
||||||
title: entryTitle,
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: entryText,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
author: {
|
|
||||||
firstName: 'Rachel',
|
|
||||||
lastName: 'Green',
|
|
||||||
id: btoa('PublicUserNode:rachels-id'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
errors: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkRadioButton = () => {
|
|
||||||
cy.get('.base-input-container__input:checked + .base-input-container__radiobutton svg').should('have.length', 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('displays new room entry with author name', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
|
|
||||||
cy.getByDataCy('add-room-entry-button').click();
|
|
||||||
cy.getByDataCy('add-content-link').first().click();
|
|
||||||
cy.getByDataCy('choose-text-widget').click();
|
|
||||||
cy.getByDataCy('input-with-label-input').type(entryTitle);
|
|
||||||
|
|
||||||
cy.get('.tip-tap__editor').type(entryText);
|
|
||||||
cy.getByDataCy('save-button').click();
|
|
||||||
|
|
||||||
cy.get('.room-entry__content:first').should('contain', entryText).should('contain', 'Rachel Green');
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: re-enable once cypress can do it correctly
|
|
||||||
it.skip('changes visibility of a room', () => {
|
|
||||||
const MeQuery = getMinimalMe({
|
|
||||||
isTeacher: true,
|
|
||||||
});
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery,
|
|
||||||
UpdateRoomVisibility: {
|
|
||||||
updateRoomVisibility: {
|
|
||||||
success: true,
|
|
||||||
room: {
|
|
||||||
...room,
|
|
||||||
restricted: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-visibility-status').should('contain', 'alle Lernenden');
|
|
||||||
cy.getByDataCy('toggle-more-actions-menu').click();
|
|
||||||
cy.getByDataCy('change-visibility').click();
|
|
||||||
cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen');
|
|
||||||
cy.get('.change-visibility__radio').should('have.length', 2);
|
|
||||||
cy.get('.change-visibility__radio--selected').should('have.length', 1);
|
|
||||||
checkRadioButton();
|
|
||||||
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'alle Lernenden');
|
|
||||||
checkRadioButton();
|
|
||||||
cy.getByDataCy('select-option').eq(0).click();
|
|
||||||
cy.get('.change-visibility__radio--selected').should('have.length', 1);
|
|
||||||
checkRadioButton();
|
|
||||||
cy.getByDataCy('select-option').eq(1).click();
|
|
||||||
cy.getByDataCy('select-option').eq(1).click();
|
|
||||||
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'eigenen Beiträge');
|
|
||||||
checkRadioButton();
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('room-visibility-status').should('contain', 'eigenen Beiträge');
|
|
||||||
cy.getByDataCy('toggle-more-actions-menu').click();
|
|
||||||
cy.getByDataCy('change-visibility').click();
|
|
||||||
cy.getByDataCy('modal-title').should('contain', 'Sichtbarkeit anpassen');
|
|
||||||
cy.get('.change-visibility__radio--selected').should('have.length', 1).should('contain', 'eigenen Beiträge');
|
|
||||||
checkRadioButton();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('deletes the room and goes back to the overview', () => {
|
|
||||||
const MeQuery = getMinimalMe();
|
|
||||||
const schoolClass = MeQuery.me.selectedClass;
|
|
||||||
const roomToDelete = {
|
|
||||||
id: btoa('RoomNode:room-to-delete'),
|
|
||||||
schoolClass,
|
|
||||||
slug: 'delete-me',
|
|
||||||
roomEntries: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const otherRoom = {
|
|
||||||
id: btoa('RoomNode:otherRoom'),
|
|
||||||
slug: 'other-slug',
|
|
||||||
schoolClass,
|
|
||||||
};
|
|
||||||
let rooms = [roomToDelete, otherRoom];
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomsQuery() {
|
|
||||||
return {
|
|
||||||
rooms,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
RoomEntriesQuery: {
|
|
||||||
room: roomToDelete,
|
|
||||||
},
|
|
||||||
DeleteRoom: {
|
|
||||||
deleteRoom: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/rooms`);
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 2);
|
|
||||||
cy.getByDataCy('room-widget').first().click();
|
|
||||||
cy.getByDataCy('toggle-more-actions-menu').click();
|
|
||||||
cy.getByDataCy('delete-room').within(() => {
|
|
||||||
cy.get('a').click();
|
|
||||||
});
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.url().should('include', 'rooms');
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('changes class while on room page', () => {
|
|
||||||
const {me} = MeQuery;
|
|
||||||
const otherClass = {
|
|
||||||
id: btoa('SchoolClassNode:34'),
|
|
||||||
name: 'Other Class',
|
|
||||||
readOnly: false,
|
|
||||||
};
|
|
||||||
let selectedClass = me.selectedClass;
|
|
||||||
const operations = {
|
|
||||||
MeQuery: () => {
|
|
||||||
return {
|
|
||||||
me: {
|
|
||||||
...me,
|
|
||||||
schoolClasses: [...me.schoolClasses, otherClass],
|
|
||||||
selectedClass,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
RoomEntriesQuery,
|
|
||||||
UpdateSettings() {
|
|
||||||
selectedClass = otherClass;
|
|
||||||
return {
|
|
||||||
updateSettings: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {},
|
|
||||||
MySchoolClassQuery: () => {
|
|
||||||
return {
|
|
||||||
me: {
|
|
||||||
selectedClass,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
RoomsQuery: {
|
|
||||||
rooms: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-title').should('contain', 'A Room');
|
|
||||||
cy.selectClass('Other Class');
|
|
||||||
cy.url().should('include', 'rooms');
|
|
||||||
cy.getByDataCy('current-class-name').should('contain', 'Other Class');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('The Room Page (student)', () => {
|
|
||||||
const slug = 'ein-historisches-festival';
|
|
||||||
const MeQuery = getMinimalMe({isTeacher: false});
|
|
||||||
const {me} = MeQuery;
|
|
||||||
const id = atob(me.id).split(':')[1];
|
|
||||||
const authorId = btoa(`PublicUserNode:${id}`);
|
|
||||||
const entrySlug = 'entry-slug';
|
|
||||||
const {selectedClass} = me;
|
|
||||||
const roomEntry = {
|
|
||||||
id: 'entry-id',
|
|
||||||
slug: entrySlug,
|
|
||||||
title: 'My Entry',
|
|
||||||
contents: [
|
|
||||||
{
|
|
||||||
type: 'text_block',
|
|
||||||
value: {
|
|
||||||
text: 'some text',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
comments: [{}, {}],
|
|
||||||
author: {
|
|
||||||
...me,
|
|
||||||
id: authorId,
|
|
||||||
firstName: 'Hans',
|
|
||||||
lastName: 'Was Heiri',
|
|
||||||
avatarUrl: '',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const room = {
|
|
||||||
id,
|
|
||||||
slug,
|
|
||||||
schoolClass: selectedClass,
|
|
||||||
restricted: false,
|
|
||||||
roomEntries: {
|
|
||||||
edges: [{
|
|
||||||
node: roomEntry,
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const RoomEntriesQuery = {
|
|
||||||
room,
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('room actions should not exist for student', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery: getMinimalMe({isTeacher: false}),
|
|
||||||
RoomEntriesQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
|
|
||||||
cy.getByDataCy('room-title').should('exist');
|
|
||||||
cy.getByDataCy('room-actions').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('creates a room entry', () => {
|
|
||||||
const MeQuery = getMinimalMe({isTeacher: false});
|
|
||||||
const room = {
|
|
||||||
id: 'some-room',
|
|
||||||
roomEntries: {
|
|
||||||
edges: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery: {
|
|
||||||
room,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('add-room-entry-button').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('content-form-section-title').should('have.text', 'Titel (Pflichtfeld)');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('edits own room entry', () => {
|
|
||||||
const room = {
|
|
||||||
id: 'some-room',
|
|
||||||
slug,
|
|
||||||
// schoolClass: me.selectedClass,
|
|
||||||
roomEntries: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: roomEntry,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const operations = {
|
|
||||||
MeQuery: MeQuery,
|
|
||||||
RoomEntriesQuery: {
|
|
||||||
room,
|
|
||||||
},
|
|
||||||
RoomEntryQuery: {
|
|
||||||
roomEntry,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-entry-actions').click();
|
|
||||||
cy.getByDataCy('edit-room-entry').click();
|
|
||||||
cy.location('pathname').should('include', entrySlug);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('deletes room entry', () => {
|
|
||||||
const DeleteRoomEntry = {
|
|
||||||
deleteRoomEntry: {
|
|
||||||
success: true,
|
|
||||||
errors: null,
|
|
||||||
roomSlug: slug,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery,
|
|
||||||
DeleteRoomEntry,
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('room-entry-actions').click();
|
|
||||||
cy.getByDataCy('delete-room-entry').click();
|
|
||||||
cy.getByDataCy('delete-room-entry').should('not.exist');
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('room-entry').should('have.length', 0);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows room entries with comment count', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery,
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-entry').should('have.length', 1).within(() => {
|
|
||||||
cy.getByDataCy('entry-count').should('contain.text', '2');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show actions on mobile', () => {
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomEntriesQuery,
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.viewport('iphone-8');
|
|
||||||
|
|
||||||
cy.visit(`/room/${slug}`);
|
|
||||||
cy.getByDataCy('room-actions').should('not.exist');
|
|
||||||
cy.getByDataCy('room-entry').should('have.length', 1);
|
|
||||||
cy.getByDataCy('room-entry-actions').should('not.be.visible');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
import {SELECTED_CLASS_ID_ENCODED} from '../../../fixtures/mocks';
|
|
||||||
|
|
||||||
describe('The Rooms Page', () => {
|
|
||||||
const getOperations = (isTeacher) => ({
|
|
||||||
MeQuery: getMinimalMe({isTeacher}),
|
|
||||||
RoomsQuery: {
|
|
||||||
rooms: [{
|
|
||||||
schoolClass: {
|
|
||||||
id: SELECTED_CLASS_ID_ENCODED,
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const getOnboardingOperations = (isTeacher) => {
|
|
||||||
const operations = getOperations(isTeacher);
|
|
||||||
return {
|
|
||||||
...operations,
|
|
||||||
RoomsQuery: {
|
|
||||||
rooms: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the onboarding page', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOnboardingOperations(true),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/rooms');
|
|
||||||
cy.getByDataCy('page-title').should('contain', 'Räume');
|
|
||||||
cy.getByDataCy('rooms-onboarding-text').should('contain', 'Hier können Sie Räume erstellen');
|
|
||||||
cy.getByDataCy('page-footer').should('not.exist');
|
|
||||||
cy.getByDataCy('create-room-button').should('contain', 'Raum erstellen').click();
|
|
||||||
cy.url().should('include', 'new-room');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the onboarding page without button for student', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: getOnboardingOperations(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/rooms');
|
|
||||||
cy.getByDataCy('page-title').should('contain', 'Räume');
|
|
||||||
cy.getByDataCy('rooms-onboarding-text').should('contain', 'Hier können Sie Räume erstellen');
|
|
||||||
cy.getByDataCy('page-footer').should('not.exist');
|
|
||||||
cy.getByDataCy('create-room-button').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('goes to the rooms page', () => {
|
|
||||||
const operations = getOperations(true);
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/rooms');
|
|
||||||
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 1);
|
|
||||||
cy.get('[data-cy=add-room]').should('exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('actions should not exist for student', () => {
|
|
||||||
const operations = getOperations(false);
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/rooms');
|
|
||||||
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 1);
|
|
||||||
cy.getByDataCy('toggle-more-actions-menu').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('adds a room as teacher', () => {
|
|
||||||
const MeQuery = getMinimalMe({isTeacher: true});
|
|
||||||
const getRoom = (title, appearance, description) => {
|
|
||||||
let id = title.toLowerCase().replace(' ', '-');
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
slug: id,
|
|
||||||
title: title,
|
|
||||||
entryCount: 3,
|
|
||||||
appearance: appearance,
|
|
||||||
description: description,
|
|
||||||
schoolClass: MeQuery.me.selectedClass
|
|
||||||
};
|
|
||||||
};
|
|
||||||
let rooms = [
|
|
||||||
getRoom('First Room', 'blue', 'Some description')
|
|
||||||
];
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery,
|
|
||||||
RoomsQuery() {
|
|
||||||
return {
|
|
||||||
rooms
|
|
||||||
};
|
|
||||||
},
|
|
||||||
AddRoom({input: {room: {title, appearance, description}}}) {
|
|
||||||
const room = getRoom(title, appearance, description);
|
|
||||||
rooms.push(room);
|
|
||||||
return {
|
|
||||||
addRoom: {
|
|
||||||
room,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
cy.visit('/rooms');
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 1);
|
|
||||||
cy.getByDataCy('add-room').click();
|
|
||||||
cy.getByDataCy('form-title').should('contain', 'Neuer Raum');
|
|
||||||
cy.getByDataCy('page-form-input-titel').type('Strg F');
|
|
||||||
cy.getByDataCy('school-class-select').should('not.exist');
|
|
||||||
cy.getByDataCy('color-select').eq(2).click();
|
|
||||||
cy.getByDataCy('room-form-save').click();
|
|
||||||
cy.getByDataCy('room-widget').should('have.length', 2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
import module from '../../fixtures/module.minimal';
|
|
||||||
|
|
||||||
const spellCheck = require('../../fixtures/spell-check.json');
|
|
||||||
|
|
||||||
const operations = {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
permissions: [],
|
|
||||||
readOnly: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
AssignmentQuery: {
|
|
||||||
assignment: {
|
|
||||||
id: '',
|
|
||||||
title: 'Ein Auftragstitel',
|
|
||||||
assignment: 'Ein Auftrag',
|
|
||||||
submission: {
|
|
||||||
id: 'U3R1ZGVudFN1Ym1pc3Npb25Ob2RlOjE=',
|
|
||||||
text: 'Hir ist ein Feler gewesen',
|
|
||||||
final: false,
|
|
||||||
document: '',
|
|
||||||
submissionFeedback: {
|
|
||||||
'id': 'U3VibWlzc2lvbkZlZWRiYWNrTm9kZTox',
|
|
||||||
'text': '\ud83d\ude42\ud83d\ude10\ud83e\udd2c\ud83d\udc4d\ud83e\udd22\ud83e\udd22\ud83e\udd22\ud83e\udd22\ud83d\ude2e\ud83e\udd17',
|
|
||||||
'teacher': {
|
|
||||||
'firstName': 'Nico',
|
|
||||||
'lastName': 'Zickgraf',
|
|
||||||
'__typename': 'UserNode',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ModuleDetailsQuery: {
|
|
||||||
module: {
|
|
||||||
...module,
|
|
||||||
assignments: [
|
|
||||||
{
|
|
||||||
'id': 'QXNzaWdubWVudE5vZGU6MQ==',
|
|
||||||
'title': 'Ein Auftragstitel',
|
|
||||||
'assignment': 'Ein Auftrag',
|
|
||||||
'solution': null,
|
|
||||||
'submission': {
|
|
||||||
'id': 'U3R1ZGVudFN1Ym1pc3Npb25Ob2RlOjE=',
|
|
||||||
'text': 'Hir ist ein Feler gewesen',
|
|
||||||
'final': false,
|
|
||||||
'document': '',
|
|
||||||
'submissionFeedback': {
|
|
||||||
'id': 'U3VibWlzc2lvbkZlZWRiYWNrTm9kZTox',
|
|
||||||
'text': '🙂😐🤬👍🤢🤢🤢🤢😮🤗',
|
|
||||||
'teacher': {
|
|
||||||
'firstName': 'Nico',
|
|
||||||
'lastName': 'Zickgraf',
|
|
||||||
'__typename': 'UserNode',
|
|
||||||
},
|
|
||||||
'__typename': 'SubmissionFeedbackNode',
|
|
||||||
},
|
|
||||||
'__typename': 'StudentSubmissionNode',
|
|
||||||
},
|
|
||||||
'__typename': 'AssignmentNode',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
chapters: [
|
|
||||||
{
|
|
||||||
'id': 'Q2hhcHRlck5vZGU6MTg=',
|
|
||||||
'title': '1.1 Lehrbeginn',
|
|
||||||
'description': 'Wie sieht Ihr Konsumverhalten aus?',
|
|
||||||
'bookmark': {
|
|
||||||
'note': {
|
|
||||||
'id': 'Tm90ZU5vZGU6Mg==',
|
|
||||||
'text': 'Chapter Chapter',
|
|
||||||
'__typename': 'NoteNode',
|
|
||||||
},
|
|
||||||
'__typename': 'ChapterBookmarkNode',
|
|
||||||
},
|
|
||||||
contentBlocks: [
|
|
||||||
{
|
|
||||||
'id': 'Q29udGVudEJsb2NrTm9kZToxOQ==',
|
|
||||||
'slug': 'assignment',
|
|
||||||
'title': 'Assignment',
|
|
||||||
'type': 'NORMAL',
|
|
||||||
'contents': [
|
|
||||||
{
|
|
||||||
'type': 'assignment',
|
|
||||||
'value': {
|
|
||||||
'title': 'Ein Auftragstitel',
|
|
||||||
'assignment': 'Ein Auftrag',
|
|
||||||
'id': 'QXNzaWdubWVudE5vZGU6MQ==',
|
|
||||||
},
|
|
||||||
'id': 'df8212ee-3e82-49fa-977e-c4b60789163e',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'userCreated': false,
|
|
||||||
'mine': false,
|
|
||||||
'bookmarks': [
|
|
||||||
{
|
|
||||||
'uuid': 'df8212ee-3e82-49fa-977e-c4b60789163e',
|
|
||||||
'note': {
|
|
||||||
'id': 'Tm90ZU5vZGU6Mw==',
|
|
||||||
'text': 'Noch eine Notiz',
|
|
||||||
'__typename': 'NoteNode',
|
|
||||||
},
|
|
||||||
'__typename': 'ContentBlockBookmarkNode',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'hiddenFor': [],
|
|
||||||
'visibleFor': [],
|
|
||||||
'__typename': 'ContentBlockNode',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SpellCheck: {
|
|
||||||
spellCheck,
|
|
||||||
},
|
|
||||||
UpdateAssignment: {
|
|
||||||
updateAssignment: {
|
|
||||||
assignment: {
|
|
||||||
id: '',
|
|
||||||
title: 'title',
|
|
||||||
assignment: '',
|
|
||||||
solution: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateLastModule: {
|
|
||||||
updateLastModule: {
|
|
||||||
lastModule: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Spellcheck', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: unskip me
|
|
||||||
it('should highlight three errors', () => {
|
|
||||||
cy.visit('/module/lohn-und-budget/');
|
|
||||||
|
|
||||||
cy.getByDataCy('spellcheck-correction').should('have.length', 0);
|
|
||||||
cy.getByDataCy('spellcheck-button').click();
|
|
||||||
cy.getByDataCy('spellcheck-correction').should('have.length', 3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
const module = require('../../fixtures/module.json');
|
|
||||||
|
|
||||||
describe('Survey', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display and fill out the survey', () => {
|
|
||||||
let answer = null;
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
permissions: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ModuleQuery: variables => ({module}),
|
|
||||||
SurveyQuery: () => ({
|
|
||||||
survey: {
|
|
||||||
id: 'U3VydmV5Tm9kZTox',
|
|
||||||
title: 'Test',
|
|
||||||
data: '{"pages": [{"name": "Seite 1", "elements": [{"name": "Fall 1", "type": "panel", "title": "Fall 1", "elements": [{"name": "A: Max gibt ihr das Geld und muss das Billardspiel absagen.", "type": "text", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Triss"}, {"name": "question2", "type": "text", "title": "B: Max gibt ihr das Geld nicht und geht Billard spielen.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Jaskier"}], "description": "Max hat Ende Monat noch Fr. 20.\\u2013 \\u00fcbrig, die er gespart hat, um mit seinem besten Kumpel, der ein halbes Jahr im Ausland verweilte, Billard spielen zu gehen. Doch dann bittet ihn seine j\\u00fcngere Schwester um Geld. Sie hat ein unverhofftes Date mit einem jungen Mann, in den sie sich bereits vor Monaten unsterblich verliebt hat. Leider ist ihr Kontostand aber bereits auf Null."}]}, {"name": "Seite 2", "elements": [{"name": "panel1", "type": "panel", "title": "Fall 2", "elements": [{"name": "question1", "type": "text", "title": "A: Silvio bringt seinen Mitfahrer in Sicherheit.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Yennefer", "useDisplayValuesInTitle": false}, {"name": "question3", "type": "text", "title": "B: Silvio sperrt die Strasse ab.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Geralt"}], "description": "Auf der Autobahn brennt ein Lastwagen, der jederzeit explodieren kann. Silvio, dem Fahrer, bleiben nur noch wenige Minuten: Entweder bringt er seinen ohnm\\u00e4chtig gewordenen Mitfahrer in Sicherheit oder er sperrt die Strasse ab, die nach wie vor dicht befahren wird."}]}], "completeText": "Abschliessen", "showQuestionNumbers": "off"}',
|
|
||||||
module: {
|
|
||||||
id: 'TW9kdWxlTm9kZToxNw==',
|
|
||||||
__typename: 'ModuleNode'
|
|
||||||
},
|
|
||||||
answer,
|
|
||||||
__typename: 'SurveyNode'
|
|
||||||
},
|
|
||||||
|
|
||||||
}),
|
|
||||||
UpdateAnswer: variables => {
|
|
||||||
answer = variables.input.answer;
|
|
||||||
return {
|
|
||||||
updateAnswer: {
|
|
||||||
answer,
|
|
||||||
__typename: 'UpdateAnswerPayload'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
ModuleSolutions: {
|
|
||||||
module: {
|
|
||||||
solutionsEnabled: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/survey/U3VydmV5Tm9kZTox');
|
|
||||||
|
|
||||||
cy.get('.survey__panel-title').should('contain', 'Fall 1');
|
|
||||||
|
|
||||||
cy.get('#sq_100i').type('Wohlwollen');
|
|
||||||
cy.get('#sq_101i').type('Demut');
|
|
||||||
|
|
||||||
cy.get('[value="Speichern & Weiter"]').click();
|
|
||||||
|
|
||||||
cy.get('#sq_102i').type('Keuschheit');
|
|
||||||
cy.get('#sq_103i').type('Geduld');
|
|
||||||
|
|
||||||
cy.get('[value=Abschliessen]').click();
|
|
||||||
|
|
||||||
cy.visit('/survey/U3VydmV5Tm9kZTox');
|
|
||||||
|
|
||||||
cy.get('#sq_100i').should('have.value', 'Wohlwollen');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
describe('The Home Page', () => {
|
|
||||||
it('successfully loads', () => {
|
|
||||||
cy.visit('/')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
import {assertStartPage} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('Onboarding', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the onboarding steps and finishes them', () => {
|
|
||||||
let onboardingVisited = false;
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: () => ({
|
|
||||||
me: {
|
|
||||||
onboardingVisited,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
UpdateOnboardingProgress: () => {
|
|
||||||
onboardingVisited = true;
|
|
||||||
return {
|
|
||||||
updateOnboardingProgress: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
NewsTeasers: {}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
assertStartPage(true);
|
|
||||||
cy.get('[data-cy=onboarding-next-link]').click();
|
|
||||||
cy.get('[data-cy=onboarding-next-link]').click();
|
|
||||||
cy.get('[data-cy=onboarding-next-link]').click();
|
|
||||||
cy.get('[data-cy=onboarding-next-link]').click();
|
|
||||||
assertStartPage(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('shows the onboarding steps and skips them', () => {
|
|
||||||
let onboardingVisited = false;
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
onboardingVisited,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateOnboardingProgress: () => {
|
|
||||||
onboardingVisited = true;
|
|
||||||
return {
|
|
||||||
updateOnboardingProgress: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
assertStartPage(true);
|
|
||||||
cy.getByDataCy('onboarding-skip-link').click();
|
|
||||||
assertStartPage(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not show the onboarding', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {
|
|
||||||
me: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
assertStartPage(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
describe('Sidebar', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should open sidebar and stay open', () => {
|
|
||||||
const {me} = getMinimalMe({});
|
|
||||||
const operations = {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
...me,
|
|
||||||
schoolClasses: [...me.schoolClasses, {}],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProjectsQuery: {
|
|
||||||
projects: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
|
||||||
cy.getByDataCy('sidebar').should('not.exist');
|
|
||||||
cy.getByDataCy('user-widget-avatar').click();
|
|
||||||
cy.getByDataCy('sidebar').should('exist');
|
|
||||||
cy.getByDataCy('class-selection').click();
|
|
||||||
cy.getByDataCy('class-selection-entry').should('have.length', 2);
|
|
||||||
cy.getByDataCy('close-profile-sidebar-link').click();
|
|
||||||
cy.getByDataCy('sidebar').should('not.exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
|
|
||||||
// const me = require('../../fixtures/me.new-student.json');
|
|
||||||
|
|
||||||
describe('New student', () => {
|
|
||||||
before(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
// todo: unskip me
|
|
||||||
it.skip('shows "Enter Code" page and adds the user to a class', () => {
|
|
||||||
const {me} = getMinimalMe({isTeacher: false});
|
|
||||||
|
|
||||||
let onboardingVisited = false;
|
|
||||||
let selectedClass;
|
|
||||||
let schoolClasses = [];
|
|
||||||
|
|
||||||
const name = 'KF1A';
|
|
||||||
const id = 'selectedClassId';
|
|
||||||
|
|
||||||
console.log('me', me);
|
|
||||||
|
|
||||||
const getSelectedClass = () => {
|
|
||||||
return selectedClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getMe = () => {
|
|
||||||
return {
|
|
||||||
...me,
|
|
||||||
onboardingVisited,
|
|
||||||
schoolClasses,
|
|
||||||
selectedClass: getSelectedClass(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('getMe()', getMe());
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery() {
|
|
||||||
return {
|
|
||||||
me: getMe(),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
JoinClass() {
|
|
||||||
console.log('joining class');
|
|
||||||
selectedClass = {
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
};
|
|
||||||
schoolClasses.push(selectedClass);
|
|
||||||
return {
|
|
||||||
joinClass: {
|
|
||||||
success: true,
|
|
||||||
schoolClass: selectedClass,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: getMe(),
|
|
||||||
},
|
|
||||||
UpdateOnboardingProgress: () => {
|
|
||||||
onboardingVisited = true;
|
|
||||||
return {
|
|
||||||
updateOnboardingProgress: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/');
|
|
||||||
cy.get('[data-cy=join-form-title]').should('contain', 'Einer Klasse beitreten');
|
|
||||||
cy.get('[data-cy=join-form-input]').type('XXXX');
|
|
||||||
cy.get('[data-cy=join-form-confirm]').click();
|
|
||||||
cy.getByDataCy('onboarding-skip-link').click();
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
cy.get('[data-cy=class-list-link]').click();
|
|
||||||
cy.get('[data-cy=group-list-title]').should('contain', 'Klassenliste');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,396 +0,0 @@
|
||||||
import {hasOperationName} from '../../../support/graphql';
|
|
||||||
|
|
||||||
const me = require('../../../fixtures/me.join-class.json');
|
|
||||||
const {getMinimalMe} = require('../../../support/helpers');
|
|
||||||
|
|
||||||
const MeQuery = getMinimalMe({});
|
|
||||||
const {me: teacher} = MeQuery;
|
|
||||||
|
|
||||||
const members = [
|
|
||||||
{
|
|
||||||
id: 'VXNlck5vZGU6Mw==',
|
|
||||||
firstName: 'Otis',
|
|
||||||
lastName: 'Milburn',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'VXNlck5vZGU6NA==',
|
|
||||||
firstName: 'Maeve',
|
|
||||||
lastName: 'Wiley',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
describe('School Class Management', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should join class', () => {
|
|
||||||
const name = 'KF1A';
|
|
||||||
let selectedClassName = 'Moordale';
|
|
||||||
|
|
||||||
const getSelectedClassWithName = () => ({
|
|
||||||
id: 'selectedClassId',
|
|
||||||
name: selectedClassName,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: () => ({
|
|
||||||
me: {
|
|
||||||
...teacher,
|
|
||||||
selectedClass: getSelectedClassWithName(),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
// JoinClass() {
|
|
||||||
// // fixme: is this necessary? the cache somehow does not seem to do anything for the MeQuery
|
|
||||||
// let schoolClass = {
|
|
||||||
// id,
|
|
||||||
// name,
|
|
||||||
// // __typename
|
|
||||||
// };
|
|
||||||
// // localMe.me.schoolClasses.edges.push({
|
|
||||||
// // node: schoolClass,
|
|
||||||
// // __typename: 'SchoolClassNodeEdge'
|
|
||||||
// // });
|
|
||||||
// return {
|
|
||||||
// joinClass: {
|
|
||||||
// success: true,
|
|
||||||
// schoolClass
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
JoinClass() {
|
|
||||||
selectedClassName = name;
|
|
||||||
return {
|
|
||||||
joinClass: {
|
|
||||||
success: true,
|
|
||||||
schoolClass: getSelectedClassWithName(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: () => ({
|
|
||||||
me: {
|
|
||||||
...teacher,
|
|
||||||
selectedClass: getSelectedClassWithName(),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/profile');
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
});
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-class-link]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-form-input]').type('XXXX');
|
|
||||||
cy.get('[data-cy=join-form-confirm]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=group-list-name]').should('contain', name);
|
|
||||||
cy.get('[data-cy=current-class-name]').should('contain', name);
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
cy.get('[data-cy=class-selection-entry]').should('have.length', 2);
|
|
||||||
})
|
|
||||||
;
|
|
||||||
|
|
||||||
it('should leave and re-join class', () => {
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery,
|
|
||||||
AddRemoveMember: {
|
|
||||||
addRemoveMember: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: {
|
|
||||||
...teacher,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
cy.get('[data-cy=active-member]').should('have.length', 2);
|
|
||||||
cy.get('[data-cy=inactive-class-members-list]').should('not.exist');
|
|
||||||
|
|
||||||
cy.get('[data-cy=remove-from-class]').first().click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=modal-save-button]').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 1);
|
|
||||||
cy.getByDataCy('inactive-member').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.get('[data-cy=add-to-class]').first().click();
|
|
||||||
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 2);
|
|
||||||
|
|
||||||
cy.get('[data-cy=inactive-class-members-list]').should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display old classes', () => {
|
|
||||||
let oldClasses = me.me.schoolClasses;
|
|
||||||
let OldClassesQuery = {
|
|
||||||
me: {
|
|
||||||
...me.me,
|
|
||||||
oldClasses,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: me,
|
|
||||||
OldClassesQuery,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/old-classes');
|
|
||||||
|
|
||||||
cy.get('[data-cy=old-class-item]').should('have.length', 1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Teacher Class Management', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('changes class name', () => {
|
|
||||||
let className = 'Gotta have class';
|
|
||||||
|
|
||||||
const {me: teacher} = getMinimalMe({});
|
|
||||||
|
|
||||||
let localMe = {
|
|
||||||
me: teacher,
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: localMe,
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: {
|
|
||||||
...teacher,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
UpdateSchoolClass: {
|
|
||||||
updateSchoolClass: {
|
|
||||||
success: true,
|
|
||||||
schoolClass: {
|
|
||||||
name: className,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
|
|
||||||
cy.get('[data-cy=edit-group-name-link]').click();
|
|
||||||
cy.get('[data-cy=edit-name-input] input').type('{selectall}{backspace}').type(className);
|
|
||||||
cy.get('[data-cy=modal-save-button]').click();
|
|
||||||
cy.get('[data-cy=group-list-name]').should('contain', className);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('removes student, then leaves class, then rejoins', () => {
|
|
||||||
const myId = btoa('PrivateUserNode:1');
|
|
||||||
const memberId = btoa('GroupMemberNode:1');
|
|
||||||
let classMembers = [
|
|
||||||
{...teacher, id: myId, isMe: true, isTeacher: true},
|
|
||||||
...members,
|
|
||||||
];
|
|
||||||
let me = () => ({
|
|
||||||
...teacher,
|
|
||||||
id: memberId,
|
|
||||||
selectedClass: {
|
|
||||||
name: 'Just some class',
|
|
||||||
id: 'selectedClassId',
|
|
||||||
readOnly: false,
|
|
||||||
members: classMembers,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {
|
|
||||||
me: me(),
|
|
||||||
},
|
|
||||||
AddRemoveMember: {
|
|
||||||
addRemoveMember: {
|
|
||||||
success: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: {
|
|
||||||
me: me(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 3);
|
|
||||||
cy.getByDataCy('remove-from-class').first().click();
|
|
||||||
cy.getByDataCy('deactivate-person-modal').should('exist');
|
|
||||||
cy.getByDataCy('modal-body-text').should('contain', 'deaktivieren');
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 2);
|
|
||||||
cy.getByDataCy('leave-group').click();
|
|
||||||
cy.getByDataCy('deactivate-person-modal').should('exist');
|
|
||||||
cy.getByDataCy('modal-body-text').should('contain', 'verlassen');
|
|
||||||
cy.getByDataCy('modal-save-button').click();
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 1);
|
|
||||||
cy.getByDataCy('rejoin-class').click();
|
|
||||||
cy.getByDataCy('active-member').should('have.length', 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('creates a new class', () => {
|
|
||||||
const name = 'Hill Valley';
|
|
||||||
let selectedClass = teacher.selectedClass;
|
|
||||||
|
|
||||||
const schoolClasses = [
|
|
||||||
teacher.selectedClass,
|
|
||||||
];
|
|
||||||
|
|
||||||
const me = () => ({
|
|
||||||
...teacher,
|
|
||||||
selectedClass,
|
|
||||||
schoolClasses,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: () => ({
|
|
||||||
me: me(),
|
|
||||||
}),
|
|
||||||
MySchoolClassQuery: () => ({
|
|
||||||
me: me(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
|
||||||
if (hasOperationName(req, 'CreateSchoolClass')) {
|
|
||||||
const schoolClass = {
|
|
||||||
__typename: 'SchoolClassNode',
|
|
||||||
id: 'newSchoolClassId',
|
|
||||||
name,
|
|
||||||
readOnly: false,
|
|
||||||
};
|
|
||||||
schoolClasses.push(schoolClass);
|
|
||||||
selectedClass = schoolClass;
|
|
||||||
req.reply({
|
|
||||||
data: {
|
|
||||||
createSchoolClass: {
|
|
||||||
result: schoolClass
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
|
|
||||||
cy.get('h1').should('exist');
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.get('[data-cy=create-class-link]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-form-input]').type(name);
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-form-confirm]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=close-profile-sidebar-link]').click();
|
|
||||||
cy.get('[data-cy=group-list-name]').should('contain', name);
|
|
||||||
cy.get('[data-cy=current-class-name]').should('contain', name);
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
cy.get('[data-cy=class-selection-entry]').should('have.length', 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('tries to create a new class with duplicate name', () => {
|
|
||||||
const name = 'Hill Billy Valley';
|
|
||||||
let selectedClass = teacher.selectedClass;
|
|
||||||
selectedClass.name = 'Some stupid class';
|
|
||||||
|
|
||||||
const schoolClasses = [
|
|
||||||
teacher.selectedClass,
|
|
||||||
];
|
|
||||||
|
|
||||||
const me = () => ({
|
|
||||||
...teacher,
|
|
||||||
selectedClass,
|
|
||||||
schoolClasses,
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: () => ({
|
|
||||||
me: me(),
|
|
||||||
}),
|
|
||||||
WhateverNode() {
|
|
||||||
console.log('Through here');
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
MySchoolClassQuery: () => ({
|
|
||||||
me: me(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// since recently, graphql requests can be intercepted by cypress
|
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
|
||||||
if (hasOperationName(req, 'CreateSchoolClass')) {
|
|
||||||
req.reply({
|
|
||||||
data: {
|
|
||||||
createSchoolClass: {
|
|
||||||
result: {
|
|
||||||
__typename: 'DuplicateName',
|
|
||||||
reason: 'Dieser Name wird bereits verwendet.'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.visit('/me/my-class');
|
|
||||||
|
|
||||||
cy.get('h1').should('exist');
|
|
||||||
|
|
||||||
cy.get('[data-cy=header-user-widget]').within(() => {
|
|
||||||
cy.get('[data-cy=user-widget-avatar]').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('[data-cy=class-selection]').click();
|
|
||||||
cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
|
|
||||||
|
|
||||||
cy.get('[data-cy=create-class-link]').click();
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-form-input]').type(name);
|
|
||||||
|
|
||||||
cy.get('[data-cy=join-form-confirm]').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('join-form-input-error').should('contain', 'Dieser Name wird bereits verwendet.');
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
import {getMinimalMe} from '../../../support/helpers';
|
|
||||||
import {hasOperationName} from '../../../support/graphql';
|
|
||||||
|
|
||||||
const teacher = getMinimalMe();
|
|
||||||
|
|
||||||
const mockCreateTeamCall = (name) => {
|
|
||||||
cy.intercept('POST', '/api/graphql', (req) => {
|
|
||||||
if (hasOperationName(req, 'CreateTeamMutation')) {
|
|
||||||
let result;
|
|
||||||
if (name) {
|
|
||||||
result = {
|
|
||||||
__typename: 'TeamNode',
|
|
||||||
id: 'newTeamId',
|
|
||||||
name,
|
|
||||||
code: 'ABC',
|
|
||||||
members: [],
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
result = {
|
|
||||||
__typename: 'DuplicateName',
|
|
||||||
reason: 'Dieser Name wird bereits verwendet.'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
req.reply({
|
|
||||||
data: {
|
|
||||||
createTeam: {
|
|
||||||
result,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Team', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.setup();
|
|
||||||
cy.mockGraphqlOps({
|
|
||||||
operations: {
|
|
||||||
MeQuery: {
|
|
||||||
me: {
|
|
||||||
...teacher,
|
|
||||||
team: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('creates a new team', () => {
|
|
||||||
const name = 'Team Böhmi';
|
|
||||||
|
|
||||||
mockCreateTeamCall(name);
|
|
||||||
|
|
||||||
cy.visit('/me/team');
|
|
||||||
|
|
||||||
cy.getByDataCy('create-team-button').click();
|
|
||||||
cy.getByDataCy('join-form-input').type(name);
|
|
||||||
cy.getByDataCy('join-form-confirm').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('group-list-name').should('contain', name);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('tries to create team but fails due to duplicate name', () => {
|
|
||||||
const name = 'Gibt\'s schon';
|
|
||||||
|
|
||||||
mockCreateTeamCall(false);
|
|
||||||
cy.visit('/me/team');
|
|
||||||
|
|
||||||
cy.getByDataCy('create-team-button').click();
|
|
||||||
cy.getByDataCy('join-form-input').type(name);
|
|
||||||
cy.getByDataCy('join-form-confirm').click();
|
|
||||||
|
|
||||||
cy.getByDataCy('join-form-input-error').should('contain', 'Dieser Name wird bereits verwendet.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -138,10 +138,28 @@ Cypress.Commands.add('setup', () => {
|
||||||
cy.mockGraphql();
|
cy.mockGraphql();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const typenameResolver = {
|
||||||
|
__resolveType(obj, context, info) {
|
||||||
|
return obj.__typename;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Cypress.Commands.add('mockGraphql', (options?: any) => {
|
Cypress.Commands.add('mockGraphql', (options?: any) => {
|
||||||
cy.task('getSchema').then(schemaString => {
|
cy.task('getSchema').then(( schemaString: string ) => {
|
||||||
const schema = makeExecutableSchema({typeDefs: schemaString});
|
const resolverMap = {
|
||||||
const schemaWithMocks = addMocksToSchema({schema, mocks});
|
DeleteSnapshotResult: typenameResolver,
|
||||||
|
UpdateSnapshotResult: typenameResolver
|
||||||
|
};
|
||||||
|
const schema = makeExecutableSchema({
|
||||||
|
typeDefs: schemaString,
|
||||||
|
resolvers: resolverMap
|
||||||
|
});
|
||||||
|
|
||||||
|
const schemaWithMocks = addMocksToSchema({
|
||||||
|
schema,
|
||||||
|
mocks,
|
||||||
|
preserveResolvers: true
|
||||||
|
});
|
||||||
|
|
||||||
let currentOperations = options && options.operations ? options.operations : {};
|
let currentOperations = options && options.operations ? options.operations : {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="snapshot">
|
<div class="snapshot">
|
||||||
<header class="snapshot__header">
|
<header
|
||||||
|
class="snapshot__header"
|
||||||
|
>
|
||||||
<snapshot-header
|
<snapshot-header
|
||||||
:snapshot="snapshot"
|
:snapshot="snapshot"
|
||||||
|
v-if="snapshot"
|
||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<module
|
<module
|
||||||
:module="snapshot"
|
:module="snapshot"
|
||||||
class="snapshot__module"
|
class="snapshot__module"
|
||||||
|
v-if="module"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue