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
d8b419c6
Commit
d8b419c6
authored
Aug 26, 2015
by
muhammad-ammar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Review changes
parent
6134e8b5
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
614 additions
and
559 deletions
+614
-559
cms/static/coffee/spec/views/feedback_spec.coffee
+0
-315
common/static/common/js/components/utils/view_utils.js
+5
-1
common/static/common/js/components/views/feedback.js
+139
-133
common/static/common/js/components/views/feedback_alert.js
+39
-34
common/static/common/js/components/views/feedback_notification.js
+30
-25
common/static/common/js/components/views/feedback_prompt.js
+38
-33
common/static/common/js/spec/components/feedback_spec.js
+336
-0
common/static/common/js/spec/components/view_utils_spec.js
+6
-2
common/static/common/js/spec_helpers/view_helpers.js
+9
-6
common/static/common/templates/components/system-feedback.underscore
+2
-3
lms/djangoapps/teams/static/teams/js/spec/views/team_profile_spec.js
+5
-5
lms/static/sass/_build-lms.scss
+1
-2
lms/static/sass/_mixins-inherited.scss
+2
-0
lms/static/sass/_mixins.scss
+2
-0
No files found.
cms/static/coffee/spec/views/feedback_spec.coffee
deleted
100644 → 0
View file @
6134e8b5
define
[
"jquery"
,
"js/views/feedback"
,
"js/views/feedback_notification"
,
"js/views/feedback_alert"
,
"js/views/feedback_prompt"
,
"sinon"
],
(
$
,
SystemFeedback
,
NotificationView
,
AlertView
,
PromptView
,
sinon
)
->
tpl
=
readFixtures
(
'system-feedback.underscore'
)
beforeEach
->
setFixtures
(
sandbox
({
id
:
"page-alert"
}))
appendSetFixtures
(
sandbox
({
id
:
"page-notification"
}))
appendSetFixtures
(
sandbox
({
id
:
"page-prompt"
}))
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"system-feedback-tpl"
,
type
:
"text/template"
}).
text
(
tpl
))
@
addMatchers
toBeShown
:
->
@
actual
.
hasClass
(
"is-shown"
)
and
not
@
actual
.
hasClass
(
"is-hiding"
)
toBeHiding
:
->
@
actual
.
hasClass
(
"is-hiding"
)
and
not
@
actual
.
hasClass
(
"is-shown"
)
toContainText
:
(
text
)
->
# remove this when we upgrade jasmine-jquery
trimmedText
=
$
.
trim
(
@
actual
.
text
())
if
text
and
$
.
isFunction
(
text
.
test
)
return
text
.
test
(
trimmedText
)
else
return
trimmedText
.
indexOf
(
text
)
!=
-
1
;
toHaveBeenPrevented
:
->
# remove this when we upgrade jasmine-jquery
eventName
=
@
actual
.
eventName
selector
=
@
actual
.
selector
@
message
=
->
[
"Expected event
#{
eventName
}
to have been prevented on
#{
selector
}
"
,
"Expected event
#{
eventName
}
not to have been prevented on
#{
selector
}
"
]
return
jasmine
.
JQuery
.
events
.
wasPrevented
(
selector
,
eventName
)
describe
"SystemFeedback"
,
->
beforeEach
->
@
options
=
title
:
"Portal"
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
# it will be interesting to see when this.render is called, so lets spy on it
@
renderSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'render'
).
andCallThrough
()
@
showSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'show'
).
andCallThrough
()
@
hideSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'hide'
).
andCallThrough
()
@
clock
=
sinon
.
useFakeTimers
()
afterEach
->
@
clock
.
restore
()
it
"requires a type and an intent"
,
->
neither
=
=>
new
SystemFeedback
(
@
options
)
noType
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
intent
=
"confirmation"
new
SystemFeedback
(
options
)
noIntent
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
type
=
"alert"
new
SystemFeedback
(
options
)
both
=
=>
options
=
$
.
extend
({},
@
options
)
options
.
type
=
"alert"
options
.
intent
=
"confirmation"
new
SystemFeedback
(
options
)
expect
(
neither
).
toThrow
()
expect
(
noType
).
toThrow
()
expect
(
noIntent
).
toThrow
()
expect
(
both
).
not
.
toThrow
()
# for simplicity, we'll use AlertView.Confirmation from here on,
# which extends and proxies to SystemFeedback
it
"does not show on initalize"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
)
expect
(
@
renderSpy
).
not
.
toHaveBeenCalled
()
expect
(
@
showSpy
).
not
.
toHaveBeenCalled
()
# Disabled flaky test TNL-559
xit
"renders the template"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
)
view
.
show
()
expect
(
view
.
$
(
".action-close"
)).
toBeDefined
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
expect
(
view
.
$el
).
toContainText
(
@
options
.
title
)
expect
(
view
.
$el
).
toContainText
(
@
options
.
message
)
# Disabled flaky test TNL-559
xit
"close button sends a .hide() message"
,
->
view
=
new
AlertView
.
Confirmation
(
@
options
).
show
()
view
.
$
(
".action-close"
).
click
()
expect
(
@
hideSpy
).
toHaveBeenCalled
()
@
clock
.
tick
(
900
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
describe
"PromptView"
,
->
# for some reason, expect($("body")) blows up the test runner, so this test
# just exercises the Prompt rather than asserting on anything. Best I can
# do for now. :(
it
"changes class on body"
,
->
# expect($("body")).not.toHaveClass("prompt-is-shown")
view
=
new
PromptView
.
Confirmation
({
title
:
"Portal"
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
})
# expect($("body")).toHaveClass("prompt-is-shown")
view
.
hide
()
# expect($("body")).not.toHaveClass("prompt-is-shown")
describe
"NotificationView.Mini"
,
->
beforeEach
->
@
view
=
new
NotificationView
.
Mini
()
it
"should have minShown set to 1250 by default"
,
->
expect
(
@
view
.
options
.
minShown
).
toEqual
(
1250
)
it
"should have closeIcon set to false by default"
,
->
expect
(
@
view
.
options
.
closeIcon
).
toBeFalsy
()
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback click events"
,
->
beforeEach
->
@
primaryClickSpy
=
jasmine
.
createSpy
(
'primaryClick'
)
@
secondaryClickSpy
=
jasmine
.
createSpy
(
'secondaryClick'
)
@
view
=
new
NotificationView
.
Warning
(
title
:
"Unsaved"
,
message
:
"Your content is currently Unsaved."
,
actions
:
primary
:
text
:
"Save"
,
class
:
"save-button"
,
click
:
@
primaryClickSpy
secondary
:
text
:
"Revert"
,
class
:
"cancel-button"
,
click
:
@
secondaryClickSpy
)
@
view
.
show
()
it
"should trigger the primary event on a primary click"
,
->
@
view
.
$
(
".action-primary"
).
click
()
expect
(
@
primaryClickSpy
).
toHaveBeenCalled
()
expect
(
@
secondaryClickSpy
).
not
.
toHaveBeenCalled
()
it
"should trigger the secondary event on a secondary click"
,
->
@
view
.
$
(
".action-secondary"
).
click
()
expect
(
@
secondaryClickSpy
).
toHaveBeenCalled
()
expect
(
@
primaryClickSpy
).
not
.
toHaveBeenCalled
()
it
"should apply class to primary action"
,
->
expect
(
@
view
.
$
(
".action-primary"
)).
toHaveClass
(
"save-button"
)
it
"should apply class to secondary action"
,
->
expect
(
@
view
.
$
(
".action-secondary"
)).
toHaveClass
(
"cancel-button"
)
it
"should preventDefault on primary action"
,
->
spyOnEvent
(
".action-primary"
,
"click"
)
@
view
.
$
(
".action-primary"
).
click
()
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-primary"
)
it
"should preventDefault on secondary action"
,
->
spyOnEvent
(
".action-secondary"
,
"click"
)
@
view
.
$
(
".action-secondary"
).
click
()
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-secondary"
)
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback not preventing events"
,
->
beforeEach
->
@
clickSpy
=
jasmine
.
createSpy
(
'clickSpy'
)
@
view
=
new
AlertView
.
Confirmation
(
title
:
"It's all good"
message
:
"No reason for this alert"
actions
:
primary
:
text
:
"Whatever"
click
:
@
clickSpy
preventDefault
:
false
)
@
view
.
show
()
it
"should not preventDefault"
,
->
spyOnEvent
(
".action-primary"
,
"click"
)
@
view
.
$
(
".action-primary"
).
click
()
expect
(
"click"
).
not
.
toHaveBeenPreventedOn
(
".action-primary"
)
expect
(
@
clickSpy
).
toHaveBeenCalled
()
# Disabled flaky test TNL-559
xdescribe
"SystemFeedback multiple secondary actions"
,
->
beforeEach
->
@
secondarySpyOne
=
jasmine
.
createSpy
(
'secondarySpyOne'
)
@
secondarySpyTwo
=
jasmine
.
createSpy
(
'secondarySpyTwo'
)
@
view
=
new
NotificationView
.
Warning
(
title
:
"No Primary"
,
message
:
"Pick a secondary action"
,
actions
:
secondary
:
[
{
text
:
"Option One"
class
:
"option-one"
click
:
@
secondarySpyOne
},
{
text
:
"Option Two"
class
:
"option-two"
click
:
@
secondarySpyTwo
}
]
)
@
view
.
show
()
it
"should render both"
,
->
expect
(
@
view
.
el
).
toContain
(
".action-secondary.option-one"
)
expect
(
@
view
.
el
).
toContain
(
".action-secondary.option-two"
)
expect
(
@
view
.
el
).
not
.
toContain
(
".action-secondary.option-one.option-two"
)
expect
(
@
view
.
$
(
".action-secondary.option-one"
)).
toContainText
(
"Option One"
)
expect
(
@
view
.
$
(
".action-secondary.option-two"
)).
toContainText
(
"Option Two"
)
it
"should differentiate clicks (1)"
,
->
@
view
.
$
(
".option-one"
).
click
()
expect
(
@
secondarySpyOne
).
toHaveBeenCalled
()
expect
(
@
secondarySpyTwo
).
not
.
toHaveBeenCalled
()
it
"should differentiate clicks (2)"
,
->
@
view
.
$
(
".option-two"
).
click
()
expect
(
@
secondarySpyOne
).
not
.
toHaveBeenCalled
()
expect
(
@
secondarySpyTwo
).
toHaveBeenCalled
()
describe
"NotificationView minShown and maxShown"
,
->
beforeEach
->
@
showSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'show'
)
@
showSpy
.
andCallThrough
()
@
hideSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'hide'
)
@
hideSpy
.
andCallThrough
()
@
clock
=
sinon
.
useFakeTimers
()
afterEach
->
@
clock
.
restore
()
# Disabled flaky test TNL-559
xit
"should not have minShown or maxShown by default"
,
->
view
=
new
NotificationView
.
Confirmation
()
expect
(
view
.
options
.
minShown
).
toEqual
(
0
)
expect
(
view
.
options
.
maxShown
).
toEqual
(
Infinity
)
# Disabled flaky test TNL-559
xit
"a minShown view should not hide too quickly"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# call hide() on it, but the minShown should prevent it from hiding right away
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the minShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a maxShown view should hide by itself"
,
->
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the maxShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a minShown view can stay visible longer"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait for the minShown timeout to expire, and check again
@
clock
.
tick
(
1001
)
expect
(
@
hideSpy
).
not
.
toHaveBeenCalled
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# can now hide immediately
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# Disabled flaky test TNL-559
xit
"a maxShown view can hide early"
,
->
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
})
view
.
show
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
# wait 50 milliseconds, and hide it early
@
clock
.
tick
(
50
)
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# wait for timeout to expire, make sure it doesn't do anything weird
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
it
"a view can have both maxShown and minShown"
,
->
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
,
maxShown
:
2000
})
view
.
show
()
# can't hide early
@
clock
.
tick
(
50
)
view
.
hide
()
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
# show it again, and let it hide automatically
view
.
show
()
@
clock
.
tick
(
1050
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
()
@
clock
.
tick
(
1000
)
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
()
common/static/common/js/components/utils/view_utils.js
View file @
d8b419c6
/**
/**
* Provides useful utilities for views.
* Provides useful utilities for views.
*/
*/
define
([
"jquery"
,
"underscore"
,
"gettext"
,
"js/views/feedback_notification"
,
"js/views/feedback_prompt"
],
;(
function
(
define
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"gettext"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_prompt"
],
function
(
$
,
_
,
gettext
,
NotificationView
,
PromptView
)
{
function
(
$
,
_
,
gettext
,
NotificationView
,
PromptView
)
{
var
toggleExpandCollapse
,
showLoadingIndicator
,
hideLoadingIndicator
,
confirmThenRunOperation
,
var
toggleExpandCollapse
,
showLoadingIndicator
,
hideLoadingIndicator
,
confirmThenRunOperation
,
runOperationShowingMessage
,
disableElementWhileRunning
,
getScrollOffset
,
setScrollOffset
,
runOperationShowingMessage
,
disableElementWhileRunning
,
getScrollOffset
,
setScrollOffset
,
...
@@ -246,3 +249,4 @@ define(["jquery", "underscore", "gettext", "js/views/feedback_notification", "js
...
@@ -246,3 +249,4 @@ define(["jquery", "underscore", "gettext", "js/views/feedback_notification", "js
'checkTotalKeyLengthViolations'
:
checkTotalKeyLengthViolations
'checkTotalKeyLengthViolations'
:
checkTotalKeyLengthViolations
};
};
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"backbone"
,
"js/utils/templates"
],
;(
function
(
define
)
{
function
(
$
,
_
,
str
,
Backbone
,
TemplateUtils
)
{
'use strict'
;
var
SystemFeedback
=
Backbone
.
View
.
extend
({
define
([
"jquery"
,
options
:
{
"underscore"
,
title
:
""
,
"underscore.string"
,
message
:
""
,
"backbone"
,
intent
:
null
,
// "warning", "confirmation", "error", "announcement", "step-required", etc
"text!common/templates/components/system-feedback.underscore"
],
type
:
null
,
// "alert", "notification", or "prompt": set by subclass
function
(
$
,
_
,
str
,
Backbone
,
systemFeedbackTemplate
)
{
shown
:
true
,
// is this view currently being shown?
var
SystemFeedback
=
Backbone
.
View
.
extend
({
icon
:
true
,
// should we render an icon related to the message intent?
options
:
{
closeIcon
:
true
,
// should we render a close button in the top right corner?
title
:
""
,
minShown
:
0
,
// length of time after this view has been shown before it can be hidden (milliseconds)
message
:
""
,
maxShown
:
Infinity
// length of time after this view has been shown before it will be automatically hidden (milliseconds)
intent
:
null
,
// "warning", "confirmation", "error", "announcement", "step-required", etc
type
:
null
,
// "alert", "notification", or "prompt": set by subclass
shown
:
true
,
// is this view currently being shown?
icon
:
true
,
// should we render an icon related to the message intent?
closeIcon
:
true
,
// should we render a close button in the top right corner?
minShown
:
0
,
// length of time after this view has been shown before it can be hidden (milliseconds)
maxShown
:
Infinity
// length of time after this view has been shown before it will be automatically hidden (milliseconds)
/* Could also have an "actions" hash: here is an example demonstrating
/* Could also have an "actions" hash: here is an example demonstrating
the expected structure. For each action, by default the framework
the expected structure. For each action, by default the framework
will call preventDefault on the click event before the function is
will call preventDefault on the click event before the function is
run; to make it not do that, just pass `preventDefault: false` in
run; to make it not do that, just pass `preventDefault: false` in
the action object.
the action object.
actions: {
actions: {
primary: {
primary: {
"text": "Save",
"text": "Save",
"class": "action-save",
"class": "action-save",
"click": function(view) {
"click": function(view) {
// do something when Save is clicked
// do something when Save is clicked
}
}
},
},
secondary: [
secondary: [
{
{
"text": "Cancel",
"text": "Cancel",
"class": "action-cancel",
"class": "action-cancel",
"click": function(view) {}
"click": function(view) {}
}, {
}, {
"text": "Discard Changes",
"text": "Discard Changes",
"class": "action-discard",
"class": "action-discard",
"click": function(view) {}
"click": function(view) {}
}
}
]
]
}
*/
},
initialize
:
function
()
{
if
(
!
this
.
options
.
type
)
{
throw
"SystemFeedback: type required (given "
+
JSON
.
stringify
(
this
.
options
)
+
")"
;
}
}
if
(
!
this
.
options
.
intent
)
{
*/
throw
"SystemFeedback: intent required (given "
+
},
JSON
.
stringify
(
this
.
options
)
+
")"
;
}
this
.
template
=
TemplateUtils
.
loadTemplate
(
"system-feedback"
);
this
.
setElement
(
$
(
"#page-"
+
this
.
options
.
type
));
// handle single "secondary" action
if
(
this
.
options
.
actions
&&
this
.
options
.
actions
.
secondary
&&
!
_
.
isArray
(
this
.
options
.
actions
.
secondary
))
{
this
.
options
.
actions
.
secondary
=
[
this
.
options
.
actions
.
secondary
];
}
return
this
;
},
// public API: show() and hide()
initialize
:
function
()
{
show
:
function
()
{
if
(
!
this
.
options
.
type
)
{
clearTimeout
(
this
.
hideTimeout
);
throw
"SystemFeedback: type required (given "
+
this
.
options
.
shown
=
true
;
JSON
.
stringify
(
this
.
options
)
+
")"
;
this
.
shownAt
=
new
Date
();
}
this
.
render
();
if
(
!
this
.
options
.
intent
)
{
if
(
$
.
isNumeric
(
this
.
options
.
maxShown
))
{
throw
"SystemFeedback: intent required (given "
+
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
JSON
.
stringify
(
this
.
options
)
+
")"
;
this
.
options
.
maxShown
);
}
}
this
.
setElement
(
$
(
"#page-"
+
this
.
options
.
type
));
return
this
;
// handle single "secondary" action
},
if
(
this
.
options
.
actions
&&
this
.
options
.
actions
.
secondary
&&
!
_
.
isArray
(
this
.
options
.
actions
.
secondary
))
{
this
.
options
.
actions
.
secondary
=
[
this
.
options
.
actions
.
secondary
];
}
return
this
;
},
hide
:
function
()
{
// public API: show() and hide()
if
(
this
.
shownAt
&&
$
.
isNumeric
(
this
.
options
.
minShown
)
&&
show
:
function
()
{
this
.
options
.
minShown
>
new
Date
()
-
this
.
shownAt
)
{
clearTimeout
(
this
.
hideTimeout
);
clearTimeout
(
this
.
hideTimeout
);
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
shown
=
true
;
this
.
options
.
minShown
-
(
new
Date
()
-
this
.
shownAt
));
this
.
shownAt
=
new
Date
();
}
else
{
this
.
options
.
shown
=
false
;
delete
this
.
shownAt
;
this
.
render
();
this
.
render
();
}
if
(
$
.
isNumeric
(
this
.
options
.
maxShown
))
{
return
this
;
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
},
this
.
options
.
maxShown
);
}
return
this
;
},
hide
:
function
()
{
if
(
this
.
shownAt
&&
$
.
isNumeric
(
this
.
options
.
minShown
)
&&
this
.
options
.
minShown
>
new
Date
()
-
this
.
shownAt
)
{
clearTimeout
(
this
.
hideTimeout
);
this
.
hideTimeout
=
setTimeout
(
_
.
bind
(
this
.
hide
,
this
),
this
.
options
.
minShown
-
(
new
Date
()
-
this
.
shownAt
));
}
else
{
this
.
options
.
shown
=
false
;
delete
this
.
shownAt
;
this
.
render
();
}
return
this
;
},
// the rest of the API should be considered semi-private
// the rest of the API should be considered semi-private
events
:
{
events
:
{
"click .action-close"
:
"hide"
,
"click .action-close"
:
"hide"
,
"click .action-primary"
:
"primaryClick"
,
"click .action-primary"
:
"primaryClick"
,
"click .action-secondary"
:
"secondaryClick"
"click .action-secondary"
:
"secondaryClick"
},
},
render
:
function
()
{
render
:
function
()
{
// there can be only one active view of a given type at a time: only
// there can be only one active view of a given type at a time: only
// one alert, only one notification, only one prompt. Therefore, we'll
// one alert, only one notification, only one prompt. Therefore, we'll
// use a singleton approach.
// use a singleton approach.
var
singleton
=
SystemFeedback
[
"active_"
+
this
.
options
.
type
];
var
singleton
=
SystemFeedback
[
"active_"
+
this
.
options
.
type
];
if
(
singleton
&&
singleton
!==
this
)
{
if
(
singleton
&&
singleton
!==
this
)
{
singleton
.
stopListening
();
singleton
.
stopListening
();
singleton
.
undelegateEvents
();
singleton
.
undelegateEvents
();
}
}
this
.
$el
.
html
(
this
.
template
(
this
.
options
));
this
.
$el
.
html
(
_
.
template
(
systemFeedbackTemplate
)
(
this
.
options
));
SystemFeedback
[
"active_"
+
this
.
options
.
type
]
=
this
;
SystemFeedback
[
"active_"
+
this
.
options
.
type
]
=
this
;
return
this
;
return
this
;
},
},
primaryClick
:
function
(
event
)
{
primaryClick
:
function
(
event
)
{
var
actions
,
primary
;
var
actions
,
primary
;
actions
=
this
.
options
.
actions
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
if
(
!
actions
)
{
return
;
}
primary
=
actions
.
primary
;
primary
=
actions
.
primary
;
if
(
!
primary
)
{
return
;
}
if
(
!
primary
)
{
return
;
}
if
(
primary
.
preventDefault
!==
false
)
{
if
(
primary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
event
.
preventDefault
();
}
}
if
(
primary
.
click
)
{
if
(
primary
.
click
)
{
primary
.
click
.
call
(
event
.
target
,
this
,
event
);
primary
.
click
.
call
(
event
.
target
,
this
,
event
);
}
}
},
},
secondaryClick
:
function
(
event
)
{
secondaryClick
:
function
(
event
)
{
var
actions
,
secondaryList
,
secondary
,
i
;
var
actions
,
secondaryList
,
secondary
,
i
;
actions
=
this
.
options
.
actions
;
actions
=
this
.
options
.
actions
;
if
(
!
actions
)
{
return
;
}
if
(
!
actions
)
{
return
;
}
secondaryList
=
actions
.
secondary
;
secondaryList
=
actions
.
secondary
;
if
(
!
secondaryList
)
{
return
;
}
if
(
!
secondaryList
)
{
return
;
}
// which secondary action was clicked?
// which secondary action was clicked?
i
=
0
;
// default to the first secondary action (easier for testing)
i
=
0
;
// default to the first secondary action (easier for testing)
if
(
event
&&
event
.
target
)
{
if
(
event
&&
event
.
target
)
{
i
=
_
.
indexOf
(
this
.
$
(
".action-secondary"
),
event
.
target
);
i
=
_
.
indexOf
(
this
.
$
(
".action-secondary"
),
event
.
target
);
}
}
secondary
=
secondaryList
[
i
];
secondary
=
secondaryList
[
i
];
if
(
secondary
.
preventDefault
!==
false
)
{
if
(
secondary
.
preventDefault
!==
false
)
{
event
.
preventDefault
();
event
.
preventDefault
();
}
}
if
(
secondary
.
click
)
{
if
(
secondary
.
click
)
{
secondary
.
click
.
call
(
event
.
target
,
this
,
event
);
secondary
.
click
.
call
(
event
.
target
,
this
,
event
);
}
}
}
}
});
return
SystemFeedback
;
});
});
return
SystemFeedback
;
}).
call
(
this
,
define
||
RequireJS
.
define
);
});
common/static/common/js/components/views/feedback_alert.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
;(
function
(
define
)
{
var
Alert
=
SystemFeedbackView
.
extend
({
'use strict'
;
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
type
:
"alert"
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
}),
str
=
str
||
_
.
str
;
slide_speed
:
900
,
var
Alert
=
SystemFeedbackView
.
extend
({
show
:
function
()
{
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
SystemFeedbackView
.
prototype
.
show
.
apply
(
this
,
arguments
);
type
:
"alert"
this
.
$el
.
hide
();
}),
this
.
$el
.
slideDown
(
this
.
slide_speed
);
slide_speed
:
900
,
return
this
;
show
:
function
()
{
},
SystemFeedbackView
.
prototype
.
show
.
apply
(
this
,
arguments
);
hide
:
function
()
{
this
.
$el
.
hide
();
this
.
$el
.
slideUp
({
this
.
$el
.
slideDown
(
this
.
slide_speed
);
duration
:
this
.
slide_speed
return
this
;
});
},
setTimeout
(
_
.
bind
(
SystemFeedbackView
.
prototype
.
hide
,
this
,
arguments
),
hide
:
function
()
{
this
.
slideSpeed
);
this
.
$el
.
slideUp
({
}
duration
:
this
.
slide_speed
});
});
setTimeout
(
_
.
bind
(
SystemFeedbackView
.
prototype
.
hide
,
this
,
arguments
),
this
.
slideSpeed
);
}
});
// create Alert.Warning, Alert.Confirmation, etc
// create Alert.Warning, Alert.Confirmation, etc
var
capitalCamel
,
intents
;
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
var
subclass
;
subclass
=
Alert
.
extend
({
subclass
=
Alert
.
extend
({
options
:
$
.
extend
({},
Alert
.
prototype
.
options
,
{
options
:
$
.
extend
({},
Alert
.
prototype
.
options
,
{
intent
:
intent
intent
:
intent
})
})
});
Alert
[
capitalCamel
(
intent
)]
=
subclass
;
});
});
Alert
[
capitalCamel
(
intent
)]
=
subclass
;
});
return
Alert
;
return
Alert
;
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback_notification.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
;(
function
(
define
)
{
var
Notification
=
SystemFeedbackView
.
extend
({
'use strict'
;
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
type
:
"notification"
,
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
closeIcon
:
false
str
=
str
||
_
.
str
;
})
var
Notification
=
SystemFeedbackView
.
extend
({
});
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
type
:
"notification"
,
// create Notification.Warning, Notification.Confirmation, etc
closeIcon
:
false
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Notification
.
extend
({
options
:
$
.
extend
({},
Notification
.
prototype
.
options
,
{
intent
:
intent
})
})
});
});
Notification
[
capitalCamel
(
intent
)]
=
subclass
;
});
// set more sensible defaults for Notification.Mini views
// create Notification.Warning, Notification.Confirmation, etc
var
miniOptions
=
Notification
.
Mini
.
prototype
.
options
;
var
capitalCamel
,
intents
;
miniOptions
.
minShown
=
1250
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
miniOptions
.
closeIcon
=
false
;
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
subclass
=
Notification
.
extend
({
options
:
$
.
extend
({},
Notification
.
prototype
.
options
,
{
intent
:
intent
})
});
Notification
[
capitalCamel
(
intent
)]
=
subclass
;
});
// set more sensible defaults for Notification.Mini views
var
miniOptions
=
Notification
.
Mini
.
prototype
.
options
;
miniOptions
.
minShown
=
1250
;
miniOptions
.
closeIcon
=
false
;
return
Notification
;
return
Notification
;
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/components/views/feedback_prompt.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"js/views/feedback"
],
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
;(
function
(
define
)
{
var
Prompt
=
SystemFeedbackView
.
extend
({
'use strict'
;
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
define
([
"jquery"
,
"underscore"
,
"underscore.string"
,
"common/js/components/views/feedback"
],
type
:
"prompt"
,
function
(
$
,
_
,
str
,
SystemFeedbackView
)
{
closeIcon
:
false
,
str
=
str
||
_
.
str
;
icon
:
false
var
Prompt
=
SystemFeedbackView
.
extend
({
}),
options
:
$
.
extend
({},
SystemFeedbackView
.
prototype
.
options
,
{
render
:
function
()
{
type
:
"prompt"
,
if
(
!
window
.
$body
)
{
window
.
$body
=
$
(
document
.
body
);
}
closeIcon
:
false
,
if
(
this
.
options
.
shown
)
{
icon
:
false
$body
.
addClass
(
'prompt-is-shown'
);
}),
}
else
{
render
:
function
()
{
$body
.
removeClass
(
'prompt-is-shown'
);
if
(
!
window
.
$body
)
{
window
.
$body
=
$
(
document
.
body
);
}
}
if
(
this
.
options
.
shown
)
{
// super() in Javascript has awkward syntax :(
$body
.
addClass
(
'prompt-is-shown'
);
return
SystemFeedbackView
.
prototype
.
render
.
apply
(
this
,
arguments
);
}
else
{
}
$body
.
removeClass
(
'prompt-is-shown'
);
});
}
// super() in Javascript has awkward syntax :(
return
SystemFeedbackView
.
prototype
.
render
.
apply
(
this
,
arguments
);
}
});
// create Prompt.Warning, Prompt.Confirmation, etc
// create Prompt.Warning, Prompt.Confirmation, etc
var
capitalCamel
,
intents
;
var
capitalCamel
,
intents
;
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
capitalCamel
=
_
.
compose
(
str
.
capitalize
,
str
.
camelize
);
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
intents
=
[
"warning"
,
"error"
,
"confirmation"
,
"announcement"
,
"step-required"
,
"help"
,
"mini"
];
_
.
each
(
intents
,
function
(
intent
)
{
_
.
each
(
intents
,
function
(
intent
)
{
var
subclass
;
var
subclass
;
subclass
=
Prompt
.
extend
({
subclass
=
Prompt
.
extend
({
options
:
$
.
extend
({},
Prompt
.
prototype
.
options
,
{
options
:
$
.
extend
({},
Prompt
.
prototype
.
options
,
{
intent
:
intent
intent
:
intent
})
})
});
});
Prompt
[
capitalCamel
(
intent
)]
=
subclass
;
Prompt
[
capitalCamel
(
intent
)]
=
subclass
;
});
});
return
Prompt
;
return
Prompt
;
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/js/spec/components/feedback_spec.js
0 → 100644
View file @
d8b419c6
// Generated by CoffeeScript 1.6.1
(
function
()
{
define
([
"jquery"
,
"common/js/components/views/feedback"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_alert"
,
"common/js/components/views/feedback_prompt"
,
"sinon"
],
function
(
$
,
SystemFeedback
,
NotificationView
,
AlertView
,
PromptView
,
sinon
)
{
var
tpl
;
tpl
=
readFixtures
(
'system-feedback.underscore'
);
beforeEach
(
function
()
{
setFixtures
(
sandbox
({
id
:
"page-alert"
}));
appendSetFixtures
(
sandbox
({
id
:
"page-notification"
}));
appendSetFixtures
(
sandbox
({
id
:
"page-prompt"
}));
appendSetFixtures
(
$
(
"<script>"
,
{
id
:
"system-feedback-tpl"
,
type
:
"text/template"
}).
text
(
tpl
));
return
this
.
addMatchers
({
toBeShown
:
function
()
{
return
this
.
actual
.
hasClass
(
"is-shown"
)
&&
!
this
.
actual
.
hasClass
(
"is-hiding"
);
},
toBeHiding
:
function
()
{
return
this
.
actual
.
hasClass
(
"is-hiding"
)
&&
!
this
.
actual
.
hasClass
(
"is-shown"
);
},
toContainText
:
function
(
text
)
{
var
trimmedText
;
trimmedText
=
$
.
trim
(
this
.
actual
.
text
());
if
(
text
&&
$
.
isFunction
(
text
.
test
))
{
return
text
.
test
(
trimmedText
);
}
else
{
return
trimmedText
.
indexOf
(
text
)
!==
-
1
;
}
},
toHaveBeenPrevented
:
function
()
{
var
eventName
,
selector
;
eventName
=
this
.
actual
.
eventName
;
selector
=
this
.
actual
.
selector
;
this
.
message
=
function
()
{
return
[
"Expected event "
+
eventName
+
" to have been prevented on "
+
selector
,
"Expected event "
+
eventName
+
" not to have been prevented on "
+
selector
];
};
return
jasmine
.
JQuery
.
events
.
wasPrevented
(
selector
,
eventName
);
}
});
});
describe
(
"SystemFeedback"
,
function
()
{
beforeEach
(
function
()
{
this
.
options
=
{
title
:
"Portal"
,
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
};
this
.
renderSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'render'
).
andCallThrough
();
this
.
showSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'show'
).
andCallThrough
();
this
.
hideSpy
=
spyOn
(
AlertView
.
Confirmation
.
prototype
,
'hide'
).
andCallThrough
();
return
this
.
clock
=
sinon
.
useFakeTimers
();
});
afterEach
(
function
()
{
return
this
.
clock
.
restore
();
});
it
(
"requires a type and an intent"
,
function
()
{
var
both
,
neither
,
noIntent
,
noType
,
_this
=
this
;
neither
=
function
()
{
return
new
SystemFeedback
(
_this
.
options
);
};
noType
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
intent
=
"confirmation"
;
return
new
SystemFeedback
(
options
);
};
noIntent
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
type
=
"alert"
;
return
new
SystemFeedback
(
options
);
};
both
=
function
()
{
var
options
;
options
=
$
.
extend
({},
_this
.
options
);
options
.
type
=
"alert"
;
options
.
intent
=
"confirmation"
;
return
new
SystemFeedback
(
options
);
};
expect
(
neither
).
toThrow
();
expect
(
noType
).
toThrow
();
expect
(
noIntent
).
toThrow
();
return
expect
(
both
).
not
.
toThrow
();
});
it
(
"does not show on initalize"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
);
expect
(
this
.
renderSpy
).
not
.
toHaveBeenCalled
();
return
expect
(
this
.
showSpy
).
not
.
toHaveBeenCalled
();
});
xit
(
"renders the template"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
);
view
.
show
();
expect
(
view
.
$
(
".action-close"
)).
toBeDefined
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
expect
(
view
.
$el
).
toContainText
(
this
.
options
.
title
);
return
expect
(
view
.
$el
).
toContainText
(
this
.
options
.
message
);
});
return
xit
(
"close button sends a .hide() message"
,
function
()
{
var
view
;
view
=
new
AlertView
.
Confirmation
(
this
.
options
).
show
();
view
.
$
(
".action-close"
).
click
();
expect
(
this
.
hideSpy
).
toHaveBeenCalled
();
this
.
clock
.
tick
(
900
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
});
describe
(
"PromptView"
,
function
()
{
return
it
(
"changes class on body"
,
function
()
{
var
view
;
view
=
new
PromptView
.
Confirmation
({
title
:
"Portal"
,
message
:
"Welcome to the Aperture Science Computer-Aided Enrichment Center"
});
return
view
.
hide
();
});
});
describe
(
"NotificationView.Mini"
,
function
()
{
beforeEach
(
function
()
{
return
this
.
view
=
new
NotificationView
.
Mini
();
});
it
(
"should have minShown set to 1250 by default"
,
function
()
{
return
expect
(
this
.
view
.
options
.
minShown
).
toEqual
(
1250
);
});
return
it
(
"should have closeIcon set to false by default"
,
function
()
{
return
expect
(
this
.
view
.
options
.
closeIcon
).
toBeFalsy
();
});
});
xdescribe
(
"SystemFeedback click events"
,
function
()
{
beforeEach
(
function
()
{
this
.
primaryClickSpy
=
jasmine
.
createSpy
(
'primaryClick'
);
this
.
secondaryClickSpy
=
jasmine
.
createSpy
(
'secondaryClick'
);
this
.
view
=
new
NotificationView
.
Warning
({
title
:
"Unsaved"
,
message
:
"Your content is currently Unsaved."
,
actions
:
{
primary
:
{
text
:
"Save"
,
"class"
:
"save-button"
,
click
:
this
.
primaryClickSpy
},
secondary
:
{
text
:
"Revert"
,
"class"
:
"cancel-button"
,
click
:
this
.
secondaryClickSpy
}
}
});
return
this
.
view
.
show
();
});
it
(
"should trigger the primary event on a primary click"
,
function
()
{
this
.
view
.
$
(
".action-primary"
).
click
();
expect
(
this
.
primaryClickSpy
).
toHaveBeenCalled
();
return
expect
(
this
.
secondaryClickSpy
).
not
.
toHaveBeenCalled
();
});
it
(
"should trigger the secondary event on a secondary click"
,
function
()
{
this
.
view
.
$
(
".action-secondary"
).
click
();
expect
(
this
.
secondaryClickSpy
).
toHaveBeenCalled
();
return
expect
(
this
.
primaryClickSpy
).
not
.
toHaveBeenCalled
();
});
it
(
"should apply class to primary action"
,
function
()
{
return
expect
(
this
.
view
.
$
(
".action-primary"
)).
toHaveClass
(
"save-button"
);
});
it
(
"should apply class to secondary action"
,
function
()
{
return
expect
(
this
.
view
.
$
(
".action-secondary"
)).
toHaveClass
(
"cancel-button"
);
});
it
(
"should preventDefault on primary action"
,
function
()
{
spyOnEvent
(
".action-primary"
,
"click"
);
this
.
view
.
$
(
".action-primary"
).
click
();
return
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-primary"
);
});
return
it
(
"should preventDefault on secondary action"
,
function
()
{
spyOnEvent
(
".action-secondary"
,
"click"
);
this
.
view
.
$
(
".action-secondary"
).
click
();
return
expect
(
"click"
).
toHaveBeenPreventedOn
(
".action-secondary"
);
});
});
xdescribe
(
"SystemFeedback not preventing events"
,
function
()
{
beforeEach
(
function
()
{
this
.
clickSpy
=
jasmine
.
createSpy
(
'clickSpy'
);
this
.
view
=
new
AlertView
.
Confirmation
({
title
:
"It's all good"
,
message
:
"No reason for this alert"
,
actions
:
{
primary
:
{
text
:
"Whatever"
,
click
:
this
.
clickSpy
,
preventDefault
:
false
}
}
});
return
this
.
view
.
show
();
});
return
it
(
"should not preventDefault"
,
function
()
{
spyOnEvent
(
".action-primary"
,
"click"
);
this
.
view
.
$
(
".action-primary"
).
click
();
expect
(
"click"
).
not
.
toHaveBeenPreventedOn
(
".action-primary"
);
return
expect
(
this
.
clickSpy
).
toHaveBeenCalled
();
});
});
xdescribe
(
"SystemFeedback multiple secondary actions"
,
function
()
{
beforeEach
(
function
()
{
this
.
secondarySpyOne
=
jasmine
.
createSpy
(
'secondarySpyOne'
);
this
.
secondarySpyTwo
=
jasmine
.
createSpy
(
'secondarySpyTwo'
);
this
.
view
=
new
NotificationView
.
Warning
({
title
:
"No Primary"
,
message
:
"Pick a secondary action"
,
actions
:
{
secondary
:
[
{
text
:
"Option One"
,
"class"
:
"option-one"
,
click
:
this
.
secondarySpyOne
},
{
text
:
"Option Two"
,
"class"
:
"option-two"
,
click
:
this
.
secondarySpyTwo
}
]
}
});
return
this
.
view
.
show
();
});
it
(
"should render both"
,
function
()
{
expect
(
this
.
view
.
el
).
toContain
(
".action-secondary.option-one"
);
expect
(
this
.
view
.
el
).
toContain
(
".action-secondary.option-two"
);
expect
(
this
.
view
.
el
).
not
.
toContain
(
".action-secondary.option-one.option-two"
);
expect
(
this
.
view
.
$
(
".action-secondary.option-one"
)).
toContainText
(
"Option One"
);
return
expect
(
this
.
view
.
$
(
".action-secondary.option-two"
)).
toContainText
(
"Option Two"
);
});
it
(
"should differentiate clicks (1)"
,
function
()
{
this
.
view
.
$
(
".option-one"
).
click
();
expect
(
this
.
secondarySpyOne
).
toHaveBeenCalled
();
return
expect
(
this
.
secondarySpyTwo
).
not
.
toHaveBeenCalled
();
});
return
it
(
"should differentiate clicks (2)"
,
function
()
{
this
.
view
.
$
(
".option-two"
).
click
();
expect
(
this
.
secondarySpyOne
).
not
.
toHaveBeenCalled
();
return
expect
(
this
.
secondarySpyTwo
).
toHaveBeenCalled
();
});
});
return
describe
(
"NotificationView minShown and maxShown"
,
function
()
{
beforeEach
(
function
()
{
this
.
showSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'show'
);
this
.
showSpy
.
andCallThrough
();
this
.
hideSpy
=
spyOn
(
NotificationView
.
Confirmation
.
prototype
,
'hide'
);
this
.
hideSpy
.
andCallThrough
();
return
this
.
clock
=
sinon
.
useFakeTimers
();
});
afterEach
(
function
()
{
return
this
.
clock
.
restore
();
});
xit
(
"should not have minShown or maxShown by default"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
();
expect
(
view
.
options
.
minShown
).
toEqual
(
0
);
return
expect
(
view
.
options
.
maxShown
).
toEqual
(
Infinity
);
});
xit
(
"a minShown view should not hide too quickly"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a maxShown view should hide by itself"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a minShown view can stay visible longer"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1001
);
expect
(
this
.
hideSpy
).
not
.
toHaveBeenCalled
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
view
.
hide
();
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
xit
(
"a maxShown view can hide early"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
maxShown
:
1000
});
view
.
show
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
50
);
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
this
.
clock
.
tick
(
1000
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
return
it
(
"a view can have both maxShown and minShown"
,
function
()
{
var
view
;
view
=
new
NotificationView
.
Confirmation
({
minShown
:
1000
,
maxShown
:
2000
});
view
.
show
();
this
.
clock
.
tick
(
50
);
view
.
hide
();
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1000
);
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
view
.
show
();
this
.
clock
.
tick
(
1050
);
expect
(
view
.
$
(
'.wrapper'
)).
toBeShown
();
this
.
clock
.
tick
(
1000
);
return
expect
(
view
.
$
(
'.wrapper'
)).
toBeHiding
();
});
});
});
}).
call
(
this
);
common/static/common/js/spec/components/view_utils_spec.js
View file @
d8b419c6
define
([
"jquery"
,
"underscore"
,
"js/views/baseview"
,
"js/views/utils/view_utils"
,
"js/spec_helpers/edit_helpers"
],
;(
function
(
define
)
{
function
(
$
,
_
,
BaseView
,
ViewUtils
,
ViewHelpers
)
{
'use strict'
;
define
([
"jquery"
,
"underscore"
,
"common/js/components/utils/view_utils"
,
"common/js/spec_helpers/view_helpers"
,
'jasmine-stealth'
],
function
(
$
,
_
,
ViewUtils
,
ViewHelpers
)
{
describe
(
"ViewUtils"
,
function
()
{
describe
(
"ViewUtils"
,
function
()
{
describe
(
"disabled element while running"
,
function
()
{
describe
(
"disabled element while running"
,
function
()
{
...
@@ -90,3 +92,4 @@ define(["jquery", "underscore", "js/views/baseview", "js/views/utils/view_utils"
...
@@ -90,3 +92,4 @@ define(["jquery", "underscore", "js/views/baseview", "js/views/utils/view_utils"
});
});
});
});
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
\ No newline at end of file
common/static/common/js/spec_helpers/view_helpers.js
View file @
d8b419c6
/**
/**
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
* Provides helper methods for invoking Studio modal windows in Jasmine tests.
*/
*/
define
([
"jquery"
,
"js/views/feedback_notification"
,
"js/views/feedback_prompt"
,
'common/js/spec_helpers/ajax_helpers'
,
;(
function
(
define
)
{
"common/js/spec_helpers/template_helpers"
],
'use strict'
;
function
(
$
,
NotificationView
,
Prompt
,
AjaxHelpers
,
TemplateHelpers
)
{
define
([
"jquery"
,
"common/js/components/views/feedback_notification"
,
"common/js/components/views/feedback_prompt"
,
'common/js/spec_helpers/ajax_helpers'
],
function
(
$
,
NotificationView
,
Prompt
,
AjaxHelpers
)
{
var
installViewTemplates
,
createFeedbackSpy
,
verifyFeedbackShowing
,
var
installViewTemplates
,
createFeedbackSpy
,
verifyFeedbackShowing
,
verifyFeedbackHidden
,
createNotificationSpy
,
verifyNotificationShowing
,
verifyFeedbackHidden
,
createNotificationSpy
,
verifyNotificationShowing
,
verifyNotificationHidden
,
createPromptSpy
,
confirmPrompt
,
inlineEdit
,
verifyInlineEditChange
,
verifyNotificationHidden
,
createPromptSpy
,
confirmPrompt
,
inlineEdit
,
verifyInlineEditChange
,
installMockAnalytics
,
removeMockAnalytics
,
verifyPromptShowing
,
verifyPromptHidden
;
installMockAnalytics
,
removeMockAnalytics
,
verifyPromptShowing
,
verifyPromptHidden
,
clickDeleteItem
,
patchAndVerifyRequest
,
submitAndVerifyFormSuccess
,
submitAndVerifyFormError
;
installViewTemplates
=
function
(
append
)
{
installViewTemplates
=
function
()
{
TemplateHelpers
.
installTemplate
(
'system-feedback'
,
!
append
);
appendSetFixtures
(
'<div id="page-notification"></div>'
);
appendSetFixtures
(
'<div id="page-notification"></div>'
);
};
};
...
@@ -144,3 +146,4 @@ define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt",
...
@@ -144,3 +146,4 @@ define(["jquery", "js/views/feedback_notification", "js/views/feedback_prompt",
'submitAndVerifyFormError'
:
submitAndVerifyFormError
'submitAndVerifyFormError'
:
submitAndVerifyFormError
};
};
});
});
}).
call
(
this
,
define
||
RequireJS
.
define
);
common/static/common/templates/components/system-feedback.underscore
View file @
d8b419c6
...
@@ -21,17 +21,16 @@
...
@@ -21,17 +21,16 @@
<% if(obj.actions) { %>
<% if(obj.actions) { %>
<nav class="nav-actions">
<nav class="nav-actions">
<h3 class="sr"><%= type %> Actions</h3>
<ul>
<ul>
<% if(actions.primary) { %>
<% if(actions.primary) { %>
<li class="nav-item">
<li class="nav-item">
<
a href="#" class="button action-primary <%= actions.primary.class %>"><%= actions.primary.text %></a
>
<
button class="action-primary <%= actions.primary.class %>"><%= actions.primary.text %></button
>
</li>
</li>
<% } %>
<% } %>
<% if(actions.secondary) {
<% if(actions.secondary) {
_.each(actions.secondary, function(secondary) { %>
_.each(actions.secondary, function(secondary) { %>
<li class="nav-item">
<li class="nav-item">
<
a href="#" class="button action-secondary <%= secondary.class %>"><%= secondary.text %></a
>
<
button class="action-secondary <%= secondary.class %>"><%= secondary.text %></button
>
</li>
</li>
<% });
<% });
} %>
} %>
...
...
lms/djangoapps/teams/static/teams/js/spec/views/team_profile_spec.js
View file @
d8b419c6
...
@@ -74,13 +74,13 @@ define([
...
@@ -74,13 +74,13 @@ define([
return
profileView
;
return
profileView
;
};
};
clickLeaveTeam
=
function
(
requests
,
view
,
confirmLeave
)
{
clickLeaveTeam
=
function
(
requests
,
view
,
options
)
{
expect
(
view
.
$
(
leaveTeamLinkSelector
).
length
).
toBe
(
1
);
expect
(
view
.
$
(
leaveTeamLinkSelector
).
length
).
toBe
(
1
);
// click on Leave Team link under Team Details
// click on Leave Team link under Team Details
view
.
$
(
leaveTeamLinkSelector
).
click
();
view
.
$
(
leaveTeamLinkSelector
).
click
();
if
(
confirmLeave
)
{
if
(
!
options
.
cancel
)
{
// click on Confirm button on dialog
// click on Confirm button on dialog
$
(
'.prompt.warning .action-primary'
).
click
();
$
(
'.prompt.warning .action-primary'
).
click
();
...
@@ -121,7 +121,7 @@ define([
...
@@ -121,7 +121,7 @@ define([
view
=
createTeamProfileView
(
requests
,
{
membership
:
DEFAULT_MEMBERSHIP
});
view
=
createTeamProfileView
(
requests
,
{
membership
:
DEFAULT_MEMBERSHIP
});
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
1
);
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
1
);
clickLeaveTeam
(
requests
,
view
,
true
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
false
}
);
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
0
);
expect
(
view
.
$
(
'.new-post-btn'
).
length
).
toEqual
(
0
);
});
});
});
});
...
@@ -188,7 +188,7 @@ define([
...
@@ -188,7 +188,7 @@ define([
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
);
);
assertTeamDetails
(
view
,
1
,
true
);
assertTeamDetails
(
view
,
1
,
true
);
clickLeaveTeam
(
requests
,
view
,
true
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
false
}
);
assertTeamDetails
(
view
,
0
,
false
);
assertTeamDetails
(
view
,
0
,
false
);
});
});
...
@@ -199,7 +199,7 @@ define([
...
@@ -199,7 +199,7 @@ define([
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
requests
,
{
country
:
'US'
,
language
:
'en'
,
membership
:
DEFAULT_MEMBERSHIP
}
);
);
assertTeamDetails
(
view
,
1
,
true
);
assertTeamDetails
(
view
,
1
,
true
);
clickLeaveTeam
(
requests
,
view
,
false
);
clickLeaveTeam
(
requests
,
view
,
{
cancel
:
true
}
);
assertTeamDetails
(
view
,
1
,
true
);
assertTeamDetails
(
view
,
1
,
true
);
});
});
...
...
lms/static/sass/_build-lms.scss
View file @
d8b419c6
...
@@ -81,4 +81,4 @@
...
@@ -81,4 +81,4 @@
// overrides
// overrides
@import
'developer'
;
// used for any developer-created scss that needs further polish/refactoring
@import
'developer'
;
// used for any developer-created scss that needs further polish/refactoring
@import
'shame'
;
//
used
for
any
bad-form
/
orphaned
scss
@import
'shame'
;
// used for any bad-form/orphaned scss
\ No newline at end of file
lms/static/sass/_mixins-inherited.scss
0 → 120000
View file @
d8b419c6
..
/
..
/
..
/
common
/
static
/
sass
/
_mixins-inherited
.scss
\ No newline at end of file
lms/static/sass/_mixins.scss
0 → 120000
View file @
d8b419c6
..
/
..
/
..
/
common
/
static
/
sass
/
_mixins
.scss
\ No newline at end of file
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