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
92013227
Commit
92013227
authored
Dec 04, 2020
by
Sean McGivern
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Merge branch 'jswain_whats_new_tabs' into 'master'"
This reverts merge request !47852
parent
81aa1c82
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
198 additions
and
459 deletions
+198
-459
app/assets/javascripts/whats_new/components/app.vue
app/assets/javascripts/whats_new/components/app.vue
+66
-64
app/assets/javascripts/whats_new/components/feature.vue
app/assets/javascripts/whats_new/components/feature.vue
+0
-64
app/assets/javascripts/whats_new/index.js
app/assets/javascripts/whats_new/index.js
+3
-5
app/assets/javascripts/whats_new/store/actions.js
app/assets/javascripts/whats_new/store/actions.js
+1
-2
app/assets/stylesheets/components/whats_new.scss
app/assets/stylesheets/components/whats_new.scss
+0
-26
app/controllers/whats_new_controller.rb
app/controllers/whats_new_controller.rb
+7
-20
app/helpers/whats_new_helper.rb
app/helpers/whats_new_helper.rb
+1
-5
app/models/release_highlight.rb
app/models/release_highlight.rb
+10
-28
app/views/layouts/header/_default.html.haml
app/views/layouts/header/_default.html.haml
+1
-1
locale/gitlab.pot
locale/gitlab.pot
+0
-3
spec/frontend/whats_new/components/app_spec.js
spec/frontend/whats_new/components/app_spec.js
+68
-133
spec/frontend/whats_new/store/actions_spec.js
spec/frontend/whats_new/store/actions_spec.js
+0
-17
spec/helpers/whats_new_helper_spec.rb
spec/helpers/whats_new_helper_spec.rb
+2
-12
spec/models/release_highlight_spec.rb
spec/models/release_highlight_spec.rb
+34
-62
spec/requests/whats_new_controller_spec.rb
spec/requests/whats_new_controller_spec.rb
+5
-17
No files found.
app/assets/javascripts/whats_new/components/app.vue
View file @
92013227
...
...
@@ -2,15 +2,13 @@
import
{
mapState
,
mapActions
}
from
'
vuex
'
;
import
{
GlDrawer
,
GlBadge
,
GlIcon
,
GlLink
,
GlInfiniteScroll
,
GlResizeObserverDirective
,
GlTabs
,
GlTab
,
GlBadge
,
GlLoadingIcon
,
}
from
'
@gitlab/ui
'
;
import
SkeletonLoader
from
'
./skeleton_loader.vue
'
;
import
Feature
from
'
./feature.vue
'
;
import
Tracking
from
'
~/tracking
'
;
import
{
getDrawerBodyHeight
}
from
'
../utils/get_drawer_body_height
'
;
...
...
@@ -19,13 +17,11 @@ const trackingMixin = Tracking.mixin();
export
default
{
components
:
{
GlDrawer
,
GlBadge
,
GlIcon
,
GlLink
,
GlInfiniteScroll
,
GlTabs
,
GlTab
,
SkeletonLoader
,
Feature
,
GlBadge
,
GlLoadingIcon
,
},
directives
:
{
GlResizeObserver
:
GlResizeObserverDirective
,
...
...
@@ -35,19 +31,11 @@ export default {
storageKey
:
{
type
:
String
,
required
:
true
,
},
versions
:
{
type
:
Array
,
required
:
true
,
},
gitlabDotCom
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
default
:
null
,
},
},
computed
:
{
...
mapState
([
'
open
'
,
'
features
'
,
'
pageInfo
'
,
'
drawerBodyHeight
'
,
'
fetching
'
]),
...
mapState
([
'
open
'
,
'
features
'
,
'
pageInfo
'
,
'
drawerBodyHeight
'
]),
},
mounted
()
{
this
.
openDrawer
(
this
.
storageKey
);
...
...
@@ -61,25 +49,14 @@ export default {
methods
:
{
...
mapActions
([
'
openDrawer
'
,
'
closeDrawer
'
,
'
fetchItems
'
,
'
setDrawerBodyHeight
'
]),
bottomReached
()
{
const
page
=
this
.
pageInfo
.
nextPage
;
if
(
page
)
{
this
.
fetchItems
({
page
});
if
(
this
.
pageInfo
.
nextPage
)
{
this
.
fetchItems
(
this
.
pageInfo
.
nextPage
);
}
},
handleResize
()
{
const
height
=
getDrawerBodyHeight
(
this
.
$refs
.
drawer
.
$el
);
this
.
setDrawerBodyHeight
(
height
);
},
featuresForVersion
(
version
)
{
return
this
.
features
.
filter
(
feature
=>
{
return
feature
.
release
===
parseFloat
(
version
);
});
},
fetchVersion
(
version
)
{
if
(
this
.
featuresForVersion
(
version
).
length
===
0
)
{
this
.
fetchItems
({
version
});
}
},
},
};
</
script
>
...
...
@@ -96,39 +73,64 @@ export default {
<template
#header
>
<h4
class=
"page-title gl-my-2"
>
{{
__
(
"
What's new at GitLab
"
)
}}
</h4>
</
template
>
<
template
v-if=
"features.length"
>
<gl-infinite-scroll
v-if=
"gitlabDotCom"
:fetched-items=
"features.length"
:max-list-height=
"drawerBodyHeight"
class=
"gl-p-0"
@
bottomReached=
"bottomReached"
>
<template
#items
>
<feature
v-for=
"feature in features"
:key=
"feature.title"
:feature=
"feature"
/>
</
template
>
</gl-infinite-scroll>
<gl-tabs
v-else
:style=
"{ height: `${drawerBodyHeight}px` }"
class=
"gl-p-0"
>
<gl-tab
v-for=
"(version, index) in versions"
:key=
"version"
@
click=
"fetchVersion(version)"
<gl-infinite-scroll
v-if=
"features.length"
:fetched-items=
"features.length"
:max-list-height=
"drawerBodyHeight"
class=
"gl-p-0"
@
bottomReached=
"bottomReached"
>
<
template
#items
>
<div
v-for=
"feature in features"
:key=
"feature.title"
class=
"gl-pb-7 gl-pt-5 gl-px-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
>
<
template
#title
>
<span>
{{
version
}}
</span>
<gl-badge
v-if=
"index === 0"
>
{{
__
(
'
Your Version
'
)
}}
</gl-badge>
</
template
>
<gl-loading-icon
v-if=
"fetching"
size=
"lg"
class=
"text-center"
/>
<
template
v-else
>
<feature
v-for=
"feature in featuresForVersion(version)"
:key=
"feature.title"
:feature=
"feature"
<gl-link
:href=
"feature.url"
target=
"_blank"
class=
"whats-new-item-title-link"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
<h5
class=
"gl-font-lg"
>
{{
feature
.
title
}}
</h5>
</gl-link>
<div
v-if=
"feature.packages"
class=
"gl-mb-3"
>
<gl-badge
v-for=
"package_name in feature.packages"
:key=
"package_name"
size=
"sm"
class=
"whats-new-item-badge gl-mr-2"
>
<gl-icon
name=
"license"
/>
{{
package_name
}}
</gl-badge>
</div>
<gl-link
:href=
"feature.url"
target=
"_blank"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
<img
:alt=
"feature.title"
:src=
"feature.image_url"
class=
"img-thumbnail gl-px-8 gl-py-3 whats-new-item-image"
/>
</
template
>
</gl-tab>
</gl-tabs>
</template>
</gl-link>
<p
class=
"gl-pt-3"
>
{{
feature
.
body
}}
</p>
<gl-link
:href=
"feature.url"
target=
"_blank"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
{{
__
(
'
Learn more
'
)
}}
</gl-link
>
</div>
</
template
>
</gl-infinite-scroll>
<div
v-else
class=
"gl-mt-5"
>
<skeleton-loader
/>
<skeleton-loader
/>
...
...
app/assets/javascripts/whats_new/components/feature.vue
deleted
100644 → 0
View file @
81aa1c82
<
script
>
import
{
GlBadge
,
GlIcon
,
GlLink
}
from
'
@gitlab/ui
'
;
export
default
{
components
:
{
GlBadge
,
GlIcon
,
GlLink
,
},
props
:
{
feature
:
{
type
:
Object
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"gl-pb-7 gl-pt-5 gl-px-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
>
<gl-link
:href=
"feature.url"
target=
"_blank"
class=
"whats-new-item-title-link"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
<h5
class=
"gl-font-lg"
data-test-id=
"feature-title"
>
{{
feature
.
title
}}
</h5>
</gl-link>
<div
v-if=
"feature.packages"
class=
"gl-mb-3"
>
<gl-badge
v-for=
"packageName in feature.packages"
:key=
"packageName"
size=
"sm"
class=
"whats-new-item-badge gl-mr-2"
>
<gl-icon
name=
"license"
/>
{{
packageName
}}
</gl-badge>
</div>
<gl-link
:href=
"feature.url"
target=
"_blank"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
<img
:alt=
"feature.title"
:src=
"feature.image_url"
class=
"img-thumbnail gl-px-8 gl-py-3 whats-new-item-image"
/>
</gl-link>
<p
class=
"gl-pt-3"
>
{{
feature
.
body
}}
</p>
<gl-link
:href=
"feature.url"
target=
"_blank"
data-track-event=
"click_whats_new_item"
:data-track-label=
"feature.title"
:data-track-property=
"feature.url"
>
{{
__
(
'
Learn more
'
)
}}
</gl-link
>
</div>
</
template
>
app/assets/javascripts/whats_new/index.js
View file @
92013227
...
...
@@ -10,6 +10,8 @@ export default el => {
if
(
whatsNewApp
)
{
store
.
dispatch
(
'
openDrawer
'
);
}
else
{
const
storageKey
=
getStorageKey
(
el
);
whatsNewApp
=
new
Vue
({
el
,
store
,
...
...
@@ -26,11 +28,7 @@ export default el => {
},
render
(
createElement
)
{
return
createElement
(
'
app
'
,
{
props
:
{
storageKey
:
getStorageKey
(
el
),
versions
:
JSON
.
parse
(
el
.
getAttribute
(
'
data-versions
'
)),
gitlabDotCom
:
el
.
getAttribute
(
'
data-gitlab-dot-com
'
),
},
props
:
{
storageKey
},
});
},
});
...
...
app/assets/javascripts/whats_new/store/actions.js
View file @
92013227
...
...
@@ -13,7 +13,7 @@ export default {
localStorage
.
setItem
(
storageKey
,
JSON
.
stringify
(
false
));
}
},
fetchItems
({
commit
,
state
},
{
page
,
version
}
=
{
page
:
null
,
version
:
null
}
)
{
fetchItems
({
commit
,
state
},
page
)
{
if
(
state
.
fetching
)
{
return
false
;
}
...
...
@@ -24,7 +24,6 @@ export default {
.
get
(
'
/-/whats_new
'
,
{
params
:
{
page
,
version
,
},
})
.
then
(({
data
,
headers
})
=>
{
...
...
app/assets/stylesheets/components/whats_new.scss
View file @
92013227
...
...
@@ -6,32 +6,6 @@
.gl-infinite-scroll-legend
{
@include
gl-display-none
;
}
.gl-tabs
{
@include
gl-overflow-y-auto
;
}
.gl-tabs-nav
{
flex-wrap
:
nowrap
;
overflow-x
:
scroll
;
align-items
:
stretch
;
.nav-item
{
@include
gl-flex-shrink-0
;
a
{
@include
gl-h-full
;
line-height
:
1
.5
;
}
}
}
.gl-spinner-container
{
@include
gl-w-full
;
@include
gl-absolute
;
top
:
50%
;
transform
:
translateY
(
-50%
);
}
}
.with-performance-bar
.whats-new-drawer
{
...
...
app/controllers/whats_new_controller.rb
View file @
92013227
# frozen_string_literal: true
class
WhatsNewController
<
ApplicationController
include
Gitlab
::
Utils
::
StrongMemoize
skip_before_action
:authenticate_user!
before_action
:check_feature_flag
before_action
:check_valid_page_param
,
:set_pagination_headers
,
unless:
->
{
has_version_param?
}
before_action
:check_feature_flag
,
:check_valid_page_param
,
:set_pagination_headers
feature_category
:navigation
def
index
respond_to
do
|
format
|
format
.
js
do
render
json:
highligh
t_items
render
json:
most_recen
t_items
end
end
end
...
...
@@ -32,25 +29,15 @@ class WhatsNewController < ApplicationController
params
[
:page
]
&
.
to_i
||
1
end
def
highlights
strong_memoize
(
:highlights
)
do
if
has_version_param?
ReleaseHighlight
.
for_version
(
version:
params
[
:version
])
else
ReleaseHighlight
.
paginated
(
page:
current_page
)
end
end
def
most_recent
@most_recent
||=
ReleaseHighlight
.
paginated
(
page:
current_page
)
end
def
highligh
t_items
highlights
.
map
{
|
item
|
Gitlab
::
WhatsNew
::
ItemPresenter
.
present
(
item
)
}
def
most_recen
t_items
most_recent
[
:items
]
.
map
{
|
item
|
Gitlab
::
WhatsNew
::
ItemPresenter
.
present
(
item
)
}
end
def
set_pagination_headers
response
.
set_header
(
'X-Next-Page'
,
highlights
.
next_page
)
end
def
has_version_param?
params
[
:version
].
present?
response
.
set_header
(
'X-Next-Page'
,
most_recent
[
:next_page
])
end
end
app/helpers/whats_new_helper.rb
View file @
92013227
...
...
@@ -6,14 +6,10 @@ module WhatsNewHelper
end
def
whats_new_storage_key
most_recent_version
=
ReleaseHighlight
.
versions
&
.
first
most_recent_version
=
ReleaseHighlight
.
most_recent_version
return
unless
most_recent_version
[
'display-whats-new-notification'
,
most_recent_version
].
join
(
'-'
)
end
def
whats_new_versions
ReleaseHighlight
.
versions
end
end
app/models/release_highlight.rb
View file @
92013227
...
...
@@ -3,17 +3,6 @@
class
ReleaseHighlight
CACHE_DURATION
=
1
.
hour
FILES_PATH
=
Rails
.
root
.
join
(
'data'
,
'whats_new'
,
'*.yml'
)
RELEASE_VERSIONS_IN_A_YEAR
=
12
def
self
.
for_version
(
version
:)
index
=
self
.
versions
.
index
(
version
)
return
if
index
.
nil?
page
=
index
+
1
self
.
paginated
(
page:
page
)
end
def
self
.
paginated
(
page:
1
)
Rails
.
cache
.
fetch
(
cache_key
(
page
),
expires_in:
CACHE_DURATION
)
do
...
...
@@ -21,7 +10,10 @@ class ReleaseHighlight
next
if
items
.
nil?
QueryResult
.
new
(
items:
items
,
next_page:
next_page
(
current_page:
page
))
{
items:
items
,
next_page:
next_page
(
current_page:
page
)
}
end
end
...
...
@@ -61,25 +53,15 @@ class ReleaseHighlight
next_page
if
self
.
file_paths
[
next_index
]
end
def
self
.
most_recent_
item_count
Gitlab
::
ProcessMemoryCache
.
cache_backend
.
fetch
(
'release_highlight:re
cent_item_count
'
,
expires_in:
CACHE_DURATION
)
do
self
.
paginated
&
.
items
&
.
count
def
self
.
most_recent_
version
Gitlab
::
ProcessMemoryCache
.
cache_backend
.
fetch
(
'release_highlight:re
lease_version
'
,
expires_in:
CACHE_DURATION
)
do
self
.
paginated
&
.
[
](
:items
)
&
.
first
&
.
[
](
'release'
)
end
end
def
self
.
versions
Gitlab
::
ProcessMemoryCache
.
cache_backend
.
fetch
(
'release_highlight:versions'
,
expires_in:
CACHE_DURATION
)
do
versions
=
self
.
file_paths
.
first
(
RELEASE_VERSIONS_IN_A_YEAR
).
map
do
|
path
|
/\d*\_(\d*\_\d*)\.yml$/
.
match
(
path
).
captures
[
0
].
gsub
(
/0(?=\d)/
,
""
).
tr
(
"_"
,
"."
)
end
versions
.
uniq
def
self
.
most_recent_item_count
Gitlab
::
ProcessMemoryCache
.
cache_backend
.
fetch
(
'release_highlight:recent_item_count'
,
expires_in:
CACHE_DURATION
)
do
self
.
paginated
&
.
[
](
:items
)
&
.
count
end
end
QueryResult
=
Struct
.
new
(
:items
,
:next_page
,
keyword_init:
true
)
do
include
Enumerable
delegate
:each
,
to: :items
end
end
app/views/layouts/header/_default.html.haml
View file @
92013227
...
...
@@ -102,7 +102,7 @@
=
sprite_icon
(
'close'
,
size:
12
,
css_class:
'close-icon js-navbar-toggle-left'
)
-
if
::
Feature
.
enabled?
(
:whats_new_drawer
,
current_user
)
#whats-new-app
{
data:
{
storage_key:
whats_new_storage_key
,
versions:
whats_new_versions
,
gitlab_dot_com:
Gitlab
.
dev_env_org_or_com?
}
}
#whats-new-app
{
data:
{
storage_key:
whats_new_storage_key
}
}
-
if
can?
(
current_user
,
:update_user_status
,
current_user
)
.js-set-status-modal-wrapper
{
data:
user_status_data
}
locale/gitlab.pot
View file @
92013227
...
...
@@ -31747,9 +31747,6 @@ msgstr ""
msgid "Your U2F device was registered!"
msgstr ""
msgid "Your Version"
msgstr ""
msgid "Your WebAuthn device did not send a valid JSON response."
msgstr ""
...
...
spec/frontend/whats_new/components/app_spec.js
View file @
92013227
import
{
createLocalVue
,
mount
}
from
'
@vue/test-utils
'
;
import
Vuex
from
'
vuex
'
;
import
{
GlDrawer
,
GlInfiniteScroll
,
GlTabs
}
from
'
@gitlab/ui
'
;
import
{
GlDrawer
,
GlInfiniteScroll
}
from
'
@gitlab/ui
'
;
import
{
mockTracking
,
unmockTracking
,
triggerEvent
}
from
'
helpers/tracking_helper
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
import
App
from
'
~/whats_new/components/app.vue
'
;
...
...
@@ -16,18 +16,12 @@ const localVue = createLocalVue();
localVue
.
use
(
Vuex
);
describe
(
'
App
'
,
()
=>
{
const
propsData
=
{
storageKey
:
'
storage-key
'
};
let
wrapper
;
let
store
;
let
actions
;
let
state
;
let
trackingSpy
;
let
gitlabDotCom
=
true
;
const
buildProps
=
()
=>
({
storageKey
:
'
storage-key
'
,
versions
:
[
'
3.11
'
,
'
3.10
'
],
gitlabDotCom
,
});
const
buildWrapper
=
()
=>
{
actions
=
{
...
...
@@ -51,7 +45,7 @@ describe('App', () => {
wrapper
=
mount
(
App
,
{
localVue
,
store
,
propsData
:
buildProps
()
,
propsData
,
directives
:
{
GlResizeObserver
:
createMockDirective
(),
},
...
...
@@ -59,171 +53,112 @@ describe('App', () => {
};
const
findInfiniteScroll
=
()
=>
wrapper
.
find
(
GlInfiniteScroll
);
const
emitBottomReached
=
()
=>
findInfiniteScroll
().
vm
.
$emit
(
'
bottomReached
'
);
const
setup
=
async
()
=>
{
beforeEach
(
async
()
=>
{
document
.
body
.
dataset
.
page
=
'
test-page
'
;
document
.
body
.
dataset
.
namespaceId
=
'
namespace-840
'
;
trackingSpy
=
mockTracking
(
'
_category_
'
,
null
,
jest
.
spyOn
);
buildWrapper
();
wrapper
.
vm
.
$store
.
state
.
features
=
[
{
title
:
'
Whats New Drawer
'
,
url
:
'
www.url.com
'
,
release
:
3.11
},
];
wrapper
.
vm
.
$store
.
state
.
features
=
[{
title
:
'
Whats New Drawer
'
,
url
:
'
www.url.com
'
}];
wrapper
.
vm
.
$store
.
state
.
drawerBodyHeight
=
MOCK_DRAWER_BODY_HEIGHT
;
await
wrapper
.
vm
.
$nextTick
();
};
}
)
;
afterEach
(()
=>
{
wrapper
.
destroy
();
unmockTracking
();
});
describe
(
'
gitlab.com
'
,
()
=>
{
beforeEach
(()
=>
{
setup
();
});
const
getDrawer
=
()
=>
wrapper
.
find
(
GlDrawer
);
it
(
'
contains a drawer
'
,
()
=>
{
expect
(
getDrawer
().
exists
()).
toBe
(
true
);
});
it
(
'
dispatches openDrawer and tracking calls when mounted
'
,
()
=>
{
expect
(
actions
.
openDrawer
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
'
storage-key
'
);
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
'
click_whats_new_drawer
'
,
{
label
:
'
namespace_id
'
,
value
:
'
namespace-840
'
,
});
});
it
(
'
dispatches closeDrawer when clicking close
'
,
()
=>
{
getDrawer
().
vm
.
$emit
(
'
close
'
);
expect
(
actions
.
closeDrawer
).
toHaveBeenCalled
();
});
it
.
each
([
true
,
false
])(
'
passes open property
'
,
async
openState
=>
{
wrapper
.
vm
.
$store
.
state
.
open
=
openState
;
await
wrapper
.
vm
.
$nextTick
();
expect
(
getDrawer
().
props
(
'
open
'
)).
toBe
(
openState
);
});
it
(
'
renders features when provided via ajax
'
,
()
=>
{
expect
(
actions
.
fetchItems
).
toHaveBeenCalled
();
expect
(
wrapper
.
find
(
'
[data-test-id="feature-title"]
'
).
text
()).
toBe
(
'
Whats New Drawer
'
);
});
it
(
'
send an event when feature item is clicked
'
,
()
=>
{
trackingSpy
=
mockTracking
(
'
_category_
'
,
wrapper
.
element
,
jest
.
spyOn
);
const
getDrawer
=
()
=>
wrapper
.
find
(
GlDrawer
);
const
link
=
wrapper
.
find
(
'
.whats-new-item-title-link
'
);
triggerEvent
(
link
.
element
);
it
(
'
contains a drawer
'
,
()
=>
{
expect
(
getDrawer
().
exists
()).
toBe
(
true
);
});
expect
(
trackingSpy
.
mock
.
calls
[
1
]).
toMatchObject
([
'
_category_
'
,
'
click_whats_new_item
'
,
{
label
:
'
Whats New Drawer
'
,
property
:
'
www.url.com
'
,
},
]);
it
(
'
dispatches openDrawer and tracking calls when mounted
'
,
()
=>
{
expect
(
actions
.
openDrawer
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
'
storage-key
'
);
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
'
click_whats_new_drawer
'
,
{
label
:
'
namespace_id
'
,
value
:
'
namespace-840
'
,
});
});
it
(
'
renders infinite scroll
'
,
()
=>
{
const
scroll
=
findInfiniteScroll
();
expect
(
scroll
.
props
()).
toMatchObject
({
fetchedItems
:
wrapper
.
vm
.
$store
.
state
.
features
.
length
,
maxListHeight
:
MOCK_DRAWER_BODY_HEIGHT
,
});
});
it
(
'
dispatches closeDrawer when clicking close
'
,
()
=>
{
getDrawer
().
vm
.
$emit
(
'
close
'
);
expect
(
actions
.
closeDrawer
).
toHaveBeenCalled
();
});
describe
(
'
bottomReached
'
,
()
=>
{
const
emitBottomReached
=
()
=>
findInfiniteScroll
().
vm
.
$emit
(
'
bottomReached
'
)
;
it
.
each
([
true
,
false
])(
'
passes open property
'
,
async
openState
=>
{
wrapper
.
vm
.
$store
.
state
.
open
=
openState
;
beforeEach
(()
=>
{
actions
.
fetchItems
.
mockClear
();
});
await
wrapper
.
vm
.
$nextTick
();
it
(
'
when nextPage exists it calls fetchItems
'
,
()
=>
{
wrapper
.
vm
.
$store
.
state
.
pageInfo
=
{
nextPage
:
840
};
emitBottomReached
();
expect
(
getDrawer
().
props
(
'
open
'
)).
toBe
(
openState
);
});
expect
(
actions
.
fetchItems
).
toHaveBeenCalledWith
(
expect
.
anything
(),
{
page
:
840
});
});
it
(
'
renders features when provided via ajax
'
,
()
=>
{
expect
(
actions
.
fetchItems
).
toHaveBeenCalled
();
expect
(
wrapper
.
find
(
'
h5
'
).
text
()).
toBe
(
'
Whats New Drawer
'
);
});
it
(
'
when nextPage does not exist it does not call fetchItems
'
,
()
=>
{
wrapper
.
vm
.
$store
.
state
.
pageInfo
=
{
nextPage
:
null
};
emitBottomReached
();
it
(
'
send an event when feature item is clicked
'
,
()
=>
{
trackingSpy
=
mockTracking
(
'
_category_
'
,
wrapper
.
element
,
jest
.
spyOn
);
expect
(
actions
.
fetchItems
).
not
.
toHaveBeenCalled
();
});
});
const
link
=
wrapper
.
find
(
'
.whats-new-item-title-link
'
);
triggerEvent
(
link
.
element
);
it
(
'
calls getDrawerBodyHeight and setDrawerBodyHeight when resize directive is triggered
'
,
()
=>
{
const
{
value
}
=
getBinding
(
getDrawer
().
element
,
'
gl-resize-observer
'
);
value
();
expect
(
trackingSpy
.
mock
.
calls
[
1
]).
toMatchObject
([
'
_category_
'
,
'
click_whats_new_item
'
,
{
label
:
'
Whats New Drawer
'
,
property
:
'
www.url.com
'
,
},
]);
});
expect
(
getDrawerBodyHeight
).
toHaveBeenCalledWith
(
wrapper
.
find
(
GlDrawer
).
element
);
it
(
'
renders infinite scroll
'
,
()
=>
{
const
scroll
=
findInfiniteScroll
();
expect
(
actions
.
setDrawerBodyHeight
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
MOCK_DRAWER_BODY_HEIGHT
,
);
expect
(
scroll
.
props
()).
toMatchObject
({
fetchedItems
:
wrapper
.
vm
.
$store
.
state
.
features
.
length
,
maxListHeight
:
MOCK_DRAWER_BODY_HEIGHT
,
});
});
describe
(
'
self managed
'
,
()
=>
{
const
findTabs
=
()
=>
wrapper
.
find
(
GlTabs
);
const
clickSecondTab
=
async
()
=>
{
const
secondTab
=
wrapper
.
findAll
(
'
.nav-link
'
).
at
(
1
);
await
secondTab
.
trigger
(
'
click
'
);
await
new
Promise
(
resolve
=>
requestAnimationFrame
(
resolve
));
};
describe
(
'
bottomReached
'
,
()
=>
{
beforeEach
(()
=>
{
gitlabDotCom
=
false
;
setup
();
actions
.
fetchItems
.
mockClear
();
});
it
(
'
renders tabs with drawer body height and content
'
,
()
=>
{
const
scroll
=
findInfiniteScroll
()
;
const
tabs
=
findTabs
();
it
(
'
when nextPage exists it calls fetchItems
'
,
()
=>
{
wrapper
.
vm
.
$store
.
state
.
pageInfo
=
{
nextPage
:
840
}
;
emitBottomReached
();
expect
(
scroll
.
exists
()).
toBe
(
false
);
expect
(
tabs
.
attributes
().
style
).
toBe
(
`height:
${
MOCK_DRAWER_BODY_HEIGHT
}
px;`
);
expect
(
wrapper
.
find
(
'
h5
'
).
text
()).
toBe
(
'
Whats New Drawer
'
);
expect
(
actions
.
fetchItems
).
toHaveBeenCalledWith
(
expect
.
anything
(),
840
);
});
describe
(
'
fetchVersion
'
,
()
=>
{
beforeEach
(()
=>
{
actions
.
fetchItems
.
mockClear
();
});
it
(
'
when nextPage does not exist it does not call fetchItems
'
,
()
=>
{
wrapper
.
vm
.
$store
.
state
.
pageInfo
=
{
nextPage
:
null
};
emitBottomReached
();
it
(
'
when version isnt fetched, clicking a tab calls fetchItems
'
,
async
()
=>
{
const
fetchVersionSpy
=
jest
.
spyOn
(
wrapper
.
vm
,
'
fetchVersion
'
);
await
clickSecondTab
(
);
expect
(
actions
.
fetchItems
).
not
.
toHaveBeenCalled
();
}
);
}
);
expect
(
fetchVersionSpy
).
toHaveBeenCalledWith
(
'
3.10
'
);
expect
(
actions
.
fetchItems
).
toHaveBeenCalledWith
(
expect
.
anything
(),
{
version
:
'
3.10
'
});
});
it
(
'
calls getDrawerBodyHeight and setDrawerBodyHeight when resize directive is triggered
'
,
()
=>
{
const
{
value
}
=
getBinding
(
getDrawer
().
element
,
'
gl-resize-observer
'
);
it
(
'
when version has been fetched, clicking a tab calls fetchItems
'
,
async
()
=>
{
wrapper
.
vm
.
$store
.
state
.
features
.
push
({
title
:
'
GitLab Stories
'
,
release
:
3.1
});
await
wrapper
.
vm
.
$nextTick
();
value
();
const
fetchVersionSpy
=
jest
.
spyOn
(
wrapper
.
vm
,
'
fetchVersion
'
);
await
clickSecondTab
();
expect
(
getDrawerBodyHeight
).
toHaveBeenCalledWith
(
wrapper
.
find
(
GlDrawer
).
element
);
expect
(
fetchVersionSpy
).
toHaveBeenCalledWith
(
'
3.10
'
);
expect
(
actions
.
fetchItems
).
not
.
toHaveBeenCalled
();
expect
(
wrapper
.
find
(
'
.tab-pane.active h5
'
).
text
()).
toBe
(
'
GitLab Stories
'
);
});
});
expect
(
actions
.
setDrawerBodyHeight
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
MOCK_DRAWER_BODY_HEIGHT
,
);
});
});
spec/frontend/whats_new/store/actions_spec.js
View file @
92013227
...
...
@@ -41,23 +41,6 @@ describe('whats new actions', () => {
axiosMock
.
restore
();
});
it
(
'
passes arguments
'
,
()
=>
{
axiosMock
.
reset
();
axiosMock
.
onGet
(
'
/-/whats_new
'
,
{
params
:
{
page
:
8
,
version
:
40
}
})
.
replyOnce
(
200
,
[{
title
:
'
GitLab Stories
'
}]);
testAction
(
actions
.
fetchItems
,
{
page
:
8
,
version
:
40
},
{},
expect
.
arrayContaining
([
{
type
:
types
.
ADD_FEATURES
,
payload
:
[{
title
:
'
GitLab Stories
'
}]
},
]),
);
});
it
(
'
if already fetching, does not fetch
'
,
()
=>
{
testAction
(
actions
.
fetchItems
,
{},
{
fetching
:
true
},
[]);
});
...
...
spec/helpers/whats_new_helper_spec.rb
View file @
92013227
...
...
@@ -10,7 +10,7 @@ RSpec.describe WhatsNewHelper do
let
(
:release_item
)
{
double
(
:item
)
}
before
do
allow
(
ReleaseHighlight
).
to
receive
(
:
versions
).
and_return
([
84.0
]
)
allow
(
ReleaseHighlight
).
to
receive
(
:
most_recent_version
).
and_return
(
84.0
)
end
it
{
is_expected
.
to
eq
(
'display-whats-new-notification-84.0'
)
}
...
...
@@ -18,7 +18,7 @@ RSpec.describe WhatsNewHelper do
context
'when most recent release highlights do NOT exist'
do
before
do
allow
(
ReleaseHighlight
).
to
receive
(
:
versions
).
and_return
(
nil
)
allow
(
ReleaseHighlight
).
to
receive
(
:
most_recent_version
).
and_return
(
nil
)
end
it
{
is_expected
.
to
be_nil
}
...
...
@@ -44,14 +44,4 @@ RSpec.describe WhatsNewHelper do
end
end
end
describe
'#whats_new_versions'
do
let
(
:versions
)
{
[
84.0
]
}
it
'returns ReleaseHighlight.versions'
do
expect
(
ReleaseHighlight
).
to
receive
(
:versions
).
and_return
(
versions
)
expect
(
helper
.
whats_new_versions
).
to
eq
(
versions
)
end
end
end
spec/models/release_highlight_spec.rb
View file @
92013227
...
...
@@ -3,44 +3,21 @@
require
'spec_helper'
RSpec
.
describe
ReleaseHighlight
do
let
(
:fixture_dir_glob
)
{
Dir
.
glob
(
File
.
join
(
'spec'
,
'fixtures'
,
'whats_new'
,
'*.yml'
))
}
let
(
:cache_mock
)
{
double
(
:cache_mock
)
}
before
do
allow
(
Dir
).
to
receive
(
:glob
).
with
(
Rails
.
root
.
join
(
'data'
,
'whats_new'
,
'*.yml'
)).
and_return
(
fixture_dir_glob
)
allow
(
cache_mock
).
to
receive
(
:fetch
).
with
(
'release_highlight:file_paths'
,
expires_in:
1
.
hour
).
and_yield
end
after
do
ReleaseHighlight
.
instance_variable_set
(
:@file_paths
,
nil
)
end
describe
'.for_version'
do
subject
{
ReleaseHighlight
.
for_version
(
version:
version
)
}
let
(
:version
)
{
'1.1'
}
context
'with version param that exists'
do
it
'returns items from that version'
do
expect
(
subject
.
items
.
first
[
'title'
]).
to
eq
(
"It's gonna be a bright"
)
end
end
context
'with version param that does NOT exist'
do
let
(
:version
)
{
'84.0'
}
it
'returns nil'
do
expect
(
subject
).
to
be_nil
end
end
end
describe
'.paginated'
do
describe
'#paginated'
do
let
(
:fixture_dir_glob
)
{
Dir
.
glob
(
File
.
join
(
'spec'
,
'fixtures'
,
'whats_new'
,
'*.yml'
))
}
let
(
:cache_mock
)
{
double
(
:cache_mock
)
}
let
(
:dot_com
)
{
false
}
before
do
allow
(
Gitlab
).
to
receive
(
:com?
).
and_return
(
dot_com
)
allow
(
Dir
).
to
receive
(
:glob
).
with
(
Rails
.
root
.
join
(
'data'
,
'whats_new'
,
'*.yml'
)).
and_return
(
fixture_dir_glob
)
expect
(
Rails
).
to
receive
(
:cache
).
twice
.
and_return
(
cache_mock
)
expect
(
cache_mock
).
to
receive
(
:fetch
).
with
(
'release_highlight:file_paths'
,
expires_in:
1
.
hour
).
and_yield
end
after
do
ReleaseHighlight
.
instance_variable_set
(
:@file_paths
,
nil
)
end
context
'with page param'
do
...
...
@@ -113,51 +90,46 @@ RSpec.describe ReleaseHighlight do
end
end
describe
'.most_recent_
item_count
'
do
subject
{
ReleaseHighlight
.
most_recent_
item_count
}
describe
'.most_recent_
version
'
do
subject
{
ReleaseHighlight
.
most_recent_
version
}
context
'when recent release items exist'
do
it
'returns the count from the most recent file'
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
and_return
(
double
(
:paginated
,
items:
[
double
(
:item
)]))
context
'when version exist'
do
let
(
:release_item
)
{
double
(
:item
)
}
expect
(
subject
).
to
eq
(
1
)
before
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
and_return
({
items:
[
release_item
]
})
allow
(
release_item
).
to
receive
(
:[]
).
with
(
'release'
).
and_return
(
84.0
)
end
it
{
is_expected
.
to
eq
(
84.0
)
}
end
context
'when
recent release item
s do NOT exist'
do
it
'returns nil'
do
context
'when
most recent release highlight
s do NOT exist'
do
before
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
and_return
(
nil
)
expect
(
subject
).
to
be_nil
end
it
{
is_expected
.
to
be_nil
}
end
end
describe
'.versions'
do
it
'returns versions from the file paths'
do
expect
(
ReleaseHighlight
.
versions
).
to
eq
([
'1.5'
,
'1.2'
,
'1.1'
])
end
describe
'#most_recent_item_count'
do
subject
{
ReleaseHighlight
.
most_recent_item_count
}
context
'when there are more than 12 versions'
do
let
(
:file_paths
)
do
i
=
0
Array
.
new
(
20
)
{
"20201225_01_
#{
i
+=
1
}
.yml"
}
end
context
'when recent release items exist'
do
it
'returns the count from the most recent file'
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
and_return
({
items:
[
double
(
:item
)]
})
it
'limits to 12 versions'
do
allow
(
ReleaseHighlight
).
to
receive
(
:file_paths
).
and_return
(
file_paths
)
expect
(
ReleaseHighlight
.
versions
.
count
).
to
eq
(
12
)
expect
(
subject
).
to
eq
(
1
)
end
end
end
describe
'QueryResult'
do
subject
{
ReleaseHighlight
::
QueryResult
.
new
(
items:
items
,
next_page:
2
)
}
let
(
:items
)
{
[
:item
]
}
context
'when recent release items do NOT exist'
do
it
'returns nil'
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
and_return
(
nil
)
it
'responds to map'
do
e
xpect
(
subject
.
map
(
&
:to_s
)).
to
eq
(
items
.
map
(
&
:to_s
))
expect
(
subject
).
to
be_nil
e
nd
end
end
end
spec/requests/whats_new_controller_spec.rb
View file @
92013227
...
...
@@ -4,22 +4,22 @@ require 'spec_helper'
RSpec
.
describe
WhatsNewController
do
describe
'whats_new_path'
do
let
(
:item
)
{
double
(
:item
)
}
let
(
:highlights
)
{
double
(
:highlight
,
items:
[
item
],
map:
[
item
].
map
,
next_page:
2
)
}
context
'with whats_new_drawer feature enabled'
do
before
do
stub_feature_flags
(
whats_new_drawer:
true
)
end
context
'with no page param'
do
let
(
:most_recent
)
{
{
items:
[
item
],
next_page:
2
}
}
let
(
:item
)
{
double
(
:item
)
}
it
'responds with paginated data and headers'
do
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
with
(
page:
1
).
and_return
(
highlights
)
allow
(
ReleaseHighlight
).
to
receive
(
:paginated
).
with
(
page:
1
).
and_return
(
most_recent
)
allow
(
Gitlab
::
WhatsNew
::
ItemPresenter
).
to
receive
(
:present
).
with
(
item
).
and_return
(
item
)
get
whats_new_path
,
xhr:
true
expect
(
response
.
body
).
to
eq
(
highlights
.
items
.
to_json
)
expect
(
response
.
body
).
to
eq
(
most_recent
[
:items
]
.
to_json
)
expect
(
response
.
headers
[
'X-Next-Page'
]).
to
eq
(
2
)
end
end
...
...
@@ -37,18 +37,6 @@ RSpec.describe WhatsNewController do
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'with version param'
do
it
'returns items without pagination headers'
do
allow
(
ReleaseHighlight
).
to
receive
(
:for_version
).
with
(
version:
'42'
).
and_return
(
highlights
)
allow
(
Gitlab
::
WhatsNew
::
ItemPresenter
).
to
receive
(
:present
).
with
(
item
).
and_return
(
item
)
get
whats_new_path
(
version:
42
),
xhr:
true
expect
(
response
.
body
).
to
eq
(
highlights
.
items
.
to_json
)
expect
(
response
.
headers
[
'X-Next-Page'
]).
to
be_nil
end
end
end
context
'with whats_new_drawer feature disabled'
do
...
...
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