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
0
Merge Requests
0
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
Léo-Paul Géneau
gitlab-ce
Commits
c7c5492c
Commit
c7c5492c
authored
Feb 06, 2019
by
Phil Hughes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'knative-list' into 'master'
Modify Serverless Listing See merge request gitlab-org/gitlab-ce!24072
parents
cef60443
17bae7c7
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
513 additions
and
103 deletions
+513
-103
app/assets/javascripts/serverless/components/environment_row.vue
...ets/javascripts/serverless/components/environment_row.vue
+65
-0
app/assets/javascripts/serverless/components/function_details.vue
...ts/javascripts/serverless/components/function_details.vue
+4
-21
app/assets/javascripts/serverless/components/function_row.vue
...assets/javascripts/serverless/components/function_row.vue
+36
-19
app/assets/javascripts/serverless/components/functions.vue
app/assets/javascripts/serverless/components/functions.vue
+18
-41
app/assets/javascripts/serverless/components/url.vue
app/assets/javascripts/serverless/components/url.vue
+38
-0
app/assets/javascripts/serverless/stores/serverless_store.js
app/assets/javascripts/serverless/stores/serverless_store.js
+8
-3
app/assets/stylesheets/pages/serverless.scss
app/assets/stylesheets/pages/serverless.scss
+3
-0
changelogs/unreleased/knative-list.yml
changelogs/unreleased/knative-list.yml
+5
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-18
spec/features/projects/serverless/functions_spec.rb
spec/features/projects/serverless/functions_spec.rb
+8
-1
spec/javascripts/serverless/components/environment_row_spec.js
...javascripts/serverless/components/environment_row_spec.js
+81
-0
spec/javascripts/serverless/components/function_row_spec.js
spec/javascripts/serverless/components/function_row_spec.js
+33
-0
spec/javascripts/serverless/components/functions_spec.js
spec/javascripts/serverless/components/functions_spec.js
+68
-0
spec/javascripts/serverless/components/url_spec.js
spec/javascripts/serverless/components/url_spec.js
+28
-0
spec/javascripts/serverless/mock_data.js
spec/javascripts/serverless/mock_data.js
+79
-0
spec/javascripts/serverless/stores/serverless_store_spec.js
spec/javascripts/serverless/stores/serverless_store_spec.js
+36
-0
No files found.
app/assets/javascripts/serverless/components/environment_row.vue
0 → 100644
View file @
c7c5492c
<
script
>
import
FunctionRow
from
'
./function_row.vue
'
;
import
ItemCaret
from
'
~/groups/components/item_caret.vue
'
;
export
default
{
components
:
{
ItemCaret
,
FunctionRow
,
},
props
:
{
env
:
{
type
:
Array
,
required
:
true
,
},
envName
:
{
type
:
String
,
required
:
true
,
},
},
data
()
{
return
{
isOpen
:
true
,
};
},
computed
:
{
envId
()
{
if
(
this
.
envName
===
'
*
'
)
{
return
'
env-global
'
;
}
return
`env-
${
this
.
envName
}
`
;
},
isOpenClass
()
{
return
{
'
is-open
'
:
this
.
isOpen
,
};
},
},
methods
:
{
toggleOpen
()
{
this
.
isOpen
=
!
this
.
isOpen
;
},
},
};
</
script
>
<
template
>
<li
:id=
"envId"
:class=
"isOpenClass"
class=
"group-row has-children"
>
<div
class=
"group-row-contents d-flex justify-content-end align-items-center"
role=
"button"
@
click.stop=
"toggleOpen"
>
<div
class=
"folder-toggle-wrap d-flex align-items-center"
>
<item-caret
:is-group-open=
"isOpen"
/>
</div>
<div
class=
"group-text flex-grow title namespace-title prepend-left-default"
>
{{
envName
}}
</div>
</div>
<ul
v-if=
"isOpen"
class=
"content-list group-list-tree"
>
<function-row
v-for=
"(f, index) in env"
:key=
"f.name"
:index=
"index"
:func=
"f"
/>
</ul>
</li>
</
template
>
app/assets/javascripts/serverless/components/function_details.vue
View file @
c7c5492c
<
script
>
<
script
>
import
PodBox
from
'
./pod_box.vue
'
;
import
PodBox
from
'
./pod_box.vue
'
;
import
ClipboardButton
from
'
../../vue_shared/components/clipboard_button.vue
'
;
import
Url
from
'
./url.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
Icon
,
PodBox
,
PodBox
,
ClipboardButton
,
Url
,
},
},
props
:
{
props
:
{
func
:
{
func
:
{
...
@@ -36,24 +34,9 @@ export default {
...
@@ -36,24 +34,9 @@ export default {
<section
id=
"serverless-function-details"
>
<section
id=
"serverless-function-details"
>
<h3>
{{
name
}}
</h3>
<h3>
{{
name
}}
</h3>
<div
class=
"append-bottom-default"
>
<div
class=
"append-bottom-default"
>
<div
v-for=
"line in description.split('\n')"
:key=
"line"
>
{{
line
}}
<br
/></div>
<div
v-for=
"(line, index) in description.split('\n')"
:key=
"index"
>
{{
line
}}
</div>
</div>
<div
class=
"clipboard-group append-bottom-default"
>
<div
class=
"label label-monospace"
>
{{
funcUrl
}}
</div>
<clipboard-button
:text=
"String(funcUrl)"
:title=
"s__('ServerlessDetails|Copy URL to clipboard')"
class=
"input-group-text js-clipboard-btn"
/>
<a
:href=
"funcUrl"
target=
"_blank"
rel=
"noopener noreferrer nofollow"
class=
"input-group-text btn btn-default"
>
<icon
name=
"external-link"
/>
</a>
</div>
</div>
<url
:uri=
"funcUrl"
/>
<h4>
{{
s__
(
'
ServerlessDetails|Kubernetes Pods
'
)
}}
</h4>
<h4>
{{
s__
(
'
ServerlessDetails|Kubernetes Pods
'
)
}}
</h4>
<div
v-if=
"podCount > 0"
>
<div
v-if=
"podCount > 0"
>
...
...
app/assets/javascripts/serverless/components/function_row.vue
View file @
c7c5492c
<
script
>
<
script
>
import
Timeago
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
Timeago
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
import
Url
from
'
./url.vue
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
export
default
{
export
default
{
components
:
{
components
:
{
Timeago
,
Timeago
,
Url
,
},
},
props
:
{
props
:
{
func
:
{
func
:
{
...
@@ -16,13 +19,18 @@ export default {
...
@@ -16,13 +19,18 @@ export default {
return
this
.
func
.
name
;
return
this
.
func
.
name
;
},
},
description
()
{
description
()
{
return
this
.
func
.
description
;
const
desc
=
this
.
func
.
description
.
split
(
'
\n
'
);
if
(
desc
.
length
>
1
)
{
return
desc
[
1
];
}
return
desc
[
0
];
},
},
detailUrl
()
{
detailUrl
()
{
return
this
.
func
.
detail_url
;
return
this
.
func
.
detail_url
;
},
},
environment
()
{
targetUrl
()
{
return
this
.
func
.
environment_scope
;
return
this
.
func
.
url
;
},
},
image
()
{
image
()
{
return
this
.
func
.
image
;
return
this
.
func
.
image
;
...
@@ -31,25 +39,34 @@ export default {
...
@@ -31,25 +39,34 @@ export default {
return
this
.
func
.
created_at
;
return
this
.
func
.
created_at
;
},
},
},
},
methods
:
{
checkClass
(
element
)
{
if
(
element
.
closest
(
'
.no-expand
'
)
===
null
)
{
return
true
;
}
return
false
;
},
openDetails
(
e
)
{
if
(
this
.
checkClass
(
e
.
target
))
{
visitUrl
(
this
.
detailUrl
);
}
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"gl-responsive-table-row"
>
<li
:id=
"name"
class=
"group-row"
>
<div
class=
"table-section section-20 section-wrap"
>
<div
class=
"group-row-contents"
role=
"button"
@
click=
"openDetails"
>
<a
:href=
"detailUrl"
>
{{
name
}}
</a>
<p
class=
"float-right text-right"
>
</div>
<span>
{{
image
}}
</span
<div
class=
"table-section section-10"
>
{{
environment
}}
</div>
><br
/>
<div
class=
"table-section section-40 section-wrap"
>
<timeago
:time=
"timestamp"
/>
<span
class=
"line-break"
>
{{
description
}}
</span>
</p>
<b>
{{
name
}}
</b>
<div
v-for=
"line in description.split('\n')"
:key=
"line"
>
{{
line
}}
</div>
<url
:uri=
"targetUrl"
class=
"prepend-top-8 no-expand"
/>
</div>
</div>
<div
class=
"table-section section-20"
>
{{
image
}}
</div>
</li>
<div
class=
"table-section section-10"
><timeago
:time=
"timestamp"
/></div>
</div>
</
template
>
</
template
>
<
style
>
.line-break
{
white-space
:
pre
;
}
</
style
>
app/assets/javascripts/serverless/components/functions.vue
View file @
c7c5492c
<
script
>
<
script
>
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
FunctionRow
from
'
./function_row.vue
'
;
import
FunctionRow
from
'
./function_row.vue
'
;
import
EnvironmentRow
from
'
./environment_row.vue
'
;
import
EmptyState
from
'
./empty_state.vue
'
;
import
EmptyState
from
'
./empty_state.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
EnvironmentRow
,
FunctionRow
,
FunctionRow
,
EmptyState
,
EmptyState
,
GlSkeletonLoading
,
GlSkeletonLoading
,
},
},
props
:
{
props
:
{
functions
:
{
functions
:
{
type
:
Array
,
type
:
Object
,
required
:
true
,
required
:
true
,
default
:
()
=>
[]
,
default
:
()
=>
({})
,
},
},
installed
:
{
installed
:
{
type
:
Boolean
,
type
:
Boolean
,
...
@@ -45,33 +47,21 @@ export default {
...
@@ -45,33 +47,21 @@ export default {
<section
id=
"serverless-functions"
>
<section
id=
"serverless-functions"
>
<div
v-if=
"installed"
>
<div
v-if=
"installed"
>
<div
v-if=
"hasFunctionData"
>
<div
v-if=
"hasFunctionData"
>
<div
class=
"ci-table js-services-list function-element"
>
<template
v-if=
"loadingData"
>
<div
class=
"gl-responsive-table-row table-row-header"
role=
"row"
>
<div
v-for=
"j in 3"
:key=
"j"
class=
"gl-responsive-table-row"
><gl-skeleton-loading
/></div>
<div
class=
"table-section section-20"
role=
"rowheader"
>
</
template
>
{{
s__
(
'
Serverless|Function
'
)
}}
<
template
v-else
>
</div>
<div
class=
"groups-list-tree-container"
>
<div
class=
"table-section section-10"
role=
"rowheader"
>
<ul
class=
"content-list group-list-tree"
>
{{
s__
(
'
Serverless|Cluster Env
'
)
}}
<environment-row
</div>
v-for=
"(env, index) in functions"
<div
class=
"table-section section-40"
role=
"rowheader"
>
:key=
"index"
{{
s__
(
'
Serverless|Description
'
)
}}
:env=
"env"
</div>
:env-name=
"index"
<div
class=
"table-section section-20"
role=
"rowheader"
>
/>
{{
s__
(
'
Serverless|Runtime
'
)
}}
</ul>
</div>
<div
class=
"table-section section-10"
role=
"rowheader"
>
{{
s__
(
'
Serverless|Last Update
'
)
}}
</div>
</div>
</div>
<template
v-if=
"loadingData"
>
</
template
>
<div
v-for=
"j in 3"
:key=
"j"
class=
"gl-responsive-table-row"
>
<gl-skeleton-loading
/>
</div>
</
template
>
<
template
v-else
>
<function-row
v-for=
"f in functions"
:key=
"f.name"
:func=
"f"
/>
</
template
>
</div>
</div>
</div>
<div
v-else
class=
"empty-state js-empty-state"
>
<div
v-else
class=
"empty-state js-empty-state"
>
<div
class=
"text-content"
>
<div
class=
"text-content"
>
...
@@ -111,16 +101,3 @@ export default {
...
@@ -111,16 +101,3 @@ export default {
<empty-state
v-else
:clusters-path=
"clustersPath"
:help-path=
"helpPath"
/>
<empty-state
v-else
:clusters-path=
"clustersPath"
:help-path=
"helpPath"
/>
</section>
</section>
</template>
</template>
<
style
>
.top-area
{
border-bottom
:
0
;
}
.function-element
{
border-bottom
:
1px
solid
#e5e5e5
;
border-bottom-color
:
rgb
(
229
,
229
,
229
);
border-bottom-style
:
solid
;
border-bottom-width
:
1px
;
}
</
style
>
app/assets/javascripts/serverless/components/url.vue
0 → 100644
View file @
c7c5492c
<
script
>
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
ClipboardButton
from
'
../../vue_shared/components/clipboard_button.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon.vue
'
;
export
default
{
components
:
{
Icon
,
GlButton
,
ClipboardButton
,
},
props
:
{
uri
:
{
type
:
String
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"clipboard-group"
>
<div
class=
"url-text-field label label-monospace"
>
{{
uri
}}
</div>
<clipboard-button
:text=
"uri"
:title=
"s__('ServerlessURL|Copy URL to clipboard')"
class=
"input-group-text js-clipboard-btn"
/>
<gl-button
:href=
"uri"
target=
"_blank"
rel=
"noopener noreferrer nofollow"
class=
"input-group-text btn btn-default"
>
<icon
name=
"external-link"
/>
</gl-button>
</div>
</
template
>
app/assets/javascripts/serverless/stores/serverless_store.js
View file @
c7c5492c
export
default
class
ServerlessStore
{
export
default
class
ServerlessStore
{
constructor
(
knativeInstalled
=
false
,
clustersPath
,
helpPath
)
{
constructor
(
knativeInstalled
=
false
,
clustersPath
,
helpPath
)
{
this
.
state
=
{
this
.
state
=
{
functions
:
[]
,
functions
:
{}
,
hasFunctionData
:
true
,
hasFunctionData
:
true
,
loadingData
:
true
,
loadingData
:
true
,
installed
:
knativeInstalled
,
installed
:
knativeInstalled
,
...
@@ -10,8 +10,13 @@ export default class ServerlessStore {
...
@@ -10,8 +10,13 @@ export default class ServerlessStore {
};
};
}
}
updateFunctionsFromServer
(
functions
=
[])
{
updateFunctionsFromServer
(
upstreamFunctions
=
[])
{
this
.
state
.
functions
=
functions
;
this
.
state
.
functions
=
upstreamFunctions
.
reduce
((
rv
,
func
)
=>
{
const
envs
=
rv
;
envs
[
func
.
environment_scope
]
=
(
rv
[
func
.
environment_scope
]
||
[]).
concat
([
func
]);
return
envs
;
},
{});
}
}
updateLoadingState
(
loadingData
)
{
updateLoadingState
(
loadingData
)
{
...
...
app/assets/stylesheets/pages/serverless.scss
0 → 100644
View file @
c7c5492c
.url-text-field
{
cursor
:
text
;
}
changelogs/unreleased/knative-list.yml
0 → 100644
View file @
c7c5492c
---
title
:
Modified Knative list view to provide more details
merge_request
:
24072
author
:
Chris Baumbauer
type
:
changed
locale/gitlab.pot
View file @
c7c5492c
...
@@ -6360,9 +6360,6 @@ msgstr ""
...
@@ -6360,9 +6360,6 @@ msgstr ""
msgid "Serverless"
msgid "Serverless"
msgstr ""
msgstr ""
msgid "ServerlessDetails|Copy URL to clipboard"
msgstr ""
msgid "ServerlessDetails|Kubernetes Pods"
msgid "ServerlessDetails|Kubernetes Pods"
msgstr ""
msgstr ""
...
@@ -6375,19 +6372,13 @@ msgstr ""
...
@@ -6375,19 +6372,13 @@ msgstr ""
msgid "ServerlessDetails|pods in use"
msgid "ServerlessDetails|pods in use"
msgstr ""
msgstr ""
msgid "Serverless| In order to start using functions as a service, you must first install Knative on your Kubernetes cluster."
msgid "ServerlessURL|Copy URL to clipboard"
msgstr ""
msgid "Serverless|An error occurred while retrieving serverless components"
msgstr ""
msgid "Serverless|Cluster Env"
msgstr ""
msgstr ""
msgid "Serverless|
Description
"
msgid "Serverless|
In order to start using functions as a service, you must first install Knative on your Kubernetes cluster.
"
msgstr ""
msgstr ""
msgid "Serverless|
Function
"
msgid "Serverless|
An error occurred while retrieving serverless components
"
msgstr ""
msgstr ""
msgid "Serverless|Getting started with serverless"
msgid "Serverless|Getting started with serverless"
...
@@ -6399,18 +6390,12 @@ msgstr ""
...
@@ -6399,18 +6390,12 @@ msgstr ""
msgid "Serverless|Install Knative"
msgid "Serverless|Install Knative"
msgstr ""
msgstr ""
msgid "Serverless|Last Update"
msgstr ""
msgid "Serverless|Learn more about Serverless"
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgstr ""
msgid "Serverless|No functions available"
msgid "Serverless|No functions available"
msgstr ""
msgstr ""
msgid "Serverless|Runtime"
msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr ""
msgstr ""
...
...
spec/features/projects/serverless/functions_spec.rb
View file @
c7c5492c
# frozen_string_literal: true
require
'spec_helper'
require
'spec_helper'
describe
'Functions'
,
:js
do
describe
'Functions'
,
:js
do
include
KubernetesHelpers
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
...
@@ -34,11 +38,14 @@ describe 'Functions', :js do
...
@@ -34,11 +38,14 @@ describe 'Functions', :js do
end
end
context
'when the user has a cluster and knative installed and visits the serverless page'
do
context
'when the user has a cluster and knative installed and visits the serverless page'
do
let!
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:service
)
{
cluster
.
platform_kubernetes
}
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
let
(
:project
)
{
knative
.
cluster
.
project
}
let
(
:project
)
{
knative
.
cluster
.
project
}
before
do
before
do
stub_kubeclient_knative_services
stub_kubeclient_service_pods
visit
project_serverless_functions_path
(
project
)
visit
project_serverless_functions_path
(
project
)
end
end
...
...
spec/javascripts/serverless/components/environment_row_spec.js
0 → 100644
View file @
c7c5492c
import
Vue
from
'
vue
'
;
import
environmentRowComponent
from
'
~/serverless/components/environment_row.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
ServerlessStore
from
'
~/serverless/stores/serverless_store
'
;
import
{
mockServerlessFunctions
,
mockServerlessFunctionsDiffEnv
}
from
'
../mock_data
'
;
const
createComponent
=
(
env
,
envName
)
=>
mountComponent
(
Vue
.
extend
(
environmentRowComponent
),
{
env
,
envName
});
describe
(
'
environment row component
'
,
()
=>
{
describe
(
'
default global cluster case
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
store
=
new
ServerlessStore
(
false
,
'
/cluster_path
'
,
'
help_path
'
);
store
.
updateFunctionsFromServer
(
mockServerlessFunctions
);
vm
=
createComponent
(
store
.
state
.
functions
[
'
*
'
],
'
*
'
);
});
it
(
'
has the correct envId
'
,
()
=>
{
expect
(
vm
.
envId
).
toEqual
(
'
env-global
'
);
vm
.
$destroy
();
});
it
(
'
is open by default
'
,
()
=>
{
expect
(
vm
.
isOpenClass
).
toEqual
({
'
is-open
'
:
true
});
vm
.
$destroy
();
});
it
(
'
generates correct output
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
li
'
).
length
).
toEqual
(
2
);
expect
(
vm
.
$el
.
id
).
toEqual
(
'
env-global
'
);
expect
(
vm
.
$el
.
classList
.
contains
(
'
is-open
'
)).
toBe
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
div.title
'
).
innerHTML
.
trim
()).
toEqual
(
'
*
'
);
vm
.
$destroy
();
});
it
(
'
opens and closes correctly
'
,
()
=>
{
expect
(
vm
.
isOpen
).
toBe
(
true
);
vm
.
toggleOpen
();
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
isOpen
).
toBe
(
false
);
});
vm
.
$destroy
();
});
});
describe
(
'
default named cluster case
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
const
store
=
new
ServerlessStore
(
false
,
'
/cluster_path
'
,
'
help_path
'
);
store
.
updateFunctionsFromServer
(
mockServerlessFunctionsDiffEnv
);
vm
=
createComponent
(
store
.
state
.
functions
.
test
,
'
test
'
);
});
it
(
'
has the correct envId
'
,
()
=>
{
expect
(
vm
.
envId
).
toEqual
(
'
env-test
'
);
vm
.
$destroy
();
});
it
(
'
is open by default
'
,
()
=>
{
expect
(
vm
.
isOpenClass
).
toEqual
({
'
is-open
'
:
true
});
vm
.
$destroy
();
});
it
(
'
generates correct output
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelectorAll
(
'
li
'
).
length
).
toEqual
(
1
);
expect
(
vm
.
$el
.
id
).
toEqual
(
'
env-test
'
);
expect
(
vm
.
$el
.
classList
.
contains
(
'
is-open
'
)).
toBe
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
div.title
'
).
innerHTML
.
trim
()).
toEqual
(
'
test
'
);
vm
.
$destroy
();
});
});
});
spec/javascripts/serverless/components/function_row_spec.js
0 → 100644
View file @
c7c5492c
import
Vue
from
'
vue
'
;
import
functionRowComponent
from
'
~/serverless/components/function_row.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
{
mockServerlessFunction
}
from
'
../mock_data
'
;
const
createComponent
=
func
=>
mountComponent
(
Vue
.
extend
(
functionRowComponent
),
{
func
});
describe
(
'
functionRowComponent
'
,
()
=>
{
it
(
'
Parses the function details correctly
'
,
()
=>
{
const
vm
=
createComponent
(
mockServerlessFunction
);
expect
(
vm
.
$el
.
querySelector
(
'
b
'
).
innerHTML
).
toEqual
(
mockServerlessFunction
.
name
);
expect
(
vm
.
$el
.
querySelector
(
'
span
'
).
innerHTML
).
toEqual
(
mockServerlessFunction
.
image
);
expect
(
vm
.
$el
.
querySelector
(
'
time
'
).
getAttribute
(
'
data-original-title
'
)).
not
.
toBe
(
null
);
expect
(
vm
.
$el
.
querySelector
(
'
div.url-text-field
'
).
innerHTML
).
toEqual
(
mockServerlessFunction
.
url
,
);
vm
.
$destroy
();
});
it
(
'
handles clicks correctly
'
,
()
=>
{
const
vm
=
createComponent
(
mockServerlessFunction
);
expect
(
vm
.
checkClass
(
vm
.
$el
.
querySelector
(
'
p
'
))).
toBe
(
true
);
// check somewhere inside the row
expect
(
vm
.
checkClass
(
vm
.
$el
.
querySelector
(
'
svg
'
))).
toBe
(
false
);
// check a button image
expect
(
vm
.
checkClass
(
vm
.
$el
.
querySelector
(
'
div.url-text-field
'
))).
toBe
(
false
);
// check the url bar
vm
.
$destroy
();
});
});
spec/javascripts/serverless/components/functions_spec.js
0 → 100644
View file @
c7c5492c
import
Vue
from
'
vue
'
;
import
functionsComponent
from
'
~/serverless/components/functions.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
import
ServerlessStore
from
'
~/serverless/stores/serverless_store
'
;
import
{
mockServerlessFunctions
}
from
'
../mock_data
'
;
const
createComponent
=
(
functions
,
installed
=
true
,
loadingData
=
true
,
hasFunctionData
=
true
,
)
=>
{
const
component
=
Vue
.
extend
(
functionsComponent
);
return
mountComponent
(
component
,
{
functions
,
installed
,
clustersPath
:
'
/testClusterPath
'
,
helpPath
:
'
/helpPath
'
,
loadingData
,
hasFunctionData
,
});
};
describe
(
'
functionsComponent
'
,
()
=>
{
it
(
'
should render empty state when Knative is not installed
'
,
()
=>
{
const
vm
=
createComponent
({},
false
);
expect
(
vm
.
$el
.
querySelector
(
'
div.row
'
).
classList
.
contains
(
'
js-empty-state
'
)).
toBe
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
h4.state-title
'
).
innerHTML
.
trim
()).
toEqual
(
'
Getting started with serverless
'
,
);
vm
.
$destroy
();
});
it
(
'
should render a loading component
'
,
()
=>
{
const
vm
=
createComponent
({});
expect
(
vm
.
$el
.
querySelector
(
'
.gl-responsive-table-row
'
)).
not
.
toBe
(
null
);
expect
(
vm
.
$el
.
querySelector
(
'
div.animation-container
'
)).
not
.
toBe
(
null
);
});
it
(
'
should render empty state when there is no function data
'
,
()
=>
{
const
vm
=
createComponent
({},
true
,
false
,
false
);
expect
(
vm
.
$el
.
querySelector
(
'
.empty-state, .js-empty-state
'
).
classList
.
contains
(
'
js-empty-state
'
),
).
toBe
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
h4.state-title
'
).
innerHTML
.
trim
()).
toEqual
(
'
No functions available
'
,
);
vm
.
$destroy
();
});
it
(
'
should render the functions list
'
,
()
=>
{
const
store
=
new
ServerlessStore
(
false
,
'
/cluster_path
'
,
'
help_path
'
);
store
.
updateFunctionsFromServer
(
mockServerlessFunctions
);
const
vm
=
createComponent
(
store
.
state
.
functions
,
true
,
false
);
expect
(
vm
.
$el
.
querySelector
(
'
div.groups-list-tree-container
'
)).
not
.
toBe
(
null
);
expect
(
vm
.
$el
.
querySelector
(
'
#env-global
'
).
classList
.
contains
(
'
has-children
'
)).
toBe
(
true
);
});
});
spec/javascripts/serverless/components/url_spec.js
0 → 100644
View file @
c7c5492c
import
Vue
from
'
vue
'
;
import
urlComponent
from
'
~/serverless/components/url.vue
'
;
import
mountComponent
from
'
spec/helpers/vue_mount_component_helper
'
;
const
createComponent
=
uri
=>
{
const
component
=
Vue
.
extend
(
urlComponent
);
return
mountComponent
(
component
,
{
uri
,
});
};
describe
(
'
urlComponent
'
,
()
=>
{
it
(
'
should render correctly
'
,
()
=>
{
const
uri
=
'
http://testfunc.apps.example.com
'
;
const
vm
=
createComponent
(
uri
);
expect
(
vm
.
$el
.
classList
.
contains
(
'
clipboard-group
'
)).
toBe
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
.js-clipboard-btn
'
).
getAttribute
(
'
data-clipboard-text
'
)).
toEqual
(
uri
,
);
expect
(
vm
.
$el
.
querySelector
(
'
.url-text-field
'
).
innerHTML
).
toEqual
(
uri
);
vm
.
$destroy
();
});
});
spec/javascripts/serverless/mock_data.js
0 → 100644
View file @
c7c5492c
export
const
mockServerlessFunctions
=
[
{
name
:
'
testfunc1
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
*
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc1
'
,
podcount
:
null
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc1.tm-example.apps.example.com
'
,
description
:
'
A test service
'
,
image
:
'
knative-test-container-buildtemplate
'
,
},
{
name
:
'
testfunc2
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
*
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc2
'
,
podcount
:
null
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc2.tm-example.apps.example.com
'
,
description
:
'
A second test service
\n
This one with additional descriptions
'
,
image
:
'
knative-test-echo-buildtemplate
'
,
},
];
export
const
mockServerlessFunctionsDiffEnv
=
[
{
name
:
'
testfunc1
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
*
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc1
'
,
podcount
:
null
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc1.tm-example.apps.example.com
'
,
description
:
'
A test service
'
,
image
:
'
knative-test-container-buildtemplate
'
,
},
{
name
:
'
testfunc2
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
test
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc2
'
,
podcount
:
null
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc2.tm-example.apps.example.com
'
,
description
:
'
A second test service
\n
This one with additional descriptions
'
,
image
:
'
knative-test-echo-buildtemplate
'
,
},
];
export
const
mockServerlessFunction
=
{
name
:
'
testfunc1
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
*
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc1
'
,
podcount
:
'
3
'
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc1.tm-example.apps.example.com
'
,
description
:
'
A test service
'
,
image
:
'
knative-test-container-buildtemplate
'
,
};
export
const
mockMultilineServerlessFunction
=
{
name
:
'
testfunc1
'
,
namespace
:
'
tm-example
'
,
environment_scope
:
'
*
'
,
cluster_id
:
46
,
detail_url
:
'
/testuser/testproj/serverless/functions/*/testfunc1
'
,
podcount
:
'
3
'
,
created_at
:
'
2019-02-05T01:01:23Z
'
,
url
:
'
http://testfunc1.tm-example.apps.example.com
'
,
description
:
'
testfunc1
\n
A test service line
\\
nWith additional services
'
,
image
:
'
knative-test-container-buildtemplate
'
,
};
spec/javascripts/serverless/stores/serverless_store_spec.js
0 → 100644
View file @
c7c5492c
import
ServerlessStore
from
'
~/serverless/stores/serverless_store
'
;
import
{
mockServerlessFunctions
,
mockServerlessFunctionsDiffEnv
}
from
'
../mock_data
'
;
describe
(
'
Serverless Functions Store
'
,
()
=>
{
let
store
;
beforeEach
(()
=>
{
store
=
new
ServerlessStore
(
false
,
'
/cluster_path
'
,
'
help_path
'
);
});
describe
(
'
#updateFunctionsFromServer
'
,
()
=>
{
it
(
'
should pass an empty hash object
'
,
()
=>
{
store
.
updateFunctionsFromServer
();
expect
(
store
.
state
.
functions
).
toEqual
({});
});
it
(
'
should group functions to one global environment
'
,
()
=>
{
const
mockServerlessData
=
mockServerlessFunctions
;
store
.
updateFunctionsFromServer
(
mockServerlessData
);
expect
(
Object
.
keys
(
store
.
state
.
functions
)).
toEqual
(
jasmine
.
objectContaining
([
'
*
'
]));
expect
(
store
.
state
.
functions
[
'
*
'
].
length
).
toEqual
(
2
);
});
it
(
'
should group functions to multiple environments
'
,
()
=>
{
const
mockServerlessData
=
mockServerlessFunctionsDiffEnv
;
store
.
updateFunctionsFromServer
(
mockServerlessData
);
expect
(
Object
.
keys
(
store
.
state
.
functions
)).
toEqual
(
jasmine
.
objectContaining
([
'
*
'
]));
expect
(
store
.
state
.
functions
[
'
*
'
].
length
).
toEqual
(
1
);
expect
(
store
.
state
.
functions
.
test
.
length
).
toEqual
(
1
);
expect
(
store
.
state
.
functions
.
test
[
0
].
name
).
toEqual
(
'
testfunc2
'
);
});
});
});
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