Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
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
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
5eaca3c7
Commit
5eaca3c7
authored
Jan 23, 2020
by
Lyza Danger Gardner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor `AnnotationPublishControl` to handle `revert` and `setPrivacy`
parent
da333b79
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
141 additions
and
241 deletions
+141
-241
annotation-omega.js
src/sidebar/components/annotation-omega.js
+2
-15
annotation-publish-control.js
src/sidebar/components/annotation-publish-control.js
+36
-20
annotation.js
src/sidebar/components/annotation.js
+0
-38
annotation-omega-test.js
src/sidebar/components/test/annotation-omega-test.js
+9
-71
annotation-publish-control-test.js
...idebar/components/test/annotation-publish-control-test.js
+92
-22
annotation-test.js
src/sidebar/components/test/annotation-test.js
+0
-70
annotation.html
src/sidebar/templates/annotation.html
+2
-5
No files found.
src/sidebar/components/annotation-omega.js
View file @
5eaca3c7
...
@@ -2,7 +2,7 @@ import { createElement } from 'preact';
...
@@ -2,7 +2,7 @@ import { createElement } from 'preact';
import
propTypes
from
'prop-types'
;
import
propTypes
from
'prop-types'
;
import
useStore
from
'../store/use-store'
;
import
useStore
from
'../store/use-store'
;
import
{
isNew
,
isReply
,
quote
}
from
'../util/annotation-metadata'
;
import
{
isNew
,
quote
}
from
'../util/annotation-metadata'
;
import
{
isShared
}
from
'../util/permissions'
;
import
{
isShared
}
from
'../util/permissions'
;
import
AnnotationActionBar
from
'./annotation-action-bar'
;
import
AnnotationActionBar
from
'./annotation-action-bar'
;
...
@@ -24,7 +24,6 @@ function AnnotationOmega({
...
@@ -24,7 +24,6 @@ function AnnotationOmega({
showDocumentInfo
,
showDocumentInfo
,
})
{
})
{
const
createDraft
=
useStore
(
store
=>
store
.
createDraft
);
const
createDraft
=
useStore
(
store
=>
store
.
createDraft
);
const
setDefault
=
useStore
(
store
=>
store
.
setDefault
);
// An annotation will have a draft if it is being edited
// An annotation will have a draft if it is being edited
const
draft
=
useStore
(
store
=>
store
.
getDraft
(
annotation
));
const
draft
=
useStore
(
store
=>
store
.
getDraft
(
annotation
));
...
@@ -50,17 +49,8 @@ function AnnotationOmega({
...
@@ -50,17 +49,8 @@ function AnnotationOmega({
createDraft
(
annotation
,
{
...
draft
,
text
});
createDraft
(
annotation
,
{
...
draft
,
text
});
};
};
const
onSetPrivacy
=
({
level
})
=>
{
createDraft
(
annotation
,
{
...
draft
,
isPrivate
:
level
===
'private'
});
// Persist this as privacy default for future annotations unless this is a reply
if
(
!
isReply
(
annotation
))
{
setDefault
(
'annotationPrivacy'
,
level
);
}
};
// TODO
// TODO
const
fakeOnReply
=
()
=>
alert
(
'Reply: TBD'
);
const
fakeOnReply
=
()
=>
alert
(
'Reply: TBD'
);
const
fakeOnRevert
=
()
=>
alert
(
'Revert changes: TBD'
);
const
fakeOnSave
=
()
=>
alert
(
'Save changes: TBD'
);
const
fakeOnSave
=
()
=>
alert
(
'Save changes: TBD'
);
return
(
return
(
...
@@ -84,12 +74,9 @@ function AnnotationOmega({
...
@@ -84,12 +74,9 @@ function AnnotationOmega({
<
footer
className
=
"annotation-footer"
>
<
footer
className
=
"annotation-footer"
>
{
isEditing
&&
(
{
isEditing
&&
(
<
AnnotationPublishControl
<
AnnotationPublishControl
group
=
{
group
}
annotation
=
{
annotation
}
isDisabled
=
{
isEmpty
}
isDisabled
=
{
isEmpty
}
isShared
=
{
!
isPrivate
}
onCancel
=
{
fakeOnRevert
}
onSave
=
{
fakeOnSave
}
onSave
=
{
fakeOnSave
}
onSetPrivacy
=
{
onSetPrivacy
}
/
>
/
>
)}
)}
{
shouldShowLicense
&&
<
AnnotationLicense
/>
}
{
shouldShowLicense
&&
<
AnnotationLicense
/>
}
...
...
src/sidebar/components/annotation-publish-control.js
View file @
5eaca3c7
import
{
createElement
}
from
'preact'
;
import
{
createElement
}
from
'preact'
;
import
propTypes
from
'prop-types'
;
import
propTypes
from
'prop-types'
;
import
useStore
from
'../store/use-store'
;
import
{
isNew
,
isReply
}
from
'../util/annotation-metadata'
;
import
{
isShared
}
from
'../util/permissions'
;
import
{
withServices
}
from
'../util/service-context'
;
import
{
withServices
}
from
'../util/service-context'
;
import
{
applyTheme
}
from
'../util/theme'
;
import
{
applyTheme
}
from
'../util/theme'
;
...
@@ -15,17 +18,40 @@ import MenuItem from './menu-item';
...
@@ -15,17 +18,40 @@ import MenuItem from './menu-item';
*
*
*/
*/
function
AnnotationPublishControl
({
function
AnnotationPublishControl
({
group
,
annotation
,
isDisabled
,
isDisabled
,
isShared
,
onCancel
,
onSave
,
onSave
,
onSetPrivacy
,
settings
,
settings
,
})
{
})
{
const
publishDestination
=
isShared
?
group
.
name
:
'Only Me'
;
const
draft
=
useStore
(
store
=>
store
.
getDraft
(
annotation
));
const
group
=
useStore
(
store
=>
store
.
getGroup
(
annotation
.
group
));
const
createDraft
=
useStore
(
store
=>
store
.
createDraft
);
const
removeDraft
=
useStore
(
store
=>
store
.
removeDraft
);
const
setDefault
=
useStore
(
store
=>
store
.
setDefault
);
const
removeAnnotations
=
useStore
(
store
=>
store
.
removeAnnotations
);
const
isPrivate
=
draft
?
draft
.
isPrivate
:
!
isShared
(
annotation
.
permissions
);
const
publishDestination
=
isPrivate
?
'Only Me'
:
group
.
name
;
const
themeProps
=
[
'ctaTextColor'
,
'ctaBackgroundColor'
];
const
themeProps
=
[
'ctaTextColor'
,
'ctaBackgroundColor'
];
// Revert changes to this annotation
const
onCancel
=
()
=>
{
removeDraft
(
annotation
);
if
(
isNew
(
annotation
))
{
removeAnnotations
([
annotation
]);
}
};
const
onSetPrivacy
=
level
=>
{
createDraft
(
annotation
,
{
...
draft
,
isPrivate
:
level
===
'private'
});
// Persist this as privacy default for future annotations unless this is a reply
if
(
!
isReply
(
annotation
))
{
setDefault
(
'annotationPrivacy'
,
level
);
}
};
const
menuLabel
=
(
const
menuLabel
=
(
<
div
className
=
"annotation-publish-control__btn-dropdown-arrow"
>
<
div
className
=
"annotation-publish-control__btn-dropdown-arrow"
>
<
div
className
=
"annotation-publish-control__btn-dropdown-arrow-separator"
/>
<
div
className
=
"annotation-publish-control__btn-dropdown-arrow-separator"
/>
...
@@ -62,14 +88,14 @@ function AnnotationPublishControl({
...
@@ -62,14 +88,14 @@ function AnnotationPublishControl({
<
MenuItem
<
MenuItem
icon
=
{
group
.
type
===
'open'
?
'public'
:
'groups'
}
icon
=
{
group
.
type
===
'open'
?
'public'
:
'groups'
}
label
=
{
group
.
name
}
label
=
{
group
.
name
}
isSelected
=
{
isShared
}
isSelected
=
{
!
isPrivate
}
onClick
=
{()
=>
onSetPrivacy
(
{
level
:
'shared'
}
)}
onClick
=
{()
=>
onSetPrivacy
(
'shared'
)}
/
>
/
>
<
MenuItem
<
MenuItem
icon
=
"lock"
icon
=
"lock"
label
=
"Only Me"
label
=
"Only Me"
isSelected
=
{
!
isShared
}
isSelected
=
{
isPrivate
}
onClick
=
{()
=>
onSetPrivacy
(
{
level
:
'private'
}
)}
onClick
=
{()
=>
onSetPrivacy
(
'private'
)}
/
>
/
>
<
/Menu
>
<
/Menu
>
<
/div
>
<
/div
>
...
@@ -84,8 +110,7 @@ function AnnotationPublishControl({
...
@@ -84,8 +110,7 @@ function AnnotationPublishControl({
}
}
AnnotationPublishControl
.
propTypes
=
{
AnnotationPublishControl
.
propTypes
=
{
/** The group the annotation is currently associated with */
annotation
:
propTypes
.
object
.
isRequired
,
group
:
propTypes
.
object
.
isRequired
,
/**
/**
* Should the save button be disabled?
* Should the save button be disabled?
...
@@ -93,18 +118,9 @@ AnnotationPublishControl.propTypes = {
...
@@ -93,18 +118,9 @@ AnnotationPublishControl.propTypes = {
*/
*/
isDisabled
:
propTypes
.
bool
,
isDisabled
:
propTypes
.
bool
,
/** The current privacy setting on the annotation. Is it shared to group? */
isShared
:
propTypes
.
bool
,
/** Callback for cancel button click */
onCancel
:
propTypes
.
func
.
isRequired
,
/** Callback for save button click */
/** Callback for save button click */
onSave
:
propTypes
.
func
.
isRequired
,
onSave
:
propTypes
.
func
.
isRequired
,
/** Callback when selecting a privacy option in the menu */
onSetPrivacy
:
propTypes
.
func
.
isRequired
,
/** services */
/** services */
settings
:
propTypes
.
object
.
isRequired
,
settings
:
propTypes
.
object
.
isRequired
,
};
};
...
...
src/sidebar/components/annotation.js
View file @
5eaca3c7
...
@@ -261,18 +261,6 @@ function AnnotationController(
...
@@ -261,18 +261,6 @@ function AnnotationController(
});
});
};
};
/**
* @ngdoc method
* @name annotation.AnnotationController#revert
* @description Reverts an edit in progress and returns to the viewer.
*/
this
.
revert
=
function
()
{
store
.
removeDraft
(
self
.
annotation
);
if
(
isNew
(
self
.
annotation
))
{
$rootScope
.
$broadcast
(
events
.
ANNOTATION_DELETED
,
self
.
annotation
);
}
};
this
.
save
=
function
()
{
this
.
save
=
function
()
{
if
(
!
self
.
annotation
.
user
)
{
if
(
!
self
.
annotation
.
user
)
{
flash
.
info
(
'Please log in to save your annotations.'
);
flash
.
info
(
'Please log in to save your annotations.'
);
...
@@ -313,32 +301,6 @@ function AnnotationController(
...
@@ -313,32 +301,6 @@ function AnnotationController(
});
});
};
};
/**
* @ngdoc method
* @name annotation.AnnotationController#setPrivacy
*
* Set the privacy settings on the annotation to a predefined
* level. The supported levels are 'private' which makes the annotation
* visible only to its creator and 'shared' which makes the annotation
* visible to everyone in the group.
*
* The changes take effect when the annotation is saved
*/
this
.
setPrivacy
=
function
(
privacy
)
{
// When the user changes the privacy level of an annotation they're
// creating or editing, we cache that and use the same privacy level the
// next time they create an annotation.
// But _don't_ cache it when they change the privacy level of a reply.
if
(
!
isReply
(
self
.
annotation
))
{
permissions
.
setDefault
(
privacy
);
}
store
.
createDraft
(
self
.
annotation
,
{
tags
:
self
.
state
().
tags
,
text
:
self
.
state
().
text
,
isPrivate
:
privacy
===
'private'
,
});
};
this
.
user
=
function
()
{
this
.
user
=
function
()
{
return
self
.
annotation
.
user
;
return
self
.
annotation
.
user
;
};
};
...
...
src/sidebar/components/test/annotation-omega-test.js
View file @
5eaca3c7
...
@@ -45,7 +45,6 @@ describe('AnnotationOmega', () => {
...
@@ -45,7 +45,6 @@ describe('AnnotationOmega', () => {
fakeMetadata
=
{
fakeMetadata
=
{
isNew
:
sinon
.
stub
(),
isNew
:
sinon
.
stub
(),
isReply
:
sinon
.
stub
().
returns
(
false
),
quote
:
sinon
.
stub
(),
quote
:
sinon
.
stub
(),
};
};
...
@@ -59,7 +58,6 @@ describe('AnnotationOmega', () => {
...
@@ -59,7 +58,6 @@ describe('AnnotationOmega', () => {
getGroup
:
sinon
.
stub
().
returns
({
getGroup
:
sinon
.
stub
().
returns
({
type
:
'private'
,
type
:
'private'
,
}),
}),
setDefault
:
sinon
.
stub
(),
};
};
$imports
.
$mock
(
mockImportedComponents
());
$imports
.
$mock
(
mockImportedComponents
());
...
@@ -157,89 +155,29 @@ describe('AnnotationOmega', () => {
...
@@ -157,89 +155,29 @@ describe('AnnotationOmega', () => {
assert
.
isFalse
(
wrapper
.
find
(
'AnnotationPublishControl'
).
exists
());
assert
.
isFalse
(
wrapper
.
find
(
'AnnotationPublishControl'
).
exists
());
});
});
it
(
'should
set the publish control to disabled if annotation is
empty'
,
()
=>
{
it
(
'should
enable the publish control if the annotation is not
empty'
,
()
=>
{
const
draft
=
fixtures
.
defaultDraft
();
const
draft
=
fixtures
.
defaultDraft
();
draft
.
tags
=
[];
draft
.
text
=
'bananas'
;
draft
.
text
=
''
;
fakeStore
.
getDraft
.
returns
(
draft
);
fakeStore
.
getDraft
.
returns
(
draft
);
const
wrapper
=
createComponent
();
const
wrapper
=
createComponent
();
assert
.
is
Tru
e
(
assert
.
is
Fals
e
(
wrapper
.
find
(
'AnnotationPublishControl'
).
props
().
isDisabled
wrapper
.
find
(
'AnnotationPublishControl'
).
props
().
isDisabled
);
);
});
});
it
(
'should set `isShared` to `false` if annotation is private'
,
()
=>
{
it
(
'should set the publish control to disabled if annotation is empty'
,
()
=>
{
const
draft
=
fixtures
.
defaultDraft
();
draft
.
isPrivate
=
true
;
fakeStore
.
getDraft
.
returns
(
draft
);
const
wrapper
=
createComponent
();
assert
.
isFalse
(
wrapper
.
find
(
'AnnotationPublishControl'
).
props
().
isShared
);
});
it
(
'should set `isShared` to `true` if annotation is shared'
,
()
=>
{
const
draft
=
fixtures
.
defaultDraft
();
const
draft
=
fixtures
.
defaultDraft
();
draft
.
isPrivate
=
false
;
draft
.
tags
=
[];
draft
.
text
=
''
;
fakeStore
.
getDraft
.
returns
(
draft
);
fakeStore
.
getDraft
.
returns
(
draft
);
const
wrapper
=
createComponent
();
const
wrapper
=
createComponent
();
assert
.
isTrue
(
wrapper
.
find
(
'AnnotationPublishControl'
).
props
().
isShared
);
assert
.
isTrue
(
});
wrapper
.
find
(
'AnnotationPublishControl'
).
props
().
isDisabled
);
it
(
'should update annotation privacy when changed by publish control'
,
()
=>
{
setEditingMode
(
true
);
const
wrapper
=
createComponent
();
act
(()
=>
{
wrapper
.
find
(
'AnnotationPublishControl'
)
.
props
()
.
onSetPrivacy
({
level
:
'private'
});
});
const
call
=
fakeStore
.
createDraft
.
getCall
(
0
);
assert
.
calledOnce
(
fakeStore
.
createDraft
);
assert
.
isTrue
(
call
.
args
[
1
].
isPrivate
);
});
it
(
'should update annotation privacy default on change'
,
()
=>
{
setEditingMode
(
true
);
const
wrapper
=
createComponent
();
act
(()
=>
{
wrapper
.
find
(
'AnnotationPublishControl'
)
.
props
()
.
onSetPrivacy
({
level
:
'private'
});
});
assert
.
calledOnce
(
fakeStore
.
setDefault
);
assert
.
calledWith
(
fakeStore
.
setDefault
,
'annotationPrivacy'
,
'private'
);
});
it
(
'should not update annotation privacy default on change if annotation is reply'
,
()
=>
{
fakeMetadata
.
isReply
.
returns
(
true
);
setEditingMode
(
true
);
const
wrapper
=
createComponent
();
act
(()
=>
{
wrapper
.
find
(
'AnnotationPublishControl'
)
.
props
()
.
onSetPrivacy
({
level
:
'private'
});
});
assert
.
equal
(
fakeStore
.
setDefault
.
callCount
,
0
);
});
});
});
});
...
...
src/sidebar/components/test/annotation-publish-control-test.js
View file @
5eaca3c7
import
{
mount
}
from
'enzyme'
;
import
{
mount
}
from
'enzyme'
;
import
{
createElement
}
from
'preact'
;
import
{
createElement
}
from
'preact'
;
import
*
as
fixtures
from
'../../test/annotation-fixtures'
;
import
AnnotationPublishControl
from
'../annotation-publish-control'
;
import
AnnotationPublishControl
from
'../annotation-publish-control'
;
import
{
$imports
}
from
'../annotation-publish-control'
;
import
{
$imports
}
from
'../annotation-publish-control'
;
...
@@ -8,18 +9,17 @@ import mockImportedComponents from './mock-imported-components';
...
@@ -8,18 +9,17 @@ import mockImportedComponents from './mock-imported-components';
describe
(
'AnnotationPublishControl'
,
()
=>
{
describe
(
'AnnotationPublishControl'
,
()
=>
{
let
fakeGroup
;
let
fakeGroup
;
let
fakeMetadata
;
let
fakeSettings
;
let
fakeSettings
;
let
fakeStore
;
let
fakeApplyTheme
;
let
fakeApplyTheme
;
const
createAnnotationPublishControl
=
(
props
=
{})
=>
{
const
createAnnotationPublishControl
=
(
props
=
{})
=>
{
return
mount
(
return
mount
(
<
AnnotationPublishControl
<
AnnotationPublishControl
group
=
{
fakeGroup
}
annotation
=
{
fixtures
.
defaultAnnotation
()
}
isDisabled
=
{
false
}
isDisabled
=
{
false
}
isShared
=
{
true
}
onCancel
=
{
sinon
.
stub
()}
onSave
=
{
sinon
.
stub
()}
onSave
=
{
sinon
.
stub
()}
onSetPrivacy
=
{
sinon
.
stub
()}
settings
=
{
fakeSettings
}
settings
=
{
fakeSettings
}
{...
props
}
{...
props
}
/
>
/
>
...
@@ -31,6 +31,12 @@ describe('AnnotationPublishControl', () => {
...
@@ -31,6 +31,12 @@ describe('AnnotationPublishControl', () => {
name
:
'Fake Group'
,
name
:
'Fake Group'
,
type
:
'private'
,
type
:
'private'
,
};
};
fakeMetadata
=
{
isNew
:
sinon
.
stub
(),
isReply
:
sinon
.
stub
().
returns
(
false
),
};
fakeSettings
=
{
fakeSettings
=
{
branding
:
{
branding
:
{
ctaTextColor
:
'#0f0'
,
ctaTextColor
:
'#0f0'
,
...
@@ -38,10 +44,21 @@ describe('AnnotationPublishControl', () => {
...
@@ -38,10 +44,21 @@ describe('AnnotationPublishControl', () => {
},
},
};
};
fakeStore
=
{
createDraft
:
sinon
.
stub
(),
getDraft
:
sinon
.
stub
().
returns
(
fixtures
.
defaultDraft
()),
getGroup
:
sinon
.
stub
().
returns
(
fakeGroup
),
setDefault
:
sinon
.
stub
(),
removeAnnotations
:
sinon
.
stub
(),
removeDraft
:
sinon
.
stub
(),
};
fakeApplyTheme
=
sinon
.
stub
();
fakeApplyTheme
=
sinon
.
stub
();
$imports
.
$mock
(
mockImportedComponents
());
$imports
.
$mock
(
mockImportedComponents
());
$imports
.
$mock
({
$imports
.
$mock
({
'../store/use-store'
:
callback
=>
callback
(
fakeStore
),
'../util/annotation-metadata'
:
fakeMetadata
,
'../util/theme'
:
{
'../util/theme'
:
{
applyTheme
:
fakeApplyTheme
,
applyTheme
:
fakeApplyTheme
,
},
},
...
@@ -74,7 +91,7 @@ describe('AnnotationPublishControl', () => {
...
@@ -74,7 +91,7 @@ describe('AnnotationPublishControl', () => {
const
btnClass
=
'.annotation-publish-control__btn-primary'
;
const
btnClass
=
'.annotation-publish-control__btn-primary'
;
context
(
'shared annotation'
,
()
=>
{
context
(
'shared annotation'
,
()
=>
{
it
(
'should label the button with the group name'
,
()
=>
{
it
(
'should label the button with the group name'
,
()
=>
{
const
wrapper
=
createAnnotationPublishControl
(
{
isShared
:
true
}
);
const
wrapper
=
createAnnotationPublishControl
();
const
btn
=
wrapper
.
find
(
btnClass
);
const
btn
=
wrapper
.
find
(
btnClass
);
assert
.
equal
(
assert
.
equal
(
...
@@ -87,7 +104,10 @@ describe('AnnotationPublishControl', () => {
...
@@ -87,7 +104,10 @@ describe('AnnotationPublishControl', () => {
context
(
'private annotation'
,
()
=>
{
context
(
'private annotation'
,
()
=>
{
it
(
'should label the button with "Only Me"'
,
()
=>
{
it
(
'should label the button with "Only Me"'
,
()
=>
{
const
wrapper
=
createAnnotationPublishControl
({
isShared
:
false
});
const
draft
=
fixtures
.
defaultDraft
();
draft
.
isPrivate
=
true
;
fakeStore
.
getDraft
.
returns
(
draft
);
const
wrapper
=
createAnnotationPublishControl
();
const
btn
=
wrapper
.
find
(
btnClass
);
const
btn
=
wrapper
.
find
(
btnClass
);
assert
.
equal
(
btn
.
prop
(
'title'
),
'Publish this annotation to Only Me'
);
assert
.
equal
(
btn
.
prop
(
'title'
),
'Publish this annotation to Only Me'
);
...
@@ -122,15 +142,35 @@ describe('AnnotationPublishControl', () => {
...
@@ -122,15 +142,35 @@ describe('AnnotationPublishControl', () => {
describe
(
'menu'
,
()
=>
{
describe
(
'menu'
,
()
=>
{
describe
(
'share (to group) menu item'
,
()
=>
{
describe
(
'share (to group) menu item'
,
()
=>
{
it
(
'should invoke privacy callback with shared privacy'
,
()
=>
{
it
(
'should invoke privacy callback with shared privacy'
,
()
=>
{
const
fakeOnSetPrivacy
=
sinon
.
stub
();
const
wrapper
=
createAnnotationPublishControl
();
const
wrapper
=
createAnnotationPublishControl
({
onSetPrivacy
:
fakeOnSetPrivacy
,
});
const
shareMenuItem
=
wrapper
.
find
(
'MenuItem'
).
first
();
const
shareMenuItem
=
wrapper
.
find
(
'MenuItem'
).
first
();
shareMenuItem
.
prop
(
'onClick'
)();
shareMenuItem
.
prop
(
'onClick'
)();
assert
.
calledWith
(
fakeOnSetPrivacy
,
{
level
:
'shared'
});
const
call
=
fakeStore
.
createDraft
.
getCall
(
0
);
assert
.
calledOnce
(
fakeStore
.
createDraft
);
assert
.
isFalse
(
call
.
args
[
1
].
isPrivate
);
});
it
(
'should update default privacy level to shared'
,
()
=>
{
const
wrapper
=
createAnnotationPublishControl
();
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
first
();
privateMenuItem
.
prop
(
'onClick'
)();
assert
.
calledOnce
(
fakeStore
.
setDefault
);
assert
.
calledWith
(
fakeStore
.
setDefault
,
'annotationPrivacy'
,
'shared'
);
});
it
(
'should not update default privacy level if annotation is reply'
,
()
=>
{
fakeMetadata
.
isReply
.
returns
(
true
);
const
wrapper
=
createAnnotationPublishControl
();
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
first
();
privateMenuItem
.
prop
(
'onClick'
)();
assert
.
equal
(
fakeStore
.
setDefault
.
callCount
,
0
);
});
});
it
(
'should have a label that is the name of the group'
,
()
=>
{
it
(
'should have a label that is the name of the group'
,
()
=>
{
...
@@ -164,16 +204,37 @@ describe('AnnotationPublishControl', () => {
...
@@ -164,16 +204,37 @@ describe('AnnotationPublishControl', () => {
describe
(
'private (only me) menu item'
,
()
=>
{
describe
(
'private (only me) menu item'
,
()
=>
{
it
(
'should invoke callback with private privacy'
,
()
=>
{
it
(
'should invoke callback with private privacy'
,
()
=>
{
const
fakeOnSetPrivacy
=
sinon
.
stub
();
const
wrapper
=
createAnnotationPublishControl
();
const
wrapper
=
createAnnotationPublishControl
({
onSetPrivacy
:
fakeOnSetPrivacy
,
});
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
privateMenuItem
.
prop
(
'onClick'
)();
privateMenuItem
.
prop
(
'onClick'
)();
assert
.
calledWith
(
fakeOnSetPrivacy
,
{
level
:
'private'
});
const
call
=
fakeStore
.
createDraft
.
getCall
(
0
);
assert
.
calledOnce
(
fakeStore
.
createDraft
);
assert
.
isTrue
(
call
.
args
[
1
].
isPrivate
);
});
it
(
'should update default privacy level to private'
,
()
=>
{
const
wrapper
=
createAnnotationPublishControl
();
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
privateMenuItem
.
prop
(
'onClick'
)();
assert
.
calledOnce
(
fakeStore
.
setDefault
);
assert
.
calledWith
(
fakeStore
.
setDefault
,
'annotationPrivacy'
,
'private'
);
});
});
it
(
'should not update default privacy level if annotation is reply'
,
()
=>
{
fakeMetadata
.
isReply
.
returns
(
true
);
const
wrapper
=
createAnnotationPublishControl
();
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
privateMenuItem
.
prop
(
'onClick'
)();
assert
.
equal
(
fakeStore
.
setDefault
.
callCount
,
0
);
});
it
(
'should use a private/lock icon'
,
()
=>
{
it
(
'should use a private/lock icon'
,
()
=>
{
const
wrapper
=
createAnnotationPublishControl
();
const
wrapper
=
createAnnotationPublishControl
();
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
const
privateMenuItem
=
wrapper
.
find
(
'MenuItem'
).
at
(
1
);
...
@@ -190,16 +251,25 @@ describe('AnnotationPublishControl', () => {
...
@@ -190,16 +251,25 @@ describe('AnnotationPublishControl', () => {
});
});
describe
(
'cancel button'
,
()
=>
{
describe
(
'cancel button'
,
()
=>
{
it
(
'should have a cancel callback'
,
()
=>
{
it
(
'should remove the current draft on cancel button click'
,
()
=>
{
const
fakeOnCancel
=
sinon
.
stub
();
const
wrapper
=
createAnnotationPublishControl
({});
const
wrapper
=
createAnnotationPublishControl
({
const
cancelBtn
=
wrapper
.
find
(
'Button'
);
onCancel
:
fakeOnCancel
,
});
cancelBtn
.
props
().
onClick
();
assert
.
calledOnce
(
fakeStore
.
removeDraft
);
assert
.
calledWith
(
fakeStore
.
removeDraft
,
wrapper
.
props
().
annotation
);
assert
.
equal
(
fakeStore
.
removeAnnotations
.
callCount
,
0
);
});
it
(
'should remove the annotation from the store if it is new/unsaved'
,
()
=>
{
fakeMetadata
.
isNew
.
returns
(
true
);
const
wrapper
=
createAnnotationPublishControl
({});
const
cancelBtn
=
wrapper
.
find
(
'Button'
);
const
cancelBtn
=
wrapper
.
find
(
'Button'
);
cancelBtn
.
props
().
onClick
();
cancelBtn
.
props
().
onClick
();
assert
.
calledOnce
(
fake
OnCancel
);
assert
.
calledOnce
(
fake
Store
.
removeAnnotations
);
});
});
});
});
});
});
src/sidebar/components/test/annotation-test.js
View file @
5eaca3c7
...
@@ -499,52 +499,6 @@ describe('annotation', function() {
...
@@ -499,52 +499,6 @@ describe('annotation', function() {
});
});
});
});
describe
(
'#setPrivacy'
,
function
()
{
it
(
'makes the annotation private when level is "private"'
,
function
()
{
const
parts
=
createDirective
();
parts
.
controller
.
setPrivacy
(
'private'
);
assert
.
calledWith
(
fakeStore
.
createDraft
,
parts
.
controller
.
annotation
,
sinon
.
match
({
isPrivate
:
true
,
})
);
});
it
(
'makes the annotation shared when level is "shared"'
,
function
()
{
const
parts
=
createDirective
();
parts
.
controller
.
setPrivacy
(
'shared'
);
assert
.
calledWith
(
fakeStore
.
createDraft
,
parts
.
controller
.
annotation
,
sinon
.
match
({
isPrivate
:
false
,
})
);
});
it
(
'sets the default visibility level if "shared"'
,
function
()
{
const
parts
=
createDirective
();
parts
.
controller
.
edit
();
parts
.
controller
.
setPrivacy
(
'shared'
);
assert
.
calledWith
(
fakePermissions
.
setDefault
,
'shared'
);
});
it
(
'sets the default visibility if "private"'
,
function
()
{
const
parts
=
createDirective
();
parts
.
controller
.
edit
();
parts
.
controller
.
setPrivacy
(
'private'
);
assert
.
calledWith
(
fakePermissions
.
setDefault
,
'private'
);
});
it
(
"doesn't save the visibility if the annotation is a reply"
,
function
()
{
const
parts
=
createDirective
(
fixtures
.
oldReply
());
parts
.
controller
.
setPrivacy
(
'private'
);
assert
.
notCalled
(
fakePermissions
.
setDefault
);
});
});
describe
(
'#hasContent'
,
function
()
{
describe
(
'#hasContent'
,
function
()
{
it
(
'returns false if the annotation has no tags or text'
,
function
()
{
it
(
'returns false if the annotation has no tags or text'
,
function
()
{
const
controller
=
createDirective
(
fixtures
.
oldHighlight
()).
controller
;
const
controller
=
createDirective
(
fixtures
.
oldHighlight
()).
controller
;
...
@@ -770,13 +724,6 @@ describe('annotation', function() {
...
@@ -770,13 +724,6 @@ describe('annotation', function() {
assert
.
equal
(
controller
.
state
().
text
,
'unsaved-text'
);
assert
.
equal
(
controller
.
state
().
text
,
'unsaved-text'
);
});
});
it
(
'removes the draft when changes are discarded'
,
function
()
{
const
parts
=
createDirective
();
parts
.
controller
.
edit
();
parts
.
controller
.
revert
();
assert
.
calledWith
(
fakeStore
.
removeDraft
,
parts
.
annotation
);
});
it
(
'removes the draft when changes are saved'
,
function
()
{
it
(
'removes the draft when changes are saved'
,
function
()
{
const
annotation
=
fixtures
.
defaultAnnotation
();
const
annotation
=
fixtures
.
defaultAnnotation
();
const
controller
=
createDirective
(
annotation
).
controller
;
const
controller
=
createDirective
(
annotation
).
controller
;
...
@@ -786,22 +733,5 @@ describe('annotation', function() {
...
@@ -786,22 +733,5 @@ describe('annotation', function() {
});
});
});
});
});
});
describe
(
'reverting edits'
,
function
()
{
it
(
'removes the current draft'
,
function
()
{
const
controller
=
createDirective
(
fixtures
.
defaultAnnotation
())
.
controller
;
controller
.
edit
();
controller
.
revert
();
assert
.
calledWith
(
fakeStore
.
removeDraft
,
controller
.
annotation
);
});
it
(
'deletes the annotation if it was new'
,
function
()
{
const
controller
=
createDirective
(
fixtures
.
newAnnotation
()).
controller
;
sandbox
.
spy
(
$rootScope
,
'$broadcast'
);
controller
.
revert
();
assert
.
calledWith
(
$rootScope
.
$broadcast
,
events
.
ANNOTATION_DELETED
);
});
});
});
});
});
});
src/sidebar/templates/annotation.html
View file @
5eaca3c7
...
@@ -41,12 +41,9 @@
...
@@ -41,12 +41,9 @@
<div
class=
"annotation-form-actions"
ng-if=
"vm.editing()"
>
<div
class=
"annotation-form-actions"
ng-if=
"vm.editing()"
>
<annotation-publish-control
<annotation-publish-control
group=
"vm.group()
"
annotation=
"vm.annotation
"
is-disabled=
"!vm.hasContent()"
is-disabled=
"!vm.hasContent()"
is-shared=
"vm.isShared()"
on-save=
"vm.save()"
></annotation-publish-control>
on-cancel=
"vm.revert()"
on-save=
"vm.save()"
on-set-privacy=
"vm.setPrivacy(level)"
></annotation-publish-control>
</div>
</div>
<annotation-license
ng-if=
"vm.shouldShowLicense()"
></annotation-license>
<annotation-license
ng-if=
"vm.shouldShowLicense()"
></annotation-license>
...
...
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