Commit cf3dc786 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '337935-add-timezone-to-snapshot-view-of-gitlab-user-profile' into 'master'

Add local time to user popover

See merge request gitlab-org/gitlab!70806
parents fdf3bd55 1b3e7dba
......@@ -41,6 +41,7 @@ const populateUserInfo = (user) => {
workInformation: userData.work_information,
websiteUrl: userData.website_url,
pronouns: userData.pronouns,
localTime: userData.local_time,
loaded: true,
});
}
......
......@@ -93,19 +93,27 @@ export default {
</div>
<div class="gl-text-gray-500">
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
<gl-icon name="profile" class="gl-text-gray-400 gl-flex-shrink-0" />
<gl-icon name="profile" class="gl-flex-shrink-0" />
<span ref="bio" class="gl-ml-2 gl-overflow-hidden">{{ user.bio }}</span>
</div>
<div v-if="user.workInformation" class="gl-display-flex gl-mb-2">
<gl-icon name="work" class="gl-text-gray-400 gl-flex-shrink-0" />
<gl-icon name="work" class="gl-flex-shrink-0" />
<span ref="workInformation" class="gl-ml-2">{{ user.workInformation }}</span>
</div>
</div>
<div v-if="user.location" class="js-location gl-text-gray-500 gl-display-flex">
<gl-icon name="location" class="gl-text-gray-400 flex-shrink-0" />
<div v-if="user.location" class="gl-display-flex gl-mb-2">
<gl-icon name="location" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.location }}</span>
</div>
<div v-if="statusHtml" class="js-user-status gl-mt-3">
<div
v-if="user.localTime && !user.bot"
class="gl-display-flex gl-mb-2"
data-testid="user-popover-local-time"
>
<gl-icon name="clock" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.localTime }}</span>
</div>
</div>
<div v-if="statusHtml" class="gl-mb-2" data-testid="user-popover-status">
<span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
</div>
<div v-if="user.bot" class="gl-text-blue-500">
......
......@@ -4,6 +4,7 @@ module API
module Entities
class User < UserBasic
include UsersHelper
include TimeZoneHelper
include ActionView::Helpers::SanitizeHelper
expose :created_at, if: ->(user, opts) { Ability.allowed?(opts[:current_user], :read_user_profile, user) }
......@@ -24,6 +25,10 @@ module API
expose :bio_html do |user|
strip_tags(user.bio)
end
expose :local_time do |user|
local_time(user.timezone)
end
end
end
end
......@@ -9,6 +9,7 @@ const DEFAULT_PROPS = {
username: 'root',
name: 'Administrator',
location: 'Vienna',
localTime: '2:30 PM',
bot: false,
bio: null,
workInformation: null,
......@@ -31,10 +32,11 @@ describe('User Popover Component', () => {
wrapper.destroy();
});
const findUserStatus = () => wrapper.find('.js-user-status');
const findUserStatus = () => wrapper.findByTestId('user-popover-status');
const findTarget = () => document.querySelector('.js-user-link');
const findUserName = () => wrapper.find(UserNameWithStatus);
const findSecurityBotDocsLink = () => wrapper.findByTestId('user-popover-bot-docs-link');
const findUserLocalTime = () => wrapper.findByTestId('user-popover-local-time');
const createWrapper = (props = {}, options = {}) => {
wrapper = mountExtended(UserPopover, {
......@@ -71,7 +73,6 @@ describe('User Popover Component', () => {
expect(wrapper.text()).toContain(DEFAULT_PROPS.user.name);
expect(wrapper.text()).toContain(DEFAULT_PROPS.user.username);
expect(wrapper.text()).toContain(DEFAULT_PROPS.user.location);
});
it('shows icon for location', () => {
......@@ -164,6 +165,25 @@ describe('User Popover Component', () => {
});
});
describe('local time', () => {
it('should show local time when it is available', () => {
createWrapper();
expect(findUserLocalTime().exists()).toBe(true);
});
it('should not show local time when it is not available', () => {
const user = {
...DEFAULT_PROPS.user,
localTime: null,
};
createWrapper({ user });
expect(findUserLocalTime().exists()).toBe(false);
});
});
describe('status data', () => {
it('should show only message', () => {
const user = { ...DEFAULT_PROPS.user, status: { message_html: 'Hello World' } };
......@@ -256,5 +276,11 @@ describe('User Popover Component', () => {
const securityBotDocsLink = findSecurityBotDocsLink();
expect(securityBotDocsLink.text()).toBe('Learn more about %<>\';"');
});
it('does not display local time', () => {
createWrapper({ user: SECURITY_BOT_USER });
expect(findUserLocalTime().exists()).toBe(false);
});
});
});
......@@ -3,10 +3,13 @@
require 'spec_helper'
RSpec.describe API::Entities::User do
let(:user) { create(:user) }
let_it_be(:timezone) { 'America/Los_Angeles' }
let(:user) { create(:user, timezone: timezone) }
let(:current_user) { create(:user) }
let(:entity) { described_class.new(user, current_user: current_user) }
subject { described_class.new(user, current_user: current_user).as_json }
subject { entity.as_json }
it 'exposes correct attributes' do
expect(subject).to include(:bio, :location, :public_email, :skype, :linkedin, :twitter, :website_url, :organization, :job_title, :work_information, :pronouns)
......@@ -35,4 +38,10 @@ RSpec.describe API::Entities::User do
expect(subject[:bot]).to eq(true)
end
end
it 'exposes local_time' do
local_time = '2:30 PM'
expect(entity).to receive(:local_time).with(timezone).and_return(local_time)
expect(subject[:local_time]).to eq(local_time)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment