Skip to content

Commit

Permalink
Merge pull request #46 from dmols/questionBank_functionality
Browse files Browse the repository at this point in the history
Question bank functionality
  • Loading branch information
clpetersonucf authored Apr 16, 2024
2 parents a8badba + fbd3378 commit 046799c
Show file tree
Hide file tree
Showing 9 changed files with 1,088 additions and 823 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
],
"coverageThreshold": {
"global": {
"statements": 92,
"statements": 91,
"branches": 76,
"functions": 93,
"lines": 93
"lines": 92
}
}
},
Expand Down
8 changes: 8 additions & 0 deletions src/controllers/__snapshots__/creator.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ Object {
"name": "null",
},
],
"options": Object {
"enableQuestionBank": false,
"questionBankVal": 1,
},
}
`;

Expand Down Expand Up @@ -119,6 +123,10 @@ Object {
"name": "null",
},
],
"options": Object {
"enableQuestionBank": false,
"questionBankVal": 1,
},
}
`;

Expand Down
37 changes: 26 additions & 11 deletions src/controllers/creator.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ Matching.controller 'matchingCreatorCtrl', ['$scope', '$sce', ($scope, $sce) ->

$scope.acceptedMediaTypes = ['mp3']
audioRef = []
$scope.questionBankDialog = false
$scope.enableQuestionBank = false
$scope.questionBankValTemp = 1
$scope.questionBankVal = 1

$scope.autoSize = (pair, audio) ->
question = pair.question or ''
answer = pair.answer or ''
len = if question.length > answer.length then question.length else answer.length
if audio == true
size = if len > 15 then 85 + len * 1.1 else 85
else
size = if len > 15 then 25 + len * 1.1 else 25
height: size + 'px'

# Adds and removes a pair of textareas for users to input a word pair.
$scope.addWordPair = (q=null, a=null, media=[0,0], id='') ->
Expand All @@ -28,6 +42,11 @@ Matching.controller 'matchingCreatorCtrl', ['$scope', '$sce', ($scope, $sce) ->
materiaCallbacks.initExistingWidget = (title, widget, qset, version, baseUrl) ->
_items = qset.items[0].items

if qset.options
$scope.enableQuestionBank = if qset.options.enableQuestionBank then qset.options.enableQuestionBank else false
$scope.questionBankVal = if qset.options.questionBankVal then qset.options.questionBankVal else 1
$scope.questionBankValTemp = if qset.options.questionBankVal then qset.options.questionBankVal else 1

$scope.$apply ->
$scope.widget.title = title
$scope.widget.wordPairs = []
Expand Down Expand Up @@ -77,22 +96,17 @@ Matching.controller 'matchingCreatorCtrl', ['$scope', '$sce', ($scope, $sce) ->
$scope.hideCover()

$scope.hideCover = ->
$scope.showTitleDialog = $scope.showIntroDialog = $scope.showErrorDialog = false

$scope.autoSize = (pair, audio) ->
question = pair.question or ''
answer = pair.answer or ''
len = if question.length > answer.length then question.length else answer.length
if audio == true
size = if len > 15 then 85 + len * 1.1 else 85
else
size = if len > 15 then 25 + len * 1.1 else 25
height: size + 'px'
$scope.showTitleDialog = $scope.showIntroDialog = $scope.showErrorDialog = $scope.questionBankDialog = false
$scope.questionBankValTemp = $scope.questionBankVal

$scope.audioUrl = (assetId) ->
# use $sce.trustAsResourceUrl to avoid interpolation error
$sce.trustAsResourceUrl Materia.CreatorCore.getMediaUrl(assetId + ".mp3")

$scope.validateQuestionBankVal = ->
if ($scope.questionBankValTemp >= 1 && $scope.questionBankValTemp <= $scope.widget.wordPairs.length)
$scope.questionBankVal = $scope.questionBankValTemp

# prevents duplicate ids
createUniqueAudioAnswerId = () ->
uniqueId = 0
Expand All @@ -116,6 +130,7 @@ Matching.controller 'matchingCreatorCtrl', ['$scope', '$sce', ($scope, $sce) ->

_buildSaveData = ->
_qset.items = []
_qset.options = {enableQuestionBank: $scope.enableQuestionBank, questionBankVal: $scope.questionBankVal}
_qset.items[0] =
name: "null"
items: []
Expand Down
30 changes: 30 additions & 0 deletions src/controllers/creator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,36 @@ describe('Matching Creator Controller', function(){
// expect($scope.widget.wordPairs[2].media[1]).toBe('testId2');
});

it('should give default qset options if question bank options are undefined', function () {

qset.data.options = {};
materiaCallbacks.initExistingWidget('matcher', widgetInfo, qset.data);

expect($scope.enableQuestionBank).toBe(false);
expect($scope.questionBankVal).toBe(1);
expect($scope.questionBankValTemp).toBe(1);
});

it('should update questionBankVal if questionBankValTemp is valid within the range', function () {

qset.data.options = {enableQuestionBank: true, questionBankVal: 6};
materiaCallbacks.initExistingWidget('matcher', widgetInfo, qset.data);

// set initial values where questionBankValTemp is invalid
$scope.questionBankValTemp = 11;
$scope.validateQuestionBankVal();

// expect questionBankVal to change to wordPairs value
expect($scope.questionBankVal).toBe(6);

// this time questionBankValTemp is valid
$scope.questionBankValTemp = 8;
$scope.validateQuestionBankVal();

// expect questionBankVal to be updated to questionBankValTemp
expect($scope.questionBankVal).toBe(8);

});

it('should autosize correctly', function () {
var lessThan15chars = 'small';
Expand Down
9 changes: 9 additions & 0 deletions src/controllers/player.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
materiaCallbacks.start = (instance, qset) ->
$scope.qset = qset
$scope.title = instance.name

# Update qset items to only include the number of questions specified in the question bank. Done here since $scope.totalItems depends on it.
if qset.options && qset.options.enableQuestionBank
_shuffle qset.items[0].items
qbItemsLength = qset.options.questionBankVal
rndStart = Math.floor(Math.random() * (qset.items[0].items.length - qbItemsLength + 1))
qset.items[0].items = qset.items[0].items.slice(rndStart, rndStart + qbItemsLength)

$scope.totalItems = qset.items[0].items.length
$scope.totalPages = Math.ceil $scope.totalItems/ITEMS_PER_PAGE

Expand All @@ -62,6 +70,7 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
_itemIndex = 0
_pageIndex = 0
_indexShift = 0

# Splits the the last items over the last two pages
_leftover = $scope.totalItems % ITEMS_PER_PAGE
_splitPoint = ~~(4 + (_leftover - 1)/2)
Expand Down
18 changes: 18 additions & 0 deletions src/controllers/player.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ describe('Matching Player Controller', function(){
expect($scope.showInstructions).toBe(true);
});

it('should slice the qset if qb is enabled', function () {

// Enable question bank and set the number of questions to 3
qset.data.options = {enableQuestionBank: true, questionBankVal: 3}

materiaCallbacks.start(widgetInfo, qset.data);

// qset should be sliced to the length given by questionBankVal
expect(qset.data.items[0].items.length).toEqual(3);
});

it('should change to the previous page', inject(function ($timeout) {
materiaCallbacks.start(widgetInfo, qset.data);
Materia.Engine.getImageAssetUrl
Expand Down Expand Up @@ -476,6 +487,13 @@ describe('Matching Player Controller', function(){
expect($scope.pages[0].answers[0].text).toEqual('to change');
});

it('should return 0 progress when no items have been matched', function () {

materiaCallbacks.start(widgetInfo, qset.data);
$scope.totalItems = 0;
expect($scope.getProgressAmount()).toBe(0);
});

it('should correctly report the text of a match', function() {
materiaCallbacks.start(widgetInfo, qset.data);
setupQA();
Expand Down
36 changes: 34 additions & 2 deletions src/creator.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
<div class='logo'></div>
<h1 id='title' ng-bind='widget.title' ng-click='showTitleDialog = true'></h1>
<div class='link' ng-click='showTitleDialog = true'>Edit...</div>
<button
class="qb-button"
ng-click="questionBankDialog = true"
ng-disabled="widget.wordPairs.length < 1"
ng-class="{'gray-out': enableQuestionBank !== true}">
Question Bank: {{enableQuestionBank === true ? "On" : "Off"}}
</button>
<div class='bottom'></div>
</div>
<section class='main-area'>
Expand Down Expand Up @@ -167,10 +174,9 @@ <h1>Right Side</h1>
Add Pair
</button>
</section>

<div id='backgroundcover'
ng-click='hideCover()'
ng-class='{ show: showTitleDialog || showIntroDialog || showErrorDialog }'>
ng-class='{ show: showTitleDialog || showIntroDialog || showErrorDialog || questionBankDialog }'>
</div>
<div class='box intro'
ng-class='{ show: showIntroDialog }'>
Expand Down Expand Up @@ -210,6 +216,32 @@ <h1>Matching</h1>
value='Okay'
ng-click='hideCover()'>
</div>
<div class="box question-bank-dialog"
ng-class= '{ show: questionBankDialog }'
ng-click= 'hideCover()'>
<div class="enable-qb-question">
<label style="font-weight: bold;">Enable question bank? </label>
<div class="enable-qb-options"
ng-click="$event.stopPropagation()">
<span>
<input type="radio" ng-model="enableQuestionBank" ng-value=false> No</input>
<input type="radio" ng-model="enableQuestionBank" ng-value=true ng-change="questionBankVal = widget.wordPairs.length; questionBankValTemp = widget.wordPairs.length"> Yes</input>
</span>
</div>
</div>
<div>
<span ng-show="enableQuestionBank" >
<label style="font-weight: bold;">How many questions to ask? </label>
<div class="num-input-wrapper"
ng-click="$event.stopPropagation()">
<input class="num-input" type="number" ng-model="questionBankValTemp" ng-change="validateQuestionBankVal()" step="1">
<span> out of {{widget.wordPairs.length}} </span>
</div>
</span>
</div>
<p class="qb-warning">If question bank is enabled, questions will be randomized. </p>
<button class="dialog-close-button" ng-disabled="questionBankValTemp < 1 || questionBankValTemp > widget.wordPairs.length" ng-click="questionBankDialog = false">Confirm</button>
</div>
<div class='arrow_box'
ng-show='!widget.wordPairs.length && step'>
<span>Click here to add your first pair</span>
Expand Down
Loading

0 comments on commit 046799c

Please sign in to comment.