diff --git a/src/__tests__/rubric-defaults.spec.ts b/src/__tests__/rubric-defaults.spec.ts
deleted file mode 100644
index 409a45c..0000000
--- a/src/__tests__/rubric-defaults.spec.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { addRubric } from '../rubric-defaults';
-import { PieContent } from '../interface';
-
-let pieContent: PieContent = {
- id: '1',
- elements: {
- 'pie-rubric': '@pie-element/rubric@latest'
- },
- models: [
- {
- id: 'x',
- element: 'pie-rubric'
- }
- ],
- markup: 'markup here'
-}
-
-describe('rubric defaults', () => {
-
- it('adds rubric to markup', () => {
- const handled = addRubric(pieContent);
- expect(handled.markup).toMatch(/pie-rubric/)
- });
-
- it('do nothing if in markup', () => {
- const content = {...pieContent, markup: ''};
- const handled = addRubric(content);
- expect(handled).toEqual(content);
- });
-
-
- it('do nothing if no rubric', () => {
- const content = {
- id: '1',
- elements: {
- 'pie-rubric': '@pie-element/something-else@latest'
- },
- models: [
- {
- id: 'x',
- element: 'pie-rubric'
- }
- ],
- markup: 'markup here'
- };
- const handled = addRubric(content);
- expect(handled).toEqual(content);
- });
-});
\ No newline at end of file
diff --git a/src/__tests__/rubric-utils.spec.ts b/src/__tests__/rubric-utils.spec.ts
new file mode 100644
index 0000000..70a9947
--- /dev/null
+++ b/src/__tests__/rubric-utils.spec.ts
@@ -0,0 +1,95 @@
+import { addRubric, addPackageToContent } from '../rubric-utils';
+import { PieContent, PieModel } from '../interface';
+import cloneDeep from 'lodash/cloneDeep'
+
+
+
+describe('rubric utils', () => {
+
+ let pieContent:PieContent, noRubric:PieContent;
+ let rubricModel: PieModel;
+ beforeEach(() => {
+ pieContent = {
+ id: '1',
+ elements: {
+ 'pie-rubric': '@pie-element/rubric@latest'
+ },
+ models: [
+ {
+ id: 'x',
+ element: 'pie-rubric'
+ }
+ ],
+ markup: 'markup here'
+ };
+
+ noRubric = {
+ id: '1',
+ elements: {
+ 'something-else': '@pie-element/something-else@latest'
+ },
+ models: [
+ {
+ id: 'x',
+ element: 'something-else'
+ }
+ ],
+ markup: 'markup here'
+ };
+
+ rubricModel = {
+ "id": "rubric",
+ "element": "pie-rubric",
+ "points": [
+ "level 1",
+ "level 2",
+ "level 3",
+ "level 4"
+ ],
+ "maxPoints": 4,
+ "excludeZero": false
+ }
+
+
+ });
+
+ describe('add rubric to markup', () => {
+ it('adds rubric to markup', () => {
+ const handled = addRubric(pieContent);
+ expect(handled.markup).toMatch(/pie-rubric/);
+ });
+
+ it('do nothing if in markup', () => {
+ const content = {
+ ...pieContent,
+ markup: ''
+ };
+ const handled = addRubric(content);
+ expect(handled).toEqual(content);
+ });
+
+ it('do nothing if no rubric', () => {
+ const handled = addRubric(noRubric);
+ expect(handled).toEqual(noRubric);
+ });
+ });
+
+ describe('add rubric to model', () => {
+ it('adds a rubric to a model', () => {
+ addPackageToContent(noRubric, '@pie-element/rubric', rubricModel);
+ expect(Object.values(noRubric.elements)).toContain('@pie-element/rubric')
+ });
+
+ it('does not modify if rubric already there', () => {
+ const copy = cloneDeep(pieContent);
+ addPackageToContent(pieContent, '@pie-element/rubric', rubricModel);
+ expect(copy).toEqual(pieContent);
+ });
+
+ it('works with semver', () => {
+ addPackageToContent(noRubric, '@pie-element/rubric@latest', rubricModel);
+ expect(Object.values(noRubric.elements)).toContain('@pie-element/rubric@latest')
+ });
+ });
+
+});
diff --git a/src/components.d.ts b/src/components.d.ts
index 83137df..67ba1e4 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -24,6 +24,14 @@ export namespace Components {
*/
'addPreview': boolean;
/**
+ * If set the player will add a rubric authoring interaction to the config
+ */
+ 'addRubric': boolean;
+ /**
+ * Utility method to add a `@pie-element/rubric` section to an item config when creating an item should be used before setting the config.
+ */
+ 'addRubricToConfig': (config: ItemConfig, rubricModel?: any) => Promise;
+ /**
* The Pie config model.
*/
'config': ItemConfig;
@@ -38,6 +46,10 @@ export namespace Components {
*/
'addPreview'?: boolean;
/**
+ * If set the player will add a rubric authoring interaction to the config
+ */
+ 'addRubric'?: boolean;
+ /**
* The Pie config model.
*/
'config'?: ItemConfig;
diff --git a/src/components/__tests__/mockPieCloudResponse.js b/src/components/__tests__/mockPieCloudResponse.js
index 8d61561..917c6f5 100644
--- a/src/components/__tests__/mockPieCloudResponse.js
+++ b/src/components/__tests__/mockPieCloudResponse.js
@@ -61,6 +61,8 @@ class InlineChoiceConfig extends MockConfig {}
class MathInline extends MockElement {}
class MathInlineConfig extends MockConfig {}
class Passage extends MockElement {}
+class Rubric extends MockElement {}
+class RubricConfig extends MockConfig {}
@@ -81,6 +83,11 @@ window['pie'] = {
Configure: MathInlineConfig,
controller
},
+ '@pie-element/rubric': {
+ Element: Rubric,
+ Configure: RubricConfig,
+ controller
+ },
'@pie-element/passage': {
Element: Passage
}
diff --git a/src/components/pie-author/__tests__/pie-author.e2e.ts b/src/components/pie-author/__tests__/pie-author.e2e.ts
index 430aac6..1646ffc 100644
--- a/src/components/pie-author/__tests__/pie-author.e2e.ts
+++ b/src/components/pie-author/__tests__/pie-author.e2e.ts
@@ -1,13 +1,17 @@
import { newE2EPage, E2EElement, E2EPage } from '@stencil/core/testing';
import { setupInterceptPieCloud } from '../../__tests__/util';
import { simplePieMock, multipleChoiceItem, inlineChoiceItem } from '../../__mock__/config';
+import cloneDeep from 'lodash/cloneDeep';
describe('pie-author', () => {
let pie;
let page: E2EPage, pieAuthor: E2EElement;
+ let pieMock
beforeEach(async () => {
pie = '@pie-element/multiple-choice';
- page = await newE2EPage()
+ page = await newE2EPage();
+ pieMock = cloneDeep(simplePieMock);
+
});
it('renders', async () => {
@@ -21,7 +25,7 @@ describe('pie-author', () => {
await page.setContent('');
pieAuthor = await page.find('pie-author');
await setupInterceptPieCloud(page, pie);
- pieAuthor.setProperty('config', simplePieMock)
+ pieAuthor.setProperty('config', pieMock)
await page.waitForChanges();
const el = await page.waitForSelector('pie-author');
expect(el).toBeDefined();
@@ -35,7 +39,7 @@ describe('pie-author', () => {
await page.setContent('');
pieAuthor = await page.find('pie-author');
await setupInterceptPieCloud(page, pie);
- pieAuthor.setProperty('config', simplePieMock)
+ pieAuthor.setProperty('config', pieMock)
const spy = await page.spyOnEvent('modelLoaded');
await page.waitForChanges();
expect(spy).toHaveReceivedEvent();
@@ -46,7 +50,7 @@ describe('pie-author', () => {
await page.setContent('');
pieAuthor = await page.find('pie-author');
await setupInterceptPieCloud(page, pie);
- const emptyItem = simplePieMock;
+ const emptyItem = pieMock;
emptyItem.models = null;
await page.$eval('pie-author',
(elm: any, prop) => {
@@ -74,7 +78,7 @@ describe('pie-author', () => {
return elm;
},
{
- config: simplePieMock,
+ config: pieMock,
configSettings: {'@pie-element/multiple-choice': { "foo": "bar"} }
}
);
@@ -88,6 +92,26 @@ describe('pie-author', () => {
expect(configProp.foo).toEqual("bar");
});
+ it('add a rubric before adding config', async () => {
+ await page.setContent('');
+ pieAuthor = await page.find('pie-author');
+ await setupInterceptPieCloud(page, pie);
+ const rubricAdded = await pieAuthor.callMethod('addRubricToConfig', pieMock, {foo: 'bar'});
+ expect(Object.values(rubricAdded.elements)).toContain('@pie-element/rubric');
+
+ const tagName = Object.keys(rubricAdded.elements)[1];
+
+ pieAuthor.setProperty('config', rubricAdded);
+ await page.waitForChanges();
+ await page.waitForSelector(`pie-author ${tagName}-config:defined`);
+ const rubricModel = await page.$eval(
+ `pie-author ${tagName}-config`,
+ el => (el as any).model
+ );
+ expect(rubricModel.foo).toEqual('bar');
+
+ });
+
// TODO request intercetpion needs to be updated for this to work
it.skip('can switch items', async() => {
await page.setContent('');
@@ -102,7 +126,6 @@ describe('pie-author', () => {
);
expect(pieModel.element).toEqual('pie-multiple-choice');
- console.log(`got past first item`)
await setupInterceptPieCloud(page, `@pie-element/inline-choice`);
pieAuthor.setProperty('config', inlineChoiceItem);
await page.waitForChanges();
diff --git a/src/components/pie-author/pie-author.tsx b/src/components/pie-author/pie-author.tsx
index 9547f39..a184fea 100644
--- a/src/components/pie-author/pie-author.tsx
+++ b/src/components/pie-author/pie-author.tsx
@@ -1,10 +1,11 @@
-import { Component, Element, Prop, State, Watch, Event, EventEmitter } from '@stencil/core';
-import { PieContent, ItemConfig, PieElement } from '../../interface';
+import { Component, Element, Prop, State, Watch, Event, EventEmitter, Method } from '@stencil/core';
+import { PieContent, ItemConfig, PieElement, PieModel } from '../../interface';
import { PieLoader } from '../../pie-loader';
import { pieContentFromConfig } from '../../utils/utils';
import parseNpm from 'parse-package-name';
import { ModelUpdatedEvent } from '@pie-framework/pie-configure-events';
import _isEqual from 'lodash/isEqual';
+import { addPackageToContent, addRubric } from '../../rubric-utils';
/**
* Pie Author will load a Pie Content model for authoring.
@@ -18,6 +19,13 @@ import _isEqual from 'lodash/isEqual';
export class Author {
@Prop({ context: 'document' }) doc!: Document;
+
+ /**
+ * If set the player will add a rubric authoring interaction to the config
+ */
+ @Prop() addRubric: boolean;
+
+
/**
* Adds a preview view which will render the content in another tab as it may appear to a student or instructor.
*/
@@ -161,7 +169,6 @@ export class Author {
await this.afterRender();
await this.updateModels();
this.el.addEventListener(ModelUpdatedEvent.TYPE, (e:ModelUpdatedEvent) => {
- console.log(`got event ${e.detail}`)
// set the internal model
// emit a content-item level event with the model
if (this.pieContentModel && e.update) {
@@ -197,6 +204,36 @@ export class Author {
}
}
+ /**
+ * Utility method to add a `@pie-element/rubric` section to an item config when creating an item should be used before setting the config.
+ *
+ * @deprecated this method is for temporary use, will be removed at next major release
+ *
+ * @param config the item config to mutate
+ * @param rubricModel
+ */
+ @Method()
+ async addRubricToConfig(config: ItemConfig, rubricModel?) {
+ if (!rubricModel) {
+ rubricModel = {
+ "id": "rubric",
+ "element": "pie-rubric",
+ "points": [
+ "",
+ "",
+ "",
+ ""
+ ],
+ "maxPoints": 4,
+ "excludeZero": false
+ };
+ }
+ const configPieContent = pieContentFromConfig(config);
+ addPackageToContent(configPieContent, '@pie-element/rubric', rubricModel as PieModel);
+ addRubric(configPieContent);
+ return config;
+ }
+
render() {
if (this.pieContentModel && this.pieContentModel.markup) {
if (this.addPreview) {
diff --git a/src/components/pie-author/readme.md b/src/components/pie-author/readme.md
index 451c5f9..27ba258 100644
--- a/src/components/pie-author/readme.md
+++ b/src/components/pie-author/readme.md
@@ -16,6 +16,7 @@ The class `pie-loading` will be added to the element while assets are being load
| Property | Attribute | Description | Type | Default |
| ---------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ----------- |
| `addPreview` | `add-preview` | Adds a preview view which will render the content in another tab as it may appear to a student or instructor. | `boolean` | `false` |
+| `addRubric` | `add-rubric` | If set the player will add a rubric authoring interaction to the config | `boolean` | `undefined` |
| `config` | -- | The Pie config model. | `AdvancedItemConfig \| PieContent` | `undefined` |
| `configSettings` | -- | To customize the standard behaviour provided by interaction configuration views you can provide settings key-ed by the package name. e.g. `{ '@pie-element/inline-choice': { promptLabel: 'Item Stem' } }` The settings that are configurable for each authoring view are documented in the `@package-name/docs` folder for each package. | `{ [packageName: string]: Object; }` | `undefined` |
@@ -28,6 +29,26 @@ The class `pie-loading` will be added to the element while assets are being load
| `modelUpdated` | Emmitted when the model for the content has been updated within the ui due to user action. | `CustomEvent` |
+## Methods
+
+### `addRubricToConfig(config: ItemConfig, rubricModel?: any) => Promise`
+
+Utility method to add a `@pie-element/rubric` section to an item config when creating an item should be used before setting the config.
+
+#### Parameters
+
+| Name | Type | Description |
+| ------------- | ---------------------------------- | ------------------------- |
+| `config` | `AdvancedItemConfig \| PieContent` | the item config to mutate |
+| `rubricModel` | `any` | |
+
+#### Returns
+
+Type: `Promise`
+
+
+
+
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*
diff --git a/src/components/pie-player/pie-player.tsx b/src/components/pie-player/pie-player.tsx
index ddc9587..363bd80 100644
--- a/src/components/pie-player/pie-player.tsx
+++ b/src/components/pie-player/pie-player.tsx
@@ -10,7 +10,7 @@ import {
} from '@stencil/core';
import { PieContent, ItemConfig, ItemSession, PieElement, PieController, AdvancedItemConfig, PieModel} from '../../interface';
import { PieLoader } from '../../pie-loader';
-import { addRubric } from '../../rubric-defaults';
+import { addRubric } from '../../rubric-utils';
const controllerErrorMessage: string = 'Error processing question configuration, verify the question model?';
diff --git a/src/demo/config-preview.html b/src/demo/config-preview.html
index 34c7c33..81e880d 100644
--- a/src/demo/config-preview.html
+++ b/src/demo/config-preview.html
@@ -84,8 +84,11 @@
markup: ""
};
-
- author.config = config;
+ author.componentOnReady().then(() => {
+ author.addRubricToConfig(config).then(newConf => {
+ author.config = newConf;
+ })
+ });
+
+
+
+
diff --git a/src/demo/item-author-add-rubric.html b/src/demo/item-author-add-rubric.html
new file mode 100644
index 0000000..2c0a10c
--- /dev/null
+++ b/src/demo/item-author-add-rubric.html
@@ -0,0 +1,88 @@
+
+
+