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
f96d2118
Commit
f96d2118
authored
Nov 17, 2020
by
Ezekiel Kigbo
Committed by
Martin Wortschack
Nov 17, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Display busy status in user popover
Minor refactor to reuse some of the methods for user availability
parent
e7650bc4
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
216 additions
and
10 deletions
+216
-10
app/assets/javascripts/gfm_auto_complete.js
app/assets/javascripts/gfm_auto_complete.js
+12
-3
app/assets/javascripts/notes/components/note_header.vue
app/assets/javascripts/notes/components/note_header.vue
+16
-2
app/assets/javascripts/set_status_modal/components/user_availability_status.vue
.../set_status_modal/components/user_availability_status.vue
+26
-0
app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
...javascripts/set_status_modal/set_status_modal_wrapper.vue
+13
-0
app/assets/javascripts/set_status_modal/utils.js
app/assets/javascripts/set_status_modal/utils.js
+9
-0
app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
...ripts/vue_shared/components/user_popover/user_popover.vue
+9
-0
app/helpers/profiles_helper.rb
app/helpers/profiles_helper.rb
+8
-0
app/services/concerns/users/participable_service.rb
app/services/concerns/users/participable_service.rb
+2
-1
app/views/layouts/header/_current_user_dropdown.html.haml
app/views/layouts/header/_current_user_dropdown.html.haml
+3
-1
app/views/users/show.html.haml
app/views/users/show.html.haml
+2
-0
ee/spec/frontend/vue_shared/security_reports/components/__snapshots__/event_item_spec.js.snap
..._reports/components/__snapshots__/event_item_spec.js.snap
+1
-1
ee/spec/services/groups/participants_service_spec.rb
ee/spec/services/groups/participants_service_spec.rb
+2
-1
locale/gitlab.pot
locale/gitlab.pot
+9
-0
spec/frontend/gfm_auto_complete_spec.js
spec/frontend/gfm_auto_complete_spec.js
+17
-0
spec/frontend/notes/components/note_header_spec.js
spec/frontend/notes/components/note_header_spec.js
+12
-0
spec/frontend/set_status_modal/user_availability_status_spec.js
...rontend/set_status_modal/user_availability_status_spec.js
+31
-0
spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
...d/vue_shared/components/user_popover/user_popover_spec.js
+29
-1
spec/helpers/profiles_helper_spec.rb
spec/helpers/profiles_helper_spec.rb
+15
-0
No files found.
app/assets/javascripts/gfm_auto_complete.js
View file @
f96d2118
import
$
from
'
jquery
'
;
import
$
from
'
jquery
'
;
import
'
~/lib/utils/jquery_at_who
'
;
import
'
~/lib/utils/jquery_at_who
'
;
import
{
escape
,
template
}
from
'
lodash
'
;
import
{
escape
,
template
}
from
'
lodash
'
;
import
{
s__
}
from
'
~/locale
'
;
import
SidebarMediator
from
'
~/sidebar/sidebar_mediator
'
;
import
SidebarMediator
from
'
~/sidebar/sidebar_mediator
'
;
import
{
isUserBusy
}
from
'
~/set_status_modal/utils
'
;
import
glRegexp
from
'
./lib/utils/regexp
'
;
import
glRegexp
from
'
./lib/utils/regexp
'
;
import
AjaxCache
from
'
./lib/utils/ajax_cache
'
;
import
AjaxCache
from
'
./lib/utils/ajax_cache
'
;
import
{
spriteIcon
}
from
'
./lib/utils/common_utils
'
;
import
{
spriteIcon
}
from
'
./lib/utils/common_utils
'
;
...
@@ -39,6 +41,7 @@ export function membersBeforeSave(members) {
...
@@ -39,6 +41,7 @@ export function membersBeforeSave(members) {
title
:
sanitize
(
title
),
title
:
sanitize
(
title
),
search
:
sanitize
(
`
${
member
.
username
}
${
member
.
name
}
`
),
search
:
sanitize
(
`
${
member
.
username
}
${
member
.
name
}
`
),
icon
:
avatarIcon
,
icon
:
avatarIcon
,
availability
:
member
.
availability
,
};
};
});
});
}
}
...
@@ -253,13 +256,17 @@ class GfmAutoComplete {
...
@@ -253,13 +256,17 @@ class GfmAutoComplete {
alias
:
'
users
'
,
alias
:
'
users
'
,
displayTpl
(
value
)
{
displayTpl
(
value
)
{
let
tmpl
=
GfmAutoComplete
.
Loading
.
template
;
let
tmpl
=
GfmAutoComplete
.
Loading
.
template
;
const
{
avatarTag
,
username
,
title
,
icon
}
=
value
;
const
{
avatarTag
,
username
,
title
,
icon
,
availability
}
=
value
;
if
(
username
!=
null
)
{
if
(
username
!=
null
)
{
tmpl
=
GfmAutoComplete
.
Members
.
templateFunction
({
tmpl
=
GfmAutoComplete
.
Members
.
templateFunction
({
avatarTag
,
avatarTag
,
username
,
username
,
title
,
title
,
icon
,
icon
,
availabilityStatus
:
availability
&&
isUserBusy
(
availability
)
?
`<span class="gl-text-gray-500">
${
s__
(
'
UserAvailability|(Busy)
'
)}
</span>`
:
''
,
});
});
}
}
return
tmpl
;
return
tmpl
;
...
@@ -775,8 +782,10 @@ GfmAutoComplete.Emoji = {
...
@@ -775,8 +782,10 @@ GfmAutoComplete.Emoji = {
};
};
// Team Members
// Team Members
GfmAutoComplete
.
Members
=
{
GfmAutoComplete
.
Members
=
{
templateFunction
({
avatarTag
,
username
,
title
,
icon
})
{
templateFunction
({
avatarTag
,
username
,
title
,
icon
,
availabilityStatus
})
{
return
`<li>
${
avatarTag
}
${
username
}
<small>
${
escape
(
title
)}
</small>
${
icon
}
</li>`
;
return
`<li>
${
avatarTag
}
${
username
}
<small>
${
escape
(
title
,
)}${
availabilityStatus
}
</small>
${
icon
}
</li>`
;
},
},
};
};
GfmAutoComplete
.
Labels
=
{
GfmAutoComplete
.
Labels
=
{
...
...
app/assets/javascripts/notes/components/note_header.vue
View file @
f96d2118
<
script
>
<
script
>
/* eslint-disable vue/no-v-html */
/* eslint-disable vue/no-v-html */
import
{
mapActions
}
from
'
vuex
'
;
import
{
mapActions
}
from
'
vuex
'
;
import
{
GlIcon
,
GlLoadingIcon
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
,
GlLoadingIcon
,
GlTooltipDirective
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
isUserBusy
}
from
'
~/set_status_modal/utils
'
;
import
timeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
timeAgoTooltip
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
export
default
{
export
default
{
...
@@ -11,6 +12,7 @@ export default {
...
@@ -11,6 +12,7 @@ export default {
import
(
'
ee_component/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue
'
),
import
(
'
ee_component/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue
'
),
GlIcon
,
GlIcon
,
GlLoadingIcon
,
GlLoadingIcon
,
GlSprintf
,
},
},
directives
:
{
directives
:
{
GlTooltip
:
GlTooltipDirective
,
GlTooltip
:
GlTooltipDirective
,
...
@@ -85,9 +87,16 @@ export default {
...
@@ -85,9 +87,16 @@ export default {
authorStatus
()
{
authorStatus
()
{
return
this
.
author
.
status_tooltip_html
;
return
this
.
author
.
status_tooltip_html
;
},
},
authorIsBusy
()
{
const
{
status
}
=
this
.
author
;
return
status
?.
availability
&&
isUserBusy
(
status
.
availability
);
},
emojiElement
()
{
emojiElement
()
{
return
this
.
$refs
?.
authorStatus
?.
querySelector
(
'
gl-emoji
'
);
return
this
.
$refs
?.
authorStatus
?.
querySelector
(
'
gl-emoji
'
);
},
},
authorName
()
{
return
this
.
author
.
name
;
},
},
},
mounted
()
{
mounted
()
{
this
.
emojiTitle
=
this
.
emojiElement
?
this
.
emojiElement
.
getAttribute
(
'
title
'
)
:
''
;
this
.
emojiTitle
=
this
.
emojiElement
?
this
.
emojiElement
.
getAttribute
(
'
title
'
)
:
''
;
...
@@ -146,7 +155,12 @@ export default {
...
@@ -146,7 +155,12 @@ export default {
:data-username=
"author.username"
:data-username=
"author.username"
>
>
<slot
name=
"note-header-info"
></slot>
<slot
name=
"note-header-info"
></slot>
<span
class=
"note-header-author-name bold"
>
{{
author
.
name
}}
</span>
<span
class=
"note-header-author-name gl-font-weight-bold"
>
<gl-sprintf
v-if=
"authorIsBusy"
:message=
"s__('UserAvailability|%
{author} (Busy)')">
<template
#author
>
{{
authorName
}}
</
template
>
</gl-sprintf>
<
template
v-else
>
{{
authorName
}}
</
template
>
</span>
</a>
</a>
<span
<span
v-if=
"authorStatus"
v-if=
"authorStatus"
...
...
app/assets/javascripts/set_status_modal/components/user_availability_status.vue
0 → 100644
View file @
f96d2118
<
script
>
import
{
AVAILABILITY_STATUS
,
isUserBusy
,
isValidAvailibility
}
from
'
../utils
'
;
export
default
{
name
:
'
UserAvailabilityStatus
'
,
props
:
{
availability
:
{
type
:
String
,
required
:
true
,
validator
:
isValidAvailibility
,
},
},
computed
:
{
isBusy
()
{
const
{
availability
=
AVAILABILITY_STATUS
.
NOT_SET
}
=
this
;
return
isUserBusy
(
availability
);
},
},
};
</
script
>
<
template
>
<span
v-if=
"isBusy"
class=
"gl-font-weight-normal gl-text-gray-500"
>
{{
s__
(
'
UserAvailability|(Busy)
'
)
}}
</span>
</
template
>
app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue
View file @
f96d2118
...
@@ -7,6 +7,7 @@ import { deprecatedCreateFlash as createFlash } from '~/flash';
...
@@ -7,6 +7,7 @@ import { deprecatedCreateFlash as createFlash } from '~/flash';
import
{
__
,
s__
}
from
'
~/locale
'
;
import
{
__
,
s__
}
from
'
~/locale
'
;
import
Api
from
'
~/api
'
;
import
Api
from
'
~/api
'
;
import
EmojiMenuInModal
from
'
./emoji_menu_in_modal
'
;
import
EmojiMenuInModal
from
'
./emoji_menu_in_modal
'
;
import
{
isUserBusy
,
isValidAvailibility
}
from
'
./utils
'
;
import
*
as
Emoji
from
'
~/emoji
'
;
import
*
as
Emoji
from
'
~/emoji
'
;
const
emojiMenuClass
=
'
js-modal-status-emoji-menu
'
;
const
emojiMenuClass
=
'
js-modal-status-emoji-menu
'
;
...
@@ -28,6 +29,17 @@ export default {
...
@@ -28,6 +29,17 @@ export default {
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
currentAvailability
:
{
type
:
String
,
required
:
false
,
validator
:
isValidAvailibility
,
default
:
''
,
},
canSetUserAvailability
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
},
data
()
{
data
()
{
return
{
return
{
...
@@ -39,6 +51,7 @@ export default {
...
@@ -39,6 +51,7 @@ export default {
message
:
this
.
currentMessage
,
message
:
this
.
currentMessage
,
modalId
:
'
set-user-status-modal
'
,
modalId
:
'
set-user-status-modal
'
,
noEmoji
:
true
,
noEmoji
:
true
,
availability
:
isUserBusy
(
this
.
currentAvailability
),
};
};
},
},
computed
:
{
computed
:
{
...
...
app/assets/javascripts/set_status_modal/utils.js
0 → 100644
View file @
f96d2118
export
const
AVAILABILITY_STATUS
=
{
BUSY
:
'
busy
'
,
NOT_SET
:
'
not_set
'
,
};
export
const
isUserBusy
=
status
=>
status
===
AVAILABILITY_STATUS
.
BUSY
;
export
const
isValidAvailibility
=
availability
=>
availability
.
length
?
Object
.
values
(
AVAILABILITY_STATUS
).
includes
(
availability
)
:
true
;
app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
View file @
f96d2118
...
@@ -6,6 +6,7 @@ import {
...
@@ -6,6 +6,7 @@ import {
GlDeprecatedSkeletonLoading
as
GlSkeletonLoading
,
GlDeprecatedSkeletonLoading
as
GlSkeletonLoading
,
GlIcon
,
GlIcon
,
}
from
'
@gitlab/ui
'
;
}
from
'
@gitlab/ui
'
;
import
UserAvailabilityStatus
from
'
~/set_status_modal/components/user_availability_status.vue
'
;
import
UserAvatarImage
from
'
../user_avatar/user_avatar_image.vue
'
;
import
UserAvatarImage
from
'
../user_avatar/user_avatar_image.vue
'
;
import
{
glEmojiTag
}
from
'
../../../emoji
'
;
import
{
glEmojiTag
}
from
'
../../../emoji
'
;
...
@@ -25,6 +26,7 @@ export default {
...
@@ -25,6 +26,7 @@ export default {
GlPopover
,
GlPopover
,
GlSkeletonLoading
,
GlSkeletonLoading
,
UserAvatarImage
,
UserAvatarImage
,
UserAvailabilityStatus
,
},
},
props
:
{
props
:
{
target
:
{
target
:
{
...
@@ -63,6 +65,9 @@ export default {
...
@@ -63,6 +65,9 @@ export default {
websiteUrl
.
length
websiteUrl
.
length
);
);
},
},
availabilityStatus
()
{
return
this
.
user
?.
status
?.
availability
||
null
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -89,6 +94,10 @@ export default {
...
@@ -89,6 +94,10 @@ export default {
<div
class=
"gl-mb-3"
>
<div
class=
"gl-mb-3"
>
<h5
class=
"gl-m-0"
>
<h5
class=
"gl-m-0"
>
{{
user
.
name
}}
{{
user
.
name
}}
<user-availability-status
v-if=
"availabilityStatus"
:availability=
"availabilityStatus"
/>
</h5>
</h5>
<span
class=
"gl-text-gray-500"
>
@
{{
user
.
username
}}
</span>
<span
class=
"gl-text-gray-500"
>
@
{{
user
.
username
}}
</span>
</div>
</div>
...
...
app/helpers/profiles_helper.rb
View file @
f96d2118
...
@@ -29,4 +29,12 @@ module ProfilesHelper
...
@@ -29,4 +29,12 @@ module ProfilesHelper
def
user_profile?
def
user_profile?
params
[
:controller
]
==
'users'
params
[
:controller
]
==
'users'
end
end
def
availability_values
Types
::
AvailabilityEnum
.
enum
end
def
user_status_set_to_busy?
(
status
)
status
&
.
availability
==
availability_values
[
:busy
]
end
end
end
app/services/concerns/users/participable_service.rb
View file @
f96d2118
...
@@ -45,7 +45,8 @@ module Users
...
@@ -45,7 +45,8 @@ module Users
type:
user
.
class
.
name
,
type:
user
.
class
.
name
,
username:
user
.
username
,
username:
user
.
username
,
name:
user
.
name
,
name:
user
.
name
,
avatar_url:
user
.
avatar_url
avatar_url:
user
.
avatar_url
,
availability:
user
&
.
status
&
.
availability
}
}
end
end
...
...
app/views/layouts/header/_current_user_dropdown.html.haml
View file @
f96d2118
...
@@ -2,8 +2,10 @@
...
@@ -2,8 +2,10 @@
%ul
%ul
%li
.current-user
%li
.current-user
.user-name.bold
.user-name.
gl-font-weight-
bold
=
current_user
.
name
=
current_user
.
name
-
if
current_user
&
.
status
&&
user_status_set_to_busy?
(
current_user
.
status
)
%span
.gl-font-weight-normal.gl-text-gray-500
=
s_
(
"UserProfile|(Busy)"
)
=
current_user
.
to_reference
=
current_user
.
to_reference
-
if
current_user
.
status
-
if
current_user
.
status
.user-status.d-flex.align-items-center.gl-mt-2.has-tooltip
{
title:
current_user
.
status
.
message_html
,
data:
{
html:
'true'
,
placement:
'bottom'
}
}
.user-status.d-flex.align-items-center.gl-mt-2.has-tooltip
{
title:
current_user
.
status
.
message_html
,
data:
{
html:
'true'
,
placement:
'bottom'
}
}
...
...
app/views/users/show.html.haml
View file @
f96d2118
...
@@ -47,6 +47,8 @@
...
@@ -47,6 +47,8 @@
.user-info
.user-info
.cover-title
{
itemprop:
'name'
}
.cover-title
{
itemprop:
'name'
}
=
@user
.
name
=
@user
.
name
-
if
@user
&
.
status
&&
user_status_set_to_busy?
(
@user
.
status
)
%span
.gl-font-base.gl-text-gray-500.gl-vertical-align-middle
=
s_
(
"UserProfile|(Busy)"
)
-
if
@user
.
status
-
if
@user
.
status
.cover-status
.cover-status
...
...
ee/spec/frontend/vue_shared/security_reports/components/__snapshots__/event_item_spec.js.snap
View file @
f96d2118
...
@@ -32,7 +32,7 @@ exports[`Event Item with action buttons renders the action buttons 1`] = `
...
@@ -32,7 +32,7 @@ exports[`Event Item with action buttons renders the action buttons 1`] = `
>
>
<span
<span
class="note-header-author-name bold"
class="note-header-author-name
gl-font-weight-
bold"
>
>
Tanuki
Tanuki
</span>
</span>
...
...
ee/spec/services/groups/participants_service_spec.rb
View file @
f96d2118
...
@@ -16,7 +16,8 @@ RSpec.describe Groups::ParticipantsService do
...
@@ -16,7 +16,8 @@ RSpec.describe Groups::ParticipantsService do
type:
user
.
class
.
name
,
type:
user
.
class
.
name
,
username:
user
.
username
,
username:
user
.
username
,
name:
user
.
name
,
name:
user
.
name
,
avatar_url:
user
.
avatar_url
avatar_url:
user
.
avatar_url
,
availability:
user
&
.
status
&
.
availability
}
}
end
end
...
...
locale/gitlab.pot
View file @
f96d2118
...
@@ -29501,6 +29501,12 @@ msgstr ""
...
@@ -29501,6 +29501,12 @@ msgstr ""
msgid "User was successfully updated."
msgid "User was successfully updated."
msgstr ""
msgstr ""
msgid "UserAvailability|%{author} (Busy)"
msgstr ""
msgid "UserAvailability|(Busy)"
msgstr ""
msgid "UserLists|Add"
msgid "UserLists|Add"
msgstr ""
msgstr ""
...
@@ -29558,6 +29564,9 @@ msgstr ""
...
@@ -29558,6 +29564,9 @@ msgstr ""
msgid "UserList|created %{timeago}"
msgid "UserList|created %{timeago}"
msgstr ""
msgstr ""
msgid "UserProfile|(Busy)"
msgstr ""
msgid "UserProfile|Activity"
msgid "UserProfile|Activity"
msgstr ""
msgstr ""
...
...
spec/frontend/gfm_auto_complete_spec.js
View file @
f96d2118
...
@@ -378,6 +378,7 @@ describe('GfmAutoComplete', () => {
...
@@ -378,6 +378,7 @@ describe('GfmAutoComplete', () => {
username
:
'
my-group
'
,
username
:
'
my-group
'
,
title
:
''
,
title
:
''
,
icon
:
''
,
icon
:
''
,
availabilityStatus
:
''
,
}),
}),
).
toBe
(
'
<li>IMG my-group <small></small> </li>
'
);
).
toBe
(
'
<li>IMG my-group <small></small> </li>
'
);
});
});
...
@@ -389,6 +390,7 @@ describe('GfmAutoComplete', () => {
...
@@ -389,6 +390,7 @@ describe('GfmAutoComplete', () => {
username
:
'
my-group
'
,
username
:
'
my-group
'
,
title
:
''
,
title
:
''
,
icon
:
'
<i class="icon"/>
'
,
icon
:
'
<i class="icon"/>
'
,
availabilityStatus
:
''
,
}),
}),
).
toBe
(
'
<li>IMG my-group <small></small> <i class="icon"/></li>
'
);
).
toBe
(
'
<li>IMG my-group <small></small> <i class="icon"/></li>
'
);
});
});
...
@@ -400,9 +402,24 @@ describe('GfmAutoComplete', () => {
...
@@ -400,9 +402,24 @@ describe('GfmAutoComplete', () => {
username
:
'
my-group
'
,
username
:
'
my-group
'
,
title
:
'
MyGroup+
'
,
title
:
'
MyGroup+
'
,
icon
:
'
<i class="icon"/>
'
,
icon
:
'
<i class="icon"/>
'
,
availabilityStatus
:
''
,
}),
}),
).
toBe
(
'
<li>IMG my-group <small>MyGroup+</small> <i class="icon"/></li>
'
);
).
toBe
(
'
<li>IMG my-group <small>MyGroup+</small> <i class="icon"/></li>
'
);
});
});
it
(
'
should add user availability status if availabilityStatus is set
'
,
()
=>
{
expect
(
GfmAutoComplete
.
Members
.
templateFunction
({
avatarTag
:
'
IMG
'
,
username
:
'
my-group
'
,
title
:
''
,
icon
:
'
<i class="icon"/>
'
,
availabilityStatus
:
'
<span class="gl-text-gray-500"> (Busy)</span>
'
,
}),
).
toBe
(
'
<li>IMG my-group <small><span class="gl-text-gray-500"> (Busy)</span></small> <i class="icon"/></li>
'
,
);
});
});
});
describe
(
'
labels
'
,
()
=>
{
describe
(
'
labels
'
,
()
=>
{
...
...
spec/frontend/notes/components/note_header_spec.js
View file @
f96d2118
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
Vuex
from
'
vuex
'
;
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
NoteHeader
from
'
~/notes/components/note_header.vue
'
;
import
NoteHeader
from
'
~/notes/components/note_header.vue
'
;
import
{
AVAILABILITY_STATUS
}
from
'
~/set_status_modal/utils
'
;
const
localVue
=
createLocalVue
();
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
localVue
.
use
(
Vuex
);
...
@@ -28,6 +30,9 @@ describe('NoteHeader component', () => {
...
@@ -28,6 +30,9 @@ describe('NoteHeader component', () => {
path
:
'
/root
'
,
path
:
'
/root
'
,
state
:
'
active
'
,
state
:
'
active
'
,
username
:
'
root
'
,
username
:
'
root
'
,
status
:
{
availability
:
''
,
},
};
};
const
createComponent
=
props
=>
{
const
createComponent
=
props
=>
{
...
@@ -37,6 +42,7 @@ describe('NoteHeader component', () => {
...
@@ -37,6 +42,7 @@ describe('NoteHeader component', () => {
actions
,
actions
,
}),
}),
propsData
:
{
...
props
},
propsData
:
{
...
props
},
stubs
:
{
GlSprintf
},
});
});
};
};
...
@@ -97,6 +103,12 @@ describe('NoteHeader component', () => {
...
@@ -97,6 +103,12 @@ describe('NoteHeader component', () => {
expect
(
wrapper
.
find
(
'
.js-user-link
'
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
'
.js-user-link
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
renders busy status if author availability is set
'
,
()
=>
{
createComponent
({
author
:
{
...
author
,
status
:
{
availability
:
AVAILABILITY_STATUS
.
BUSY
}
}
});
expect
(
wrapper
.
find
(
'
.js-user-link
'
).
text
()).
toContain
(
'
(Busy)
'
);
});
it
(
'
renders deleted user text if author is not passed as a prop
'
,
()
=>
{
it
(
'
renders deleted user text if author is not passed as a prop
'
,
()
=>
{
createComponent
();
createComponent
();
...
...
spec/frontend/set_status_modal/user_availability_status_spec.js
0 → 100644
View file @
f96d2118
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
UserAvailabilityStatus
from
'
~/set_status_modal/components/user_availability_status.vue
'
;
import
{
AVAILABILITY_STATUS
}
from
'
~/set_status_modal/utils
'
;
describe
(
'
UserAvailabilityStatus
'
,
()
=>
{
let
wrapper
;
const
createComponent
=
(
props
=
{})
=>
{
return
shallowMount
(
UserAvailabilityStatus
,
{
propsData
:
{
...
props
,
},
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
describe
(
'
with availability status
'
,
()
=>
{
it
(
`set to
${
AVAILABILITY_STATUS
.
BUSY
}
`
,
()
=>
{
wrapper
=
createComponent
({
availability
:
AVAILABILITY_STATUS
.
BUSY
});
expect
(
wrapper
.
text
()).
toContain
(
'
(Busy)
'
);
});
it
(
`set to
${
AVAILABILITY_STATUS
.
NOT_SET
}
`
,
()
=>
{
wrapper
=
createComponent
({
availability
:
AVAILABILITY_STATUS
.
NOT_SET
});
expect
(
wrapper
.
html
()).
toBe
(
''
);
});
});
});
spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
View file @
f96d2118
import
{
GlDeprecatedSkeletonLoading
as
GlSkeletonLoading
,
GlSprintf
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
GlDeprecatedSkeletonLoading
as
GlSkeletonLoading
,
GlSprintf
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
UserPopover
from
'
~/vue_shared/components/user_popover/user_popover.vue
'
;
import
UserPopover
from
'
~/vue_shared/components/user_popover/user_popover.vue
'
;
import
UserAvailabilityStatus
from
'
~/set_status_modal/components/user_availability_status.vue
'
;
import
{
AVAILABILITY_STATUS
}
from
'
~/set_status_modal/utils
'
;
const
DEFAULT_PROPS
=
{
const
DEFAULT_PROPS
=
{
user
:
{
user
:
{
...
@@ -34,6 +36,7 @@ describe('User Popover Component', () => {
...
@@ -34,6 +36,7 @@ describe('User Popover Component', () => {
const
findByTestId
=
testid
=>
wrapper
.
find
(
`[data-testid="
${
testid
}
"]`
);
const
findByTestId
=
testid
=>
wrapper
.
find
(
`[data-testid="
${
testid
}
"]`
);
const
findUserStatus
=
()
=>
wrapper
.
find
(
'
.js-user-status
'
);
const
findUserStatus
=
()
=>
wrapper
.
find
(
'
.js-user-status
'
);
const
findTarget
=
()
=>
document
.
querySelector
(
'
.js-user-link
'
);
const
findTarget
=
()
=>
document
.
querySelector
(
'
.js-user-link
'
);
const
findAvailabilityStatus
=
()
=>
wrapper
.
find
(
UserAvailabilityStatus
);
const
createWrapper
=
(
props
=
{},
options
=
{})
=>
{
const
createWrapper
=
(
props
=
{},
options
=
{})
=>
{
wrapper
=
shallowMount
(
UserPopover
,
{
wrapper
=
shallowMount
(
UserPopover
,
{
...
@@ -43,7 +46,8 @@ describe('User Popover Component', () => {
...
@@ -43,7 +46,8 @@ describe('User Popover Component', () => {
...
props
,
...
props
,
},
},
stubs
:
{
stubs
:
{
'
gl-sprintf
'
:
GlSprintf
,
GlSprintf
,
UserAvailabilityStatus
,
},
},
...
options
,
...
options
,
});
});
...
@@ -199,6 +203,30 @@ describe('User Popover Component', () => {
...
@@ -199,6 +203,30 @@ describe('User Popover Component', () => {
expect
(
findUserStatus
().
exists
()).
toBe
(
false
);
expect
(
findUserStatus
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should show the busy status if user set to busy
'
,
()
=>
{
const
user
=
{
...
DEFAULT_PROPS
.
user
,
status
:
{
availability
:
AVAILABILITY_STATUS
.
BUSY
},
};
createWrapper
({
user
});
expect
(
findAvailabilityStatus
().
exists
()).
toBe
(
true
);
expect
(
wrapper
.
text
()).
toContain
(
user
.
name
);
expect
(
wrapper
.
text
()).
toContain
(
'
(Busy)
'
);
});
it
(
'
should hide the busy status for any other status
'
,
()
=>
{
const
user
=
{
...
DEFAULT_PROPS
.
user
,
status
:
{
availability
:
AVAILABILITY_STATUS
.
NOT_SET
},
};
createWrapper
({
user
});
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
(Busy)
'
);
});
});
});
describe
(
'
security bot
'
,
()
=>
{
describe
(
'
security bot
'
,
()
=>
{
...
...
spec/helpers/profiles_helper_spec.rb
View file @
f96d2118
...
@@ -80,6 +80,21 @@ RSpec.describe ProfilesHelper do
...
@@ -80,6 +80,21 @@ RSpec.describe ProfilesHelper do
end
end
end
end
describe
"#user_status_set_to_busy?"
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:availability
,
:result
)
do
"busy"
|
true
"not_set"
|
false
""
|
false
nil
|
false
end
with_them
do
it
{
expect
(
helper
.
user_status_set_to_busy?
(
OpenStruct
.
new
(
availability:
availability
))).
to
eq
(
result
)
}
end
end
def
stub_cas_omniauth_provider
def
stub_cas_omniauth_provider
provider
=
OpenStruct
.
new
(
provider
=
OpenStruct
.
new
(
'name'
=>
'cas3'
,
'name'
=>
'cas3'
,
...
...
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