Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
074964ed
Commit
074964ed
authored
Apr 16, 2020
by
Paul Slaughter
Committed by
Denys Mishunov
Apr 16, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decouple presentation of note_awards_list
- Adds awards_list component to vue_shared
parent
58b0ba62
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
692 additions
and
163 deletions
+692
-163
app/assets/javascripts/notes/components/note_awards_list.vue
app/assets/javascripts/notes/components/note_awards_list.vue
+14
-163
app/assets/javascripts/vue_shared/components/awards_list.vue
app/assets/javascripts/vue_shared/components/awards_list.vue
+178
-0
spec/frontend/vue_shared/components/__snapshots__/awards_list_spec.js.snap
..._shared/components/__snapshots__/awards_list_spec.js.snap
+287
-0
spec/frontend/vue_shared/components/awards_list_spec.js
spec/frontend/vue_shared/components/awards_list_spec.js
+213
-0
No files found.
app/assets/javascripts/notes/components/note_awards_list.vue
View file @
074964ed
<
script
>
<
script
>
import
{
mapActions
,
mapGetters
}
from
'
vuex
'
;
import
{
mapActions
,
mapGetters
}
from
'
vuex
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
AwardsList
from
'
~/vue_shared/components/awards_list.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
import
Flash
from
'
../../flash
'
;
import
Flash
from
'
../../flash
'
;
import
{
glEmojiTag
}
from
'
../../emoji
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
export
default
{
export
default
{
components
:
{
components
:
{
Icon
,
AwardsList
,
},
directives
:
{
tooltip
,
},
},
props
:
{
props
:
{
awards
:
{
awards
:
{
...
@@ -37,130 +32,20 @@ export default {
...
@@ -37,130 +32,20 @@ export default {
},
},
computed
:
{
computed
:
{
...
mapGetters
([
'
getUserData
'
]),
...
mapGetters
([
'
getUserData
'
]),
// `this.awards` is an array with emojis but they are not grouped by emoji name. See below.
// [ { name: foo, user: user1 }, { name: bar, user: user1 }, { name: foo, user: user2 } ]
// This method will group emojis by their name as an Object. See below.
// {
// foo: [ { name: foo, user: user1 }, { name: foo, user: user2 } ],
// bar: [ { name: bar, user: user1 } ]
// }
// We need to do this otherwise we will render the same emoji over and over again.
groupedAwards
()
{
const
awards
=
this
.
awards
.
reduce
((
acc
,
award
)
=>
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
acc
,
award
.
name
))
{
acc
[
award
.
name
].
push
(
award
);
}
else
{
Object
.
assign
(
acc
,
{
[
award
.
name
]:
[
award
]
});
}
return
acc
;
},
{});
const
orderedAwards
=
{};
const
{
thumbsdown
,
thumbsup
}
=
awards
;
// Always show thumbsup and thumbsdown first
if
(
thumbsup
)
{
orderedAwards
.
thumbsup
=
thumbsup
;
delete
awards
.
thumbsup
;
}
if
(
thumbsdown
)
{
orderedAwards
.
thumbsdown
=
thumbsdown
;
delete
awards
.
thumbsdown
;
}
return
Object
.
assign
({},
orderedAwards
,
awards
);
},
isAuthoredByMe
()
{
isAuthoredByMe
()
{
return
this
.
noteAuthorId
===
this
.
getUserData
.
id
;
return
this
.
noteAuthorId
===
this
.
getUserData
.
id
;
},
},
addButtonClass
()
{
return
this
.
isAuthoredByMe
?
'
js-user-authored
'
:
''
;
},
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
toggleAwardRequest
'
]),
...
mapActions
([
'
toggleAwardRequest
'
]),
getAwardHTML
(
name
)
{
return
glEmojiTag
(
name
);
},
getAwardClassBindings
(
awardList
)
{
return
{
active
:
this
.
hasReactionByCurrentUser
(
awardList
),
disabled
:
!
this
.
canInteractWithEmoji
(),
};
},
canInteractWithEmoji
()
{
return
this
.
getUserData
.
id
;
},
hasReactionByCurrentUser
(
awardList
)
{
return
awardList
.
filter
(
award
=>
award
.
user
.
id
===
this
.
getUserData
.
id
).
length
;
},
awardTitle
(
awardsList
)
{
const
hasReactionByCurrentUser
=
this
.
hasReactionByCurrentUser
(
awardsList
);
const
TOOLTIP_NAME_COUNT
=
hasReactionByCurrentUser
?
9
:
10
;
let
awardList
=
awardsList
;
// Filter myself from list if I am awarded.
if
(
hasReactionByCurrentUser
)
{
awardList
=
awardList
.
filter
(
award
=>
award
.
user
.
id
!==
this
.
getUserData
.
id
);
}
// Get only 9-10 usernames to show in tooltip text.
const
namesToShow
=
awardList
.
slice
(
0
,
TOOLTIP_NAME_COUNT
).
map
(
award
=>
award
.
user
.
name
);
// Get the remaining list to use in `and x more` text.
const
remainingAwardList
=
awardList
.
slice
(
TOOLTIP_NAME_COUNT
,
awardList
.
length
);
// Add myself to the beginning of the list so title will start with You.
if
(
hasReactionByCurrentUser
)
{
namesToShow
.
unshift
(
__
(
'
You
'
));
}
let
title
=
''
;
// We have 10+ awarded user, join them with comma and add `and x more`.
if
(
remainingAwardList
.
length
)
{
title
=
sprintf
(
__
(
`%{listToShow}, and %{awardsListLength} more.`
),
{
listToShow
:
namesToShow
.
join
(
'
,
'
),
awardsListLength
:
remainingAwardList
.
length
,
},
false
,
);
}
else
if
(
namesToShow
.
length
>
1
)
{
// Join all names with comma but not the last one, it will be added with and text.
title
=
namesToShow
.
slice
(
0
,
namesToShow
.
length
-
1
).
join
(
'
,
'
);
// If we have more than 2 users we need an extra comma before and text.
title
+=
namesToShow
.
length
>
2
?
'
,
'
:
''
;
title
+=
sprintf
(
__
(
` and %{sliced}`
),
{
sliced
:
namesToShow
.
slice
(
-
1
)
},
false
);
// Append and text
}
else
{
// We have only 2 users so join them with and.
title
=
namesToShow
.
join
(
__
(
'
and
'
));
}
return
title
;
},
handleAward
(
awardName
)
{
handleAward
(
awardName
)
{
if
(
!
this
.
canAwardEmoji
)
{
return
;
}
let
parsedName
;
// 100 and 1234 emoji are a number. Callback for v-for click sends it as a string
switch
(
awardName
)
{
case
'
100
'
:
parsedName
=
100
;
break
;
case
'
1234
'
:
parsedName
=
1234
;
break
;
default
:
parsedName
=
awardName
;
break
;
}
const
data
=
{
const
data
=
{
endpoint
:
this
.
toggleAwardPath
,
endpoint
:
this
.
toggleAwardPath
,
noteId
:
this
.
noteId
,
noteId
:
this
.
noteId
,
awardName
:
parsedName
,
awardName
,
};
};
this
.
toggleAwardRequest
(
data
).
catch
(()
=>
Flash
(
__
(
'
Something went wrong on our end.
'
)));
this
.
toggleAwardRequest
(
data
).
catch
(()
=>
Flash
(
__
(
'
Something went wrong on our end.
'
)));
...
@@ -171,46 +56,12 @@ export default {
...
@@ -171,46 +56,12 @@ export default {
<
template
>
<
template
>
<div
class=
"note-awards"
>
<div
class=
"note-awards"
>
<div
class=
"awards js-awards-block"
>
<awards-list
<button
:awards=
"awards"
v-for=
"(awardList, awardName, index) in groupedAwards"
:can-award-emoji=
"canAwardEmoji"
:key=
"index"
:current-user-id=
"getUserData.id"
v-tooltip
:add-button-class=
"addButtonClass"
:class=
"getAwardClassBindings(awardList)"
@
award=
"handleAward($event)"
:title=
"awardTitle(awardList)"
/>
data-boundary=
"viewport"
class=
"btn award-control"
type=
"button"
@
click=
"handleAward(awardName)"
>
<span
v-html=
"getAwardHTML(awardName)"
></span>
<span
class=
"award-control-text js-counter"
>
{{
awardList
.
length
}}
</span>
</button>
<div
v-if=
"canAwardEmoji"
class=
"award-menu-holder"
>
<button
v-tooltip
:class=
"
{ 'js-user-authored': isAuthoredByMe }"
class="award-control btn js-add-award"
title="Add reaction"
:aria-label="__('Add reaction')"
data-boundary="viewport"
type="button"
>
<span
class=
"award-control-icon award-control-icon-neutral"
>
<icon
name=
"slight-smile"
/>
</span>
<span
class=
"award-control-icon award-control-icon-positive"
>
<icon
name=
"smiley"
/>
</span>
<span
class=
"award-control-icon award-control-icon-super-positive"
>
<icon
name=
"smiley"
/>
</span>
<i
aria-hidden=
"true"
class=
"fa fa-spinner fa-spin award-control-icon award-control-icon-loading"
></i>
</button>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/vue_shared/components/awards_list.vue
0 → 100644
View file @
074964ed
<
script
>
import
{
groupBy
}
from
'
lodash
'
;
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
tooltip
from
'
~/vue_shared/directives/tooltip
'
;
import
{
glEmojiTag
}
from
'
../../emoji
'
;
import
{
__
,
sprintf
}
from
'
~/locale
'
;
// Internal constant, specific to this component, used when no `currentUserId` is given
const
NO_USER_ID
=
-
1
;
export
default
{
components
:
{
GlIcon
,
},
directives
:
{
tooltip
,
},
props
:
{
awards
:
{
type
:
Array
,
required
:
true
,
},
canAwardEmoji
:
{
type
:
Boolean
,
required
:
true
,
},
currentUserId
:
{
type
:
Number
,
required
:
false
,
default
:
NO_USER_ID
,
},
addButtonClass
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
computed
:
{
groupedAwards
()
{
const
{
thumbsup
,
thumbsdown
,
...
rest
}
=
groupBy
(
this
.
awards
,
x
=>
x
.
name
);
return
[
...(
thumbsup
?
[
this
.
createAwardList
(
'
thumbsup
'
,
thumbsup
)]
:
[]),
...(
thumbsdown
?
[
this
.
createAwardList
(
'
thumbsdown
'
,
thumbsdown
)]
:
[]),
...
Object
.
entries
(
rest
).
map
(([
name
,
list
])
=>
this
.
createAwardList
(
name
,
list
)),
];
},
isAuthoredByMe
()
{
return
this
.
noteAuthorId
===
this
.
currentUserId
;
},
},
methods
:
{
getAwardClassBindings
(
awardList
)
{
return
{
active
:
this
.
hasReactionByCurrentUser
(
awardList
),
disabled
:
this
.
currentUserId
===
NO_USER_ID
,
};
},
hasReactionByCurrentUser
(
awardList
)
{
if
(
this
.
currentUserId
===
NO_USER_ID
)
{
return
false
;
}
return
awardList
.
some
(
award
=>
award
.
user
.
id
===
this
.
currentUserId
);
},
createAwardList
(
name
,
list
)
{
return
{
name
,
list
,
title
:
this
.
getAwardListTitle
(
list
),
classes
:
this
.
getAwardClassBindings
(
list
),
html
:
glEmojiTag
(
name
),
};
},
getAwardListTitle
(
awardsList
)
{
const
hasReactionByCurrentUser
=
this
.
hasReactionByCurrentUser
(
awardsList
);
const
TOOLTIP_NAME_COUNT
=
hasReactionByCurrentUser
?
9
:
10
;
let
awardList
=
awardsList
;
// Filter myself from list if I am awarded.
if
(
hasReactionByCurrentUser
)
{
awardList
=
awardList
.
filter
(
award
=>
award
.
user
.
id
!==
this
.
currentUserId
);
}
// Get only 9-10 usernames to show in tooltip text.
const
namesToShow
=
awardList
.
slice
(
0
,
TOOLTIP_NAME_COUNT
).
map
(
award
=>
award
.
user
.
name
);
// Get the remaining list to use in `and x more` text.
const
remainingAwardList
=
awardList
.
slice
(
TOOLTIP_NAME_COUNT
,
awardList
.
length
);
// Add myself to the beginning of the list so title will start with You.
if
(
hasReactionByCurrentUser
)
{
namesToShow
.
unshift
(
__
(
'
You
'
));
}
let
title
=
''
;
// We have 10+ awarded user, join them with comma and add `and x more`.
if
(
remainingAwardList
.
length
)
{
title
=
sprintf
(
__
(
`%{listToShow}, and %{awardsListLength} more.`
),
{
listToShow
:
namesToShow
.
join
(
'
,
'
),
awardsListLength
:
remainingAwardList
.
length
,
},
false
,
);
}
else
if
(
namesToShow
.
length
>
1
)
{
// Join all names with comma but not the last one, it will be added with and text.
title
=
namesToShow
.
slice
(
0
,
namesToShow
.
length
-
1
).
join
(
'
,
'
);
// If we have more than 2 users we need an extra comma before and text.
title
+=
namesToShow
.
length
>
2
?
'
,
'
:
''
;
title
+=
sprintf
(
__
(
` and %{sliced}`
),
{
sliced
:
namesToShow
.
slice
(
-
1
)
},
false
);
// Append and text
}
else
{
// We have only 2 users so join them with and.
title
=
namesToShow
.
join
(
__
(
'
and
'
));
}
return
title
;
},
handleAward
(
awardName
)
{
if
(
!
this
.
canAwardEmoji
)
{
return
;
}
// 100 and 1234 emoji are a number. Callback for v-for click sends it as a string
const
parsedName
=
/^
[
0-9
]
+$/
.
test
(
awardName
)
?
Number
(
awardName
)
:
awardName
;
this
.
$emit
(
'
award
'
,
parsedName
);
},
},
};
</
script
>
<
template
>
<div
class=
"awards js-awards-block"
>
<button
v-for=
"awardList in groupedAwards"
:key=
"awardList.name"
v-tooltip
:class=
"awardList.classes"
:title=
"awardList.title"
data-boundary=
"viewport"
data-testid=
"award-button"
class=
"btn award-control"
type=
"button"
@
click=
"handleAward(awardList.name)"
>
<span
data-testid=
"award-html"
v-html=
"awardList.html"
></span>
<span
class=
"award-control-text js-counter"
>
{{
awardList
.
list
.
length
}}
</span>
</button>
<div
v-if=
"canAwardEmoji"
class=
"award-menu-holder"
>
<button
v-tooltip
:class=
"addButtonClass"
class=
"award-control btn js-add-award"
title=
"Add reaction"
:aria-label=
"__('Add reaction')"
data-boundary=
"viewport"
type=
"button"
>
<span
class=
"award-control-icon award-control-icon-neutral"
>
<gl-icon
aria-hidden=
"true"
name=
"slight-smile"
/>
</span>
<span
class=
"award-control-icon award-control-icon-positive"
>
<gl-icon
aria-hidden=
"true"
name=
"smiley"
/>
</span>
<span
class=
"award-control-icon award-control-icon-super-positive"
>
<gl-icon
aria-hidden=
"true"
name=
"smiley"
/>
</span>
<i
aria-hidden=
"true"
class=
"fa fa-spinner fa-spin award-control-icon award-control-icon-loading"
></i>
</button>
</div>
</div>
</
template
>
spec/frontend/vue_shared/components/__snapshots__/awards_list_spec.js.snap
0 → 100644
View file @
074964ed
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`vue_shared/components/awards_list default matches snapshot 1`] = `
<div
class="awards js-awards-block"
>
<button
class="btn award-control"
data-boundary="viewport"
data-original-title="Ada, Leonardo, and Marie"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/thumbsup-59ec2457ab33e8897261d01a495f6cf5c668d0004807dc541c3b1be5294b1e61.png"
data-name="thumbsup"
data-unicode-version="6.0"
title="thumbs up sign"
>
👍
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
3
</span>
</button>
<button
class="btn award-control active"
data-boundary="viewport"
data-original-title="You, Ada, and Marie"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/thumbsdown-5954334e2dae5357312b3d629f10a496c728029e02216f8c8b887f9b51561c61.png"
data-name="thumbsdown"
data-unicode-version="6.0"
title="thumbs down sign"
>
👎
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
3
</span>
</button>
<button
class="btn award-control"
data-boundary="viewport"
data-original-title="Ada and Jane"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/smile-14905c372d5bf7719bd727c9efae31a03291acec79801652a23710c6848c5d14.png"
data-name="smile"
data-unicode-version="6.0"
title="smiling face with open mouth and smiling eyes"
>
😄
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
2
</span>
</button>
<button
class="btn award-control active"
data-boundary="viewport"
data-original-title="You, Ada, Jane, and Leonardo"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/ok_hand-d63002dce3cc3655b67b8765b7c28d370edba0e3758b2329b60e0e61c4d8e78d.png"
data-name="ok_hand"
data-unicode-version="6.0"
title="ok hand sign"
>
👌
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
4
</span>
</button>
<button
class="btn award-control active"
data-boundary="viewport"
data-original-title="You"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/cactus-2c5c4c35f26c7046fdc002b337e0d939729b33a26980e675950f9934c91e40fd.png"
data-name="cactus"
data-unicode-version="6.0"
title="cactus"
>
🌵
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
1
</span>
</button>
<button
class="btn award-control"
data-boundary="viewport"
data-original-title="Marie"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/a-bddbb39e8a1d35d42b7c08e7d47f63988cb4d8614b79f74e70b9c67c221896cc.png"
data-name="a"
data-unicode-version="6.0"
title="negative squared latin capital letter a"
>
🅰
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
1
</span>
</button>
<button
class="btn award-control active"
data-boundary="viewport"
data-original-title="You"
data-testid="award-button"
title=""
type="button"
>
<span
data-testid="award-html"
>
<gl-emoji
data-fallback-src="/assets/emoji/b-722f9db9442e7c0fc0d0ac0f5291fbf47c6a0ac4d8abd42e97957da705fb82bf.png"
data-name="b"
data-unicode-version="6.0"
title="negative squared latin capital letter b"
>
🅱
</gl-emoji>
</span>
<span
class="award-control-text js-counter"
>
1
</span>
</button>
<div
class="award-menu-holder"
>
<button
aria-label="Add reaction"
class="award-control btn js-add-award js-test-add-button-class"
data-boundary="viewport"
data-original-title="Add reaction"
title=""
type="button"
>
<span
class="award-control-icon award-control-icon-neutral"
>
<gl-icon-stub
aria-hidden="true"
name="slight-smile"
size="16"
/>
</span>
<span
class="award-control-icon award-control-icon-positive"
>
<gl-icon-stub
aria-hidden="true"
name="smiley"
size="16"
/>
</span>
<span
class="award-control-icon award-control-icon-super-positive"
>
<gl-icon-stub
aria-hidden="true"
name="smiley"
size="16"
/>
</span>
<i
aria-hidden="true"
class="fa fa-spinner fa-spin award-control-icon award-control-icon-loading"
/>
</button>
</div>
</div>
`;
spec/frontend/vue_shared/components/awards_list_spec.js
0 → 100644
View file @
074964ed
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
AwardsList
from
'
~/vue_shared/components/awards_list.vue
'
;
const
createUser
=
(
id
,
name
)
=>
({
id
,
name
});
const
createAward
=
(
name
,
user
)
=>
({
name
,
user
});
const
USERS
=
{
root
:
createUser
(
1
,
'
Root
'
),
ada
:
createUser
(
2
,
'
Ada
'
),
marie
:
createUser
(
3
,
'
Marie
'
),
jane
:
createUser
(
4
,
'
Jane
'
),
leonardo
:
createUser
(
5
,
'
Leonardo
'
),
};
const
EMOJI_SMILE
=
'
smile
'
;
const
EMOJI_OK
=
'
ok_hand
'
;
const
EMOJI_THUMBSUP
=
'
thumbsup
'
;
const
EMOJI_THUMBSDOWN
=
'
thumbsdown
'
;
const
EMOJI_A
=
'
a
'
;
const
EMOJI_B
=
'
b
'
;
const
EMOJI_CACTUS
=
'
cactus
'
;
const
EMOJI_100
=
'
100
'
;
const
TEST_AWARDS
=
[
createAward
(
EMOJI_SMILE
,
USERS
.
ada
),
createAward
(
EMOJI_OK
,
USERS
.
ada
),
createAward
(
EMOJI_THUMBSUP
,
USERS
.
ada
),
createAward
(
EMOJI_THUMBSDOWN
,
USERS
.
ada
),
createAward
(
EMOJI_SMILE
,
USERS
.
jane
),
createAward
(
EMOJI_OK
,
USERS
.
jane
),
createAward
(
EMOJI_OK
,
USERS
.
leonardo
),
createAward
(
EMOJI_THUMBSUP
,
USERS
.
leonardo
),
createAward
(
EMOJI_THUMBSUP
,
USERS
.
marie
),
createAward
(
EMOJI_THUMBSDOWN
,
USERS
.
marie
),
createAward
(
EMOJI_THUMBSDOWN
,
USERS
.
root
),
createAward
(
EMOJI_OK
,
USERS
.
root
),
// Test that emoji list preserves order of occurrence, not alphabetical order
createAward
(
EMOJI_CACTUS
,
USERS
.
root
),
createAward
(
EMOJI_A
,
USERS
.
marie
),
createAward
(
EMOJI_B
,
USERS
.
root
),
];
const
TEST_ADD_BUTTON_CLASS
=
'
js-test-add-button-class
'
;
describe
(
'
vue_shared/components/awards_list
'
,
()
=>
{
let
wrapper
;
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
const
createComponent
=
(
props
=
{})
=>
{
if
(
wrapper
)
{
throw
new
Error
(
'
There should only be one wrapper created per test
'
);
}
wrapper
=
shallowMount
(
AwardsList
,
{
propsData
:
props
});
};
const
matchingEmojiTag
=
name
=>
expect
.
stringMatching
(
`gl-emoji data-name="
${
name
}
"`
);
const
findAwardButtons
=
()
=>
wrapper
.
findAll
(
'
[data-testid="award-button"
'
);
const
findAwardsData
=
()
=>
findAwardButtons
().
wrappers
.
map
(
x
=>
{
return
{
classes
:
x
.
classes
(),
title
:
x
.
attributes
(
'
data-original-title
'
),
html
:
x
.
find
(
'
[data-testid="award-html"]
'
).
element
.
innerHTML
,
count
:
Number
(
x
.
find
(
'
.js-counter
'
).
text
()),
};
});
const
findAddAwardButton
=
()
=>
wrapper
.
find
(
'
.js-add-award
'
);
describe
(
'
default
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
awards
:
TEST_AWARDS
,
canAwardEmoji
:
true
,
currentUserId
:
USERS
.
root
.
id
,
addButtonClass
:
TEST_ADD_BUTTON_CLASS
,
});
});
it
(
'
matches snapshot
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
it
(
'
shows awards in correct order
'
,
()
=>
{
expect
(
findAwardsData
()).
toEqual
([
{
classes
:
[
'
btn
'
,
'
award-control
'
],
count
:
3
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSUP
),
title
:
'
Ada, Leonardo, and Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
count
:
3
,
html
:
matchingEmojiTag
(
EMOJI_THUMBSDOWN
),
title
:
'
You, Ada, and Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
],
count
:
2
,
html
:
matchingEmojiTag
(
EMOJI_SMILE
),
title
:
'
Ada and Jane
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
count
:
4
,
html
:
matchingEmojiTag
(
EMOJI_OK
),
title
:
'
You, Ada, Jane, and Leonardo
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_CACTUS
),
title
:
'
You
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
],
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_A
),
title
:
'
Marie
'
,
},
{
classes
:
[
'
btn
'
,
'
award-control
'
,
'
active
'
],
count
:
1
,
html
:
matchingEmojiTag
(
EMOJI_B
),
title
:
'
You
'
,
},
]);
});
it
(
'
with award clicked, it emits award
'
,
()
=>
{
expect
(
wrapper
.
emitted
().
award
).
toBeUndefined
();
findAwardButtons
()
.
at
(
2
)
.
trigger
(
'
click
'
);
expect
(
wrapper
.
emitted
().
award
).
toEqual
([[
EMOJI_SMILE
]]);
});
it
(
'
shows add award button
'
,
()
=>
{
const
btn
=
findAddAwardButton
();
expect
(
btn
.
exists
()).
toBe
(
true
);
expect
(
btn
.
classes
(
TEST_ADD_BUTTON_CLASS
)).
toBe
(
true
);
});
});
describe
(
'
with numeric award
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
awards
:
[
createAward
(
EMOJI_100
,
USERS
.
ada
)],
canAwardEmoji
:
true
,
currentUserId
:
USERS
.
root
.
id
,
});
});
it
(
'
when clicked, it emits award as number
'
,
()
=>
{
expect
(
wrapper
.
emitted
().
award
).
toBeUndefined
();
findAwardButtons
()
.
at
(
0
)
.
trigger
(
'
click
'
);
expect
(
wrapper
.
emitted
().
award
).
toEqual
([[
Number
(
EMOJI_100
)]]);
});
});
describe
(
'
with no awards
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
awards
:
[],
canAwardEmoji
:
true
,
});
});
it
(
'
has no award buttons
'
,
()
=>
{
expect
(
findAwardButtons
().
length
).
toBe
(
0
);
});
});
describe
(
'
when cannot award emoji
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
awards
:
[
createAward
(
EMOJI_CACTUS
,
USERS
.
root
.
id
)],
canAwardEmoji
:
false
,
currentUserId
:
USERS
.
marie
.
id
,
});
});
it
(
'
does not have add button
'
,
()
=>
{
expect
(
findAddAwardButton
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
with no user
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
awards
:
TEST_AWARDS
,
canAwardEmoji
:
false
,
});
});
it
(
'
disables award buttons
'
,
()
=>
{
const
buttons
=
findAwardButtons
();
expect
(
buttons
.
length
).
toBe
(
7
);
expect
(
buttons
.
wrappers
.
every
(
x
=>
x
.
classes
(
'
disabled
'
))).
toBe
(
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