Add cypress test for read only portfolio
This commit is contained in:
parent
1792fe9bf1
commit
dc43b88916
|
|
@ -0,0 +1,44 @@
|
||||||
|
import {getMinimalMe} from '../../../support/helpers';
|
||||||
|
|
||||||
|
const getOperations = ({readOnly = false}) => ({
|
||||||
|
MeQuery: getMinimalMe({readOnly}),
|
||||||
|
ProjectsQuery: {
|
||||||
|
projects: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
id: 'projectId',
|
||||||
|
final: false,
|
||||||
|
student: {
|
||||||
|
id: 'meId',
|
||||||
|
},
|
||||||
|
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('add-project-button').should('exist');
|
||||||
|
cy.getByDataCy('project-widget').should('have.length', 1);
|
||||||
|
cy.getByDataCy('project-widget-actions').should('exist');
|
||||||
|
});
|
||||||
|
it('Can not create and edit project', () => {
|
||||||
|
cy.mockGraphqlOps({operations: getOperations({readOnly: true})});
|
||||||
|
|
||||||
|
cy.visit('/portfolio');
|
||||||
|
cy.getByDataCy('add-project-button').should('not.exist');
|
||||||
|
cy.getByDataCy('project-widget').should('have.length', 1);
|
||||||
|
cy.getByDataCy('project-widget-actions').should('not.exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import {getMinimalMe} from '../../../support/helpers';
|
||||||
|
|
||||||
|
const getOperations = ({readOnly = false}) => ({
|
||||||
|
MeQuery: getMinimalMe({readOnly}),
|
||||||
|
ProjectQuery: {
|
||||||
|
project: {
|
||||||
|
id: 'projectId',
|
||||||
|
final: false,
|
||||||
|
student: {
|
||||||
|
id: 'meId',
|
||||||
|
},
|
||||||
|
entriesCount: 3,
|
||||||
|
entries: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const testProject = (readOnly, shouldActionsExist) => {
|
||||||
|
cy.mockGraphqlOps({operations: getOperations({readOnly})});
|
||||||
|
|
||||||
|
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', () => {
|
||||||
|
testProject(true, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import getMe from '../../fixtures/me.minimal';
|
|
||||||
import module from '../../fixtures/module.minimal';
|
import module from '../../fixtures/module.minimal';
|
||||||
import mocks from '../../fixtures/mocks';
|
import mocks from '../../fixtures/mocks';
|
||||||
import {getMinimalMe} from '../../support/helpers';
|
import {getMinimalMe} from '../../support/helpers';
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
export const getMinimalMe = ({readOnly = false, classReadOnly = false, isTeacher = true}) => ({
|
export const getMinimalMe = ({readOnly = false, classReadOnly = false, isTeacher = true}) => ({
|
||||||
me: {
|
me: {
|
||||||
|
id: 'meId',
|
||||||
onboardingVisited: true,
|
onboardingVisited: true,
|
||||||
readOnly,
|
readOnly,
|
||||||
isTeacher,
|
isTeacher,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="project-actions">
|
<div
|
||||||
|
class="project-actions"
|
||||||
|
data-cy="project-actions">
|
||||||
<a
|
<a
|
||||||
class="project-actions__more-link"
|
class="project-actions__more-link"
|
||||||
@click="toggleMenu">
|
@click="toggleMenu">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="project-entry">
|
<div
|
||||||
|
class="project-entry"
|
||||||
|
data-cy="project-entry">
|
||||||
<more-options-widget
|
<more-options-widget
|
||||||
class="project-entry__more"
|
class="project-entry__more"
|
||||||
data-cy="project-entry-more">
|
data-cy="project-entry-more"
|
||||||
|
v-if="!readOnly">
|
||||||
<li class="popover-links__link"><a
|
<li class="popover-links__link"><a
|
||||||
data-cy="edit-project-entry"
|
data-cy="edit-project-entry"
|
||||||
@click="editProjectEntry()">Eintrag bearbeiten</a>
|
@click="editProjectEntry()">Eintrag bearbeiten</a>
|
||||||
|
|
@ -48,7 +51,7 @@
|
||||||
import PROJECT_QUERY from '@/graphql/gql/queries/projectQuery.gql';
|
import PROJECT_QUERY from '@/graphql/gql/queries/projectQuery.gql';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['activity', 'reflection', 'nextSteps', 'documentUrl', 'created', 'id'],
|
props: ['activity', 'reflection', 'nextSteps', 'documentUrl', 'created', 'id', 'readOnly'],
|
||||||
components: {
|
components: {
|
||||||
DocumentBlock,
|
DocumentBlock,
|
||||||
MoreOptionsWidget
|
MoreOptionsWidget
|
||||||
|
|
@ -87,9 +90,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "~styles/helpers";
|
||||||
@import "@/styles/_functions.scss";
|
|
||||||
@import "@/styles/_mixins.scss";
|
|
||||||
|
|
||||||
.project-entry {
|
.project-entry {
|
||||||
background-color: $color-white;
|
background-color: $color-white;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="widgetClass"
|
:class="widgetClass"
|
||||||
|
data-cy="project-widget"
|
||||||
class="project-widget">
|
class="project-widget">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{name: 'project', params: {slug: slug}}"
|
:to="{name: 'project', params: {slug: slug}}"
|
||||||
|
|
@ -15,11 +16,13 @@
|
||||||
class="project-widget__owner"/>
|
class="project-widget__owner"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<widget-footer
|
<widget-footer
|
||||||
|
data-cy="project-widget-footer"
|
||||||
class="project-widget__footer"
|
class="project-widget__footer"
|
||||||
v-if="isOwner">
|
v-if="isOwner">
|
||||||
<project-actions
|
<project-actions
|
||||||
:id="id"
|
:id="id"
|
||||||
:final="final"/>
|
:final="final"
|
||||||
|
data-cy="project-widget-actions"/>
|
||||||
</widget-footer>
|
</widget-footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -53,9 +56,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "~styles/helpers";
|
||||||
@import "@/styles/_functions.scss";
|
|
||||||
@import "@/styles/_mixins.scss";
|
|
||||||
|
|
||||||
.project-widget {
|
.project-widget {
|
||||||
border-radius: $default-border-radius;
|
border-radius: $default-border-radius;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ fragment ProjectParts on ProjectNode {
|
||||||
student {
|
student {
|
||||||
firstName
|
firstName
|
||||||
lastName
|
lastName
|
||||||
id,
|
id
|
||||||
avatarUrl
|
avatarUrl
|
||||||
}
|
}
|
||||||
entriesCount
|
entriesCount
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
query ProjectQuery($id: ID, $slug: String){
|
query ProjectQuery($id: ID, $slug: String){
|
||||||
project(slug: $slug, id: $id) {
|
project(slug: $slug, id: $id) {
|
||||||
...ProjectParts
|
...ProjectParts
|
||||||
entries {
|
entries {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
...ProjectEntryParts
|
...ProjectEntryParts
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="portfolio__page">
|
<div class="portfolio__page">
|
||||||
<div class="portfolio">
|
<div class="portfolio">
|
||||||
<add-project class="portfolio__add-project"/>
|
<add-project
|
||||||
|
class="portfolio__add-project"
|
||||||
|
v-if="!me.readOnly"/>
|
||||||
|
|
||||||
<project-widget
|
<project-widget
|
||||||
v-bind="project"
|
v-bind="project"
|
||||||
|
|
@ -56,7 +58,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/styles/_variables.scss";
|
@import "~styles/helpers";
|
||||||
|
|
||||||
.portfolio {
|
.portfolio {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
:class="specialContainerClass"
|
:class="specialContainerClass"
|
||||||
class="project">
|
class="project">
|
||||||
<div class="project__header">
|
<div class="project__header">
|
||||||
<h1 class="project__title">{{ project.title }}</h1>
|
<h1
|
||||||
|
class="project__title"
|
||||||
|
data-cy="project-title">{{ project.title }}</h1>
|
||||||
<p class="project__description">
|
<p class="project__description">
|
||||||
{{ project.description }}
|
{{ project.description }}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -18,7 +20,9 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="project__meta">
|
<div class="project__meta">
|
||||||
<project-actions :id="project.id"/>
|
<project-actions
|
||||||
|
:id="project.id"
|
||||||
|
v-if="!me.readOnly"/>
|
||||||
<owner-widget :owner="project.student"/>
|
<owner-widget :owner="project.student"/>
|
||||||
<entry-count-widget :entry-count="projectEntryCount"/>
|
<entry-count-widget :entry-count="projectEntryCount"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -29,10 +33,11 @@
|
||||||
:project="project.id"
|
:project="project.id"
|
||||||
class="project__add-entry"
|
class="project__add-entry"
|
||||||
data-cy="add-project-entry"
|
data-cy="add-project-entry"
|
||||||
v-if="isOwner"/>
|
v-if="isOwner && !me.readOnly"/>
|
||||||
<project-entry
|
<project-entry
|
||||||
v-bind="entry"
|
v-bind="entry"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
:read-only="me.readOnly"
|
||||||
v-for="(entry, index) in project.entries"/>
|
v-for="(entry, index) in project.entries"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
Page.objects.get(title='Root').delete()
|
Page.objects.get(title='Root').delete()
|
||||||
|
|
||||||
u = UserFactory(
|
UserFactory(
|
||||||
username='test',
|
username='test',
|
||||||
is_staff=True,
|
is_staff=True,
|
||||||
is_superuser=True,
|
is_superuser=True,
|
||||||
|
|
@ -69,20 +69,20 @@ class Command(BaseCommand):
|
||||||
for book_idx, book_data in enumerate(data):
|
for book_idx, book_data in enumerate(data):
|
||||||
book = BookFactory.create(parent=site.root_page, **self.filter_data(book_data, 'topics'))
|
book = BookFactory.create(parent=site.root_page, **self.filter_data(book_data, 'topics'))
|
||||||
|
|
||||||
default_topics = [{} for i in range(0, random.randint(5, 8))]
|
default_topics = [{} for _ in range(0, random.randint(5, 8))]
|
||||||
topics_data = book_data.get('topics', default_topics)
|
topics_data = book_data.get('topics', default_topics)
|
||||||
|
|
||||||
for topic_idx, topic_data in enumerate(topics_data):
|
for topic_idx, topic_data in enumerate(topics_data):
|
||||||
topic = TopicFactory.create(parent=book, **self.filter_data(topic_data, 'modules'))
|
topic = TopicFactory.create(parent=book, **self.filter_data(topic_data, 'modules'))
|
||||||
|
|
||||||
default_modules = [{} for i in range(0, random.randint(3, 6))]
|
default_modules = [{} for _ in range(0, random.randint(3, 6))]
|
||||||
modules_data = topic_data.get('modules', default_modules)
|
modules_data = topic_data.get('modules', default_modules)
|
||||||
|
|
||||||
for module_idx, module_data in enumerate(modules_data):
|
for module_idx, module_data in enumerate(modules_data):
|
||||||
module = ModuleFactory.create(parent=topic,
|
module = ModuleFactory.create(parent=topic,
|
||||||
**self.filter_data(module_data, ['objective_groups', 'chapters']))
|
**self.filter_data(module_data, ['objective_groups', 'chapters']))
|
||||||
|
|
||||||
default_objective_groups = [{} for i in range(0, 2)]
|
default_objective_groups = [{} for _ in range(0, 2)]
|
||||||
objective_group_data = module_data.get('objective_groups', default_objective_groups)
|
objective_group_data = module_data.get('objective_groups', default_objective_groups)
|
||||||
|
|
||||||
for objective_group_idx, objective_group_entry in enumerate(objective_group_data):
|
for objective_group_idx, objective_group_entry in enumerate(objective_group_data):
|
||||||
|
|
@ -91,20 +91,20 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
**factory_params)
|
**factory_params)
|
||||||
|
|
||||||
default_objectives = [{} for i in range(0, 4)]
|
default_objectives = [{} for _ in range(0, 4)]
|
||||||
objectives_data = objective_group_entry.get('objectives', default_objectives)
|
objectives_data = objective_group_entry.get('objectives', default_objectives)
|
||||||
|
|
||||||
for objective_idx, objective_data in enumerate(objectives_data):
|
for objective_idx, objective_data in enumerate(objectives_data):
|
||||||
objective = ObjectiveFactory.create(group=objective_group, **objective_data)
|
ObjectiveFactory.create(group=objective_group, **objective_data)
|
||||||
|
|
||||||
default_chapters = [{} for i in range(0, 2)]
|
default_chapters = [{} for _ in range(0, 2)]
|
||||||
chapters_data = module_data.get('chapters', default_chapters)
|
chapters_data = module_data.get('chapters', default_chapters)
|
||||||
|
|
||||||
for chapter_idx, chapter_data in enumerate(chapters_data):
|
for chapter_idx, chapter_data in enumerate(chapters_data):
|
||||||
chapter = ChapterFactory.create(parent=module,
|
chapter = ChapterFactory.create(parent=module,
|
||||||
**self.filter_data(chapter_data, 'content_blocks'))
|
**self.filter_data(chapter_data, 'content_blocks'))
|
||||||
|
|
||||||
default_content_blocks = [{} for i in range(0, 4)]
|
default_content_blocks = [{} for _ in range(0, 4)]
|
||||||
content_blocks_data = chapter_data.get('content_blocks', default_content_blocks)
|
content_blocks_data = chapter_data.get('content_blocks', default_content_blocks)
|
||||||
|
|
||||||
for content_block_idx, content_block_data in enumerate(content_blocks_data):
|
for content_block_idx, content_block_data in enumerate(content_blocks_data):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue