Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
24707f8f
Commit
24707f8f
authored
May 29, 2013
by
cahrens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Jasmine test for views.
parent
625c6b51
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
329 additions
and
19 deletions
+329
-19
cms/static/coffee/fixtures/metadata-editor.underscore
+2
-0
cms/static/coffee/fixtures/metadata-number-entry.underscore
+2
-0
cms/static/coffee/fixtures/metadata-option-entry.underscore
+2
-0
cms/static/coffee/fixtures/metadata-string-entry.underscore
+2
-0
cms/static/coffee/spec/views/metadata_edit_spec.coffee
+278
-15
cms/static/js/views/metadata_editor_view.js
+43
-4
No files found.
cms/static/coffee/fixtures/metadata-editor.underscore
0 → 120000
View file @
24707f8f
../../../templates/js/metadata-editor.underscore
\ No newline at end of file
cms/static/coffee/fixtures/metadata-number-entry.underscore
0 → 120000
View file @
24707f8f
../../../templates/js/metadata-number-entry.underscore
\ No newline at end of file
cms/static/coffee/fixtures/metadata-option-entry.underscore
0 → 120000
View file @
24707f8f
../../../templates/js/metadata-option-entry.underscore
\ No newline at end of file
cms/static/coffee/fixtures/metadata-string-entry.underscore
0 → 120000
View file @
24707f8f
../../../templates/js/metadata-string-entry.underscore
\ No newline at end of file
cms/static/coffee/spec/views/metadata_edit_spec.coffee
View file @
24707f8f
editorTemplate
=
readFixtures
(
'metadata-editor.underscore'
)
numberEntryTemplate
=
readFixtures
(
'metadata-number-entry.underscore'
)
stringEntryTemplate
=
readFixtures
(
'metadata-string-entry.underscore'
)
optionEntryTemplate
=
readFixtures
(
'metadata-option-entry.underscore'
)
beforeEach
->
# TODO: update these
setFixtures
(
sandbox
({
id
:
"page-alert"
}))
appendSetFixtures
(
sandbox
({
id
:
"page-notification"
}))
setFixtures
(
$
(
"<script>"
,
{
id
:
"metadata-editor-tpl"
,
type
:
"text/template"
}).
text
(
editorTemplate
))
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"metadata-number-entry"
,
type
:
"text/template"
}).
text
(
numberEntryTemplate
))
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"metadata-string-entry"
,
type
:
"text/template"
}).
text
(
stringEntryTemplate
))
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"metadata-option-entry"
,
type
:
"text/template"
}).
text
(
optionEntryTemplate
))
describe
"CMS.Views.Metadata.Editor creates editors for each field"
,
->
beforeEach
->
@
model
=
new
Backbone
.
Model
({
display_name
:
{
default_value
:
null
,
genericEntry
=
{
default_value
:
'default value'
,
display_name
:
"Display Name"
,
explicitly_set
:
true
,
field_name
:
"display_name"
,
help
:
"Specifies the name for this component. The name appears as a tooltip in the course ribbon at the top of the page
."
,
help
:
"Specifies the name for this component
."
,
inheritable
:
false
,
options
:
[],
type
:
"Generic"
,
type
:
CMS
.
Models
.
Metadata
.
GENERIC_TYPE
,
value
:
"Word cloud"
},
num_inputs
:
{
}
selectEntry
=
{
default_value
:
"answered"
,
display_name
:
"Show Answer"
,
explicitly_set
:
false
,
field_name
:
"show_answer"
,
help
:
"When should you show the answer"
,
inheritable
:
true
,
options
:
[
{
"display_name"
:
"Always"
,
"value"
:
"always"
},
{
"display_name"
:
"Answered"
,
"value"
:
"answered"
},
{
"display_name"
:
"Never"
,
"value"
:
"never"
}
],
type
:
CMS
.
Models
.
Metadata
.
SELECT_TYPE
,
value
:
"always"
}
integerEntry
=
{
default_value
:
5
,
display_name
:
"Inputs"
,
explicitly_set
:
false
,
...
...
@@ -25,11 +45,254 @@ describe "CMS.Views.Metadata.Editor creates editors for each field", ->
help
:
"Number of text boxes for student to input words/sentences."
,
inheritable
:
false
,
options
:
{
min
:
1
},
type
:
"Integer"
,
type
:
CMS
.
Models
.
Metadata
.
INTEGER_TYPE
,
value
:
5
}
floatEntry
=
{
default_value
:
2.7
,
display_name
:
"Weight"
,
explicitly_set
:
true
,
field_name
:
"weight"
,
help
:
"Weight for this problem"
,
inheritable
:
true
,
options
:
{
min
:
1.3
,
max
:
100.2
,
step
:
0.1
},
type
:
CMS
.
Models
.
Metadata
.
FLOAT_TYPE
,
value
:
10.2
}
# Test for the editor that creates the individual views.
describe
"CMS.Views.Metadata.Editor creates editors for each field"
,
->
beforeEach
->
@
model
=
new
Backbone
.
Model
({
num_inputs
:
integerEntry
,
weight
:
floatEntry
,
show_answer
:
selectEntry
,
display_name
:
genericEntry
,
unknown_type
:
{
default_value
:
null
,
display_name
:
"Unknown"
,
explicitly_set
:
true
,
field_name
:
"unknown_type"
,
help
:
"Mystery property."
,
inheritable
:
false
,
options
:
[
{
"display_name"
:
"Always"
,
"value"
:
"always"
},
{
"display_name"
:
"Answered"
,
"value"
:
"answered"
},
{
"display_name"
:
"Never"
,
"value"
:
"never"
}],
type
:
"unknown type"
,
value
:
null
}
})
it
"creates child views on initialize, and sorts them alphabetically"
,
->
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
@
model
})
childModels
=
view
.
models
expect
(
childModels
.
length
).
toBe
(
5
)
childViews
=
view
.
$el
.
find
(
'.setting-input'
)
expect
(
childViews
.
length
).
toBe
(
5
)
verifyEntry
=
(
index
,
display_name
,
type
)
->
expect
(
childModels
[
index
].
get
(
'display_name'
)).
toBe
(
display_name
)
expect
(
childViews
[
index
].
type
).
toBe
(
type
)
verifyEntry
(
0
,
'Display Name'
,
'text'
)
verifyEntry
(
1
,
'Inputs'
,
'number'
)
verifyEntry
(
2
,
'Show Answer'
,
'select-one'
)
verifyEntry
(
3
,
'Unknown'
,
'text'
)
verifyEntry
(
4
,
'Weight'
,
'number'
)
it
"returns its display name"
,
->
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
@
model
})
expect
(
view
.
getDisplayName
()).
toBe
(
"Word cloud"
)
it
"returns an empty string if there is no display name property with a valid value"
,
->
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
new
Backbone
.
Model
()})
expect
(
view
.
getDisplayName
()).
toBe
(
""
)
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
new
Backbone
.
Model
({
display_name
:
{
default_value
:
null
,
display_name
:
"Display Name"
,
explicitly_set
:
false
,
field_name
:
"display_name"
,
help
:
""
,
inheritable
:
false
,
options
:
[],
type
:
CMS
.
Models
.
Metadata
.
GENERIC_TYPE
,
value
:
null
}
})
})
expect
(
view
.
getDisplayName
()).
toBe
(
""
)
it
"
renders on initalize
"
,
->
it
"
has no modified values by default
"
,
->
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
@
model
})
expect
(
view
.
models
).
toBeDefined
()
expect
(
view
.
getModifiedMetadataValues
()).
toEqual
({})
it
"returns modified values only"
,
->
view
=
new
CMS
.
Views
.
Metadata
.
Editor
({
model
:
@
model
})
childModels
=
view
.
models
childModels
[
0
].
setValue
(
'updated display name'
)
childModels
[
1
].
setValue
(
20
)
expect
(
view
.
getModifiedMetadataValues
()).
toEqual
({
display_name
:
'updated display name'
,
num_inputs
:
20
})
# Tests for individual views.
assertInputType
=
(
view
,
expectedType
)
->
input
=
view
.
$el
.
find
(
'.setting-input'
)
expect
(
input
.
length
).
toBe
(
1
)
expect
(
input
[
0
].
type
).
toBe
(
expectedType
)
assertValueInView
=
(
view
,
expectedValue
)
->
expect
(
view
.
getValueFromEditor
()).
toBe
(
expectedValue
)
assertCanUpdateView
=
(
view
,
newValue
)
->
view
.
setValueInEditor
(
newValue
)
expect
(
view
.
getValueFromEditor
()).
toBe
(
newValue
)
assertClear
=
(
view
,
modelValue
,
editorValue
=
modelValue
)
->
view
.
clear
()
expect
(
view
.
model
.
getValue
()).
toBe
(
null
)
expect
(
view
.
model
.
getDisplayValue
()).
toBe
(
modelValue
)
expect
(
view
.
getValueFromEditor
()).
toBe
(
editorValue
)
assertUpdateModel
=
(
view
,
originalValue
,
newValue
)
->
view
.
setValueInEditor
(
newValue
)
expect
(
view
.
model
.
getValue
()).
toBe
(
originalValue
)
view
.
updateModel
()
expect
(
view
.
model
.
getValue
()).
toBe
(
newValue
)
describe
"CMS.Views.Metadata.String is a basic string input with clear functionality"
,
->
beforeEach
->
model
=
new
CMS
.
Models
.
Metadata
(
genericEntry
)
@
view
=
new
CMS
.
Views
.
Metadata
.
String
({
model
:
model
})
it
"uses a text input type"
,
->
assertInputType
(
@
view
,
'text'
)
it
"returns the intial value upon initialization"
,
->
assertValueInView
(
@
view
,
'Word cloud'
)
it
"can update its value in the view"
,
->
assertCanUpdateView
(
@
view
,
"updated"
)
it
"has a clear method to revert to the model default"
,
->
assertClear
(
@
view
,
'default value'
)
it
"has an update model method"
,
->
assertUpdateModel
(
@
view
,
'Word cloud'
,
'updated'
)
describe
"CMS.Views.Metadata.Option is an option input type with clear functionality"
,
->
beforeEach
->
model
=
new
CMS
.
Models
.
Metadata
(
selectEntry
)
@
view
=
new
CMS
.
Views
.
Metadata
.
Option
({
model
:
model
})
it
"uses a select input type"
,
->
assertInputType
(
@
view
,
'select-one'
)
it
"returns the intial value upon initialization"
,
->
assertValueInView
(
@
view
,
'always'
)
it
"can update its value in the view"
,
->
assertCanUpdateView
(
@
view
,
"never"
)
it
"has a clear method to revert to the model default"
,
->
assertClear
(
@
view
,
'answered'
)
it
"has an update model method"
,
->
assertUpdateModel
(
@
view
,
null
,
'never'
)
it
"does not update to a value that is not an option"
,
->
@
view
.
setValueInEditor
(
"not an option"
)
expect
(
@
view
.
getValueFromEditor
()).
toBe
(
'always'
)
describe
"CMS.Views.Metadata.Number supports integer or float type and has clear functionality"
,
->
beforeEach
->
integerModel
=
new
CMS
.
Models
.
Metadata
(
integerEntry
)
@
integerView
=
new
CMS
.
Views
.
Metadata
.
Number
({
model
:
integerModel
})
floatModel
=
new
CMS
.
Models
.
Metadata
(
floatEntry
)
@
floatView
=
new
CMS
.
Views
.
Metadata
.
Number
({
model
:
floatModel
})
it
"uses a number input type"
,
->
assertInputType
(
@
integerView
,
'number'
)
assertInputType
(
@
floatView
,
'number'
)
it
"returns the intial value upon initialization"
,
->
assertValueInView
(
@
integerView
,
'5'
)
assertValueInView
(
@
floatView
,
'10.2'
)
it
"can update its value in the view"
,
->
assertCanUpdateView
(
@
integerView
,
"12"
)
assertCanUpdateView
(
@
floatView
,
"-2.4"
)
it
"has a clear method to revert to the model default"
,
->
assertClear
(
@
integerView
,
5
,
'5'
)
assertClear
(
@
floatView
,
2.7
,
'2.7'
)
it
"has an update model method"
,
->
assertUpdateModel
(
@
integerView
,
null
,
'90'
)
assertUpdateModel
(
@
floatView
,
10.2
,
'-9.5'
)
it
"knows the difference between integer and float"
,
->
expect
(
@
integerView
.
isIntegerField
()).
toBeTruthy
()
expect
(
@
floatView
.
isIntegerField
()).
toBeFalsy
()
it
"sets attribtues related to min, max, and step"
,
->
verifyAttributes
=
(
view
,
min
,
step
,
max
=
null
)
->
inputEntry
=
view
.
$el
.
find
(
'input'
)
expect
(
Number
(
inputEntry
.
attr
(
'min'
))).
toEqual
(
min
)
expect
(
Number
(
inputEntry
.
attr
(
'step'
))).
toEqual
(
step
)
if
max
is
not
null
expect
(
Number
(
inputEntry
.
attr
(
'max'
))).
toEqual
(
max
)
verifyAttributes
(
@
integerView
,
1
,
1
)
verifyAttributes
(
@
floatView
,
1.3
,
.
1
,
100.2
)
it
"corrects values that are out of range"
,
->
verifyValueAfterChanged
=
(
view
,
value
,
expectedResult
)
->
view
.
setValueInEditor
(
value
)
view
.
changed
()
expect
(
view
.
getValueFromEditor
()).
toBe
(
expectedResult
)
verifyValueAfterChanged
(
@
integerView
,
'-4'
,
'1'
)
verifyValueAfterChanged
(
@
integerView
,
'1'
,
'1'
)
verifyValueAfterChanged
(
@
integerView
,
'0'
,
'1'
)
verifyValueAfterChanged
(
@
integerView
,
'3001'
,
'3001'
)
verifyValueAfterChanged
(
@
floatView
,
'-4'
,
'1.3'
)
verifyValueAfterChanged
(
@
floatView
,
'1.3'
,
'1.3'
)
verifyValueAfterChanged
(
@
floatView
,
'1.2'
,
'1.3'
)
verifyValueAfterChanged
(
@
floatView
,
'100.2'
,
'100.2'
)
verifyValueAfterChanged
(
@
floatView
,
'100.3'
,
'100.2'
)
it
"disallows invalid characters"
,
->
verifyValueAfterKeyPressed
=
(
view
,
character
,
reject
)
->
event
=
{
type
:
'keypress'
,
which
:
character
.
charCodeAt
(
0
),
keyCode
:
character
.
charCodeAt
(
0
),
preventDefault
:
()
->
'no op'
}
spyOn
(
event
,
'preventDefault'
)
view
.
$el
.
find
(
'input'
).
trigger
(
event
)
if
(
reject
)
expect
(
event
.
preventDefault
).
toHaveBeenCalled
()
else
expect
(
event
.
preventDefault
).
not
.
toHaveBeenCalled
()
verifyDisallowedChars
=
(
view
)
->
verifyValueAfterKeyPressed
(
view
,
'a'
,
true
)
verifyValueAfterKeyPressed
(
view
,
'.'
,
view
.
isIntegerField
())
verifyValueAfterKeyPressed
(
view
,
'['
,
true
)
verifyValueAfterKeyPressed
(
view
,
'@'
,
true
)
for
i
in
[
0
...
9
]
verifyValueAfterKeyPressed
(
view
,
String
(
i
),
false
)
verifyDisallowedChars
(
@
integerView
)
verifyDisallowedChars
(
@
floatView
)
cms/static/js/views/metadata_editor_view.js
View file @
24707f8f
...
...
@@ -3,7 +3,6 @@ if (!CMS.Views['Metadata']) CMS.Views.Metadata = {};
CMS
.
Views
.
Metadata
.
Editor
=
Backbone
.
View
.
extend
({
// Model is simply a Backbone.Model instance.
initialize
:
function
()
{
var
tpl
=
$
(
"#metadata-editor-tpl"
).
text
();
if
(
!
tpl
)
{
...
...
@@ -45,6 +44,9 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
});
},
/**
* Returns the just the modified metadata values, in the format used to persist to the server.
*/
getModifiedMetadataValues
:
function
()
{
var
modified_values
=
{};
_
.
each
(
this
.
models
,
...
...
@@ -57,8 +59,16 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
return
modified_values
;
},
/**
* Returns a display name for the component related to this metadata. This method looks to see
* if there is a metadata entry called 'display_name', and if so, it returns its value. If there
* is no such entry, or if display_name does not have a value set, it returns an empty string.
*/
getDisplayName
:
function
()
{
// It is possible that there is no display name set. In that case, return empty string.
if
(
this
.
model
.
get
(
'display_name'
)
===
undefined
)
{
return
''
;
}
var
displayNameValue
=
this
.
model
.
get
(
'display_name'
).
value
;
return
displayNameValue
?
displayNameValue
:
''
;
}
...
...
@@ -67,7 +77,6 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
CMS
.
Views
.
Metadata
.
AbstractEditor
=
Backbone
.
View
.
extend
({
// Model is CMS.Models.Metadata.
initialize
:
function
()
{
var
self
=
this
;
var
templateName
=
this
.
getTemplateName
();
...
...
@@ -82,22 +91,42 @@ CMS.Views.Metadata.AbstractEditor = Backbone.View.extend({
this
.
render
();
},
/**
* Returns the ID/name of the template. Subclasses should implement this method.
*/
getTemplateName
:
function
()
{},
/**
* Returns the value currently displayed in the editor/view. Subclasses should implement this method.
*/
getValueFromEditor
:
function
()
{},
/**
* Sets the value currently displayed in the editor/view. Subclasses should implement this method.
*/
setValueInEditor
:
function
(
value
)
{},
/**
* Sets the value in the model, using the value currently displayed in the view. Afterward,
* this method re-renders to update the clear button.
*/
updateModel
:
function
()
{
this
.
model
.
setValue
(
this
.
getValueFromEditor
());
this
.
render
();
},
/**
* Clears the value currently set in the model (reverting to the default). Afterward, this method
* re-renders the view.
*/
clear
:
function
()
{
this
.
model
.
clear
();
this
.
render
();
},
/**
* Shows the clear button, if it is not already showing.
*/
showClearButton
:
function
()
{
if
(
!
this
.
$el
.
hasClass
(
'is-set'
))
{
this
.
$el
.
addClass
(
'is-set'
);
...
...
@@ -106,10 +135,17 @@ CMS.Views.Metadata.AbstractEditor = Backbone.View.extend({
}
},
/**
* Returns the clear button.
*/
getClearButton
:
function
()
{
return
this
.
$el
.
find
(
'.setting-clear'
);
},
/**
* Renders the editor, updating the value displayed in the view, as well as the state of
* the clear button.
*/
render
:
function
()
{
if
(
!
this
.
template
)
return
;
...
...
@@ -172,7 +208,7 @@ CMS.Views.Metadata.Number = CMS.Views.Metadata.AbstractEditor.extend({
}
if
(
options
.
hasOwnProperty
(
max
))
{
this
.
max
=
Number
(
options
[
max
]);
this
.
$el
.
find
(
'input'
).
attr
(
max
,
numToString
(
this
.
max
.
toFixed
));
this
.
$el
.
find
(
'input'
).
attr
(
max
,
numToString
(
this
.
max
));
}
var
stepValue
=
undefined
;
if
(
options
.
hasOwnProperty
(
step
))
{
...
...
@@ -208,6 +244,9 @@ CMS.Views.Metadata.Number = CMS.Views.Metadata.AbstractEditor.extend({
this
.
$el
.
find
(
'input'
).
val
(
value
);
},
/**
* Returns true if this view is restricted to integers, as opposed to floating points values.
*/
isIntegerField
:
function
()
{
return
this
.
model
.
getType
()
===
'Integer'
;
},
...
...
@@ -275,7 +314,7 @@ CMS.Views.Metadata.Option = CMS.Views.Metadata.AbstractEditor.extend({
value
=
modelValue
[
'display_name'
];
}
});
$
(
'#'
+
this
.
uniqueId
+
" option"
).
filter
(
function
()
{
this
.
$el
.
find
(
'#'
+
this
.
uniqueId
+
" option"
).
filter
(
function
()
{
return
$
(
this
).
text
()
===
value
;
}).
prop
(
'selected'
,
true
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment