diff --git a/packages/components/src/components/Trigger/Trigger.js b/packages/components/src/components/Trigger/Trigger.js index e65a262d07..a8a1673bc2 100644 --- a/packages/components/src/components/Trigger/Trigger.js +++ b/packages/components/src/components/Trigger/Trigger.js @@ -11,14 +11,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Launch16 as LinkIcon } from '@carbon/icons-react'; import { injectIntl } from 'react-intl'; import React from 'react'; import { urls } from '@tektoncd/dashboard-utils'; import { Link } from 'react-router-dom'; -import './Trigger.scss'; +import { Accordion, AccordionItem } from 'carbon-components-react'; import { Table } from '@tektoncd/dashboard-components'; +import './Trigger.scss'; + const Trigger = ({ intl, eventListenerNamespace, trigger }) => { const tableHeaders = [ { @@ -37,120 +38,217 @@ const Trigger = ({ intl, eventListenerNamespace, trigger }) => { } ]; - let triggerParams = []; - - if (trigger.params) { - triggerParams = trigger.params.map(param => ({ - id: param.name, - name: param.name, - value: param.value - })); - } - - let interceptorValues = []; - - if (trigger.interceptor) { - if (trigger.interceptor.header) { - interceptorValues = trigger.interceptor.header.map(header => ({ - id: header.name, - name: header.name, - value: header.value - })); - } - } - return ( <> -
-

Trigger: {trigger.name}

+

Trigger: {trigger.name}

+
- TriggerBinding - - - - - - {trigger.binding.name} - - + TriggerBindings: +
+ {trigger.bindings && + trigger.bindings.map((binding, index) => ( + + + {binding.name} + + {index !== trigger.bindings.length - 1 && , } + + ))} +
- TriggerTemplate + TriggerTemplate: - - - - - {trigger.template.name} - + {trigger.template.name}
+
-
-

- {intl.formatMessage({ - id: 'dashboard.parameters.title', - defaultMessage: 'Parameters' - })} -

- - - {trigger.interceptor && ( - <> -
-

- {intl.formatMessage({ - id: 'dashboard.triggerDetails.interceptorName', - defaultMessage: 'Interceptor: ' - })} - {trigger.interceptor.objectRef.name} -

-

- {intl.formatMessage({ - id: 'dashboard.triggerDetails.interceptorHeaders', - defaultMessage: 'Headers' - })} -

-
-
- - )} - +
+ {trigger.interceptors && trigger.interceptors.length !== 0 && ( + <> + + {intl.formatMessage({ + id: 'dashboard.triggerDetails.interceptors', + defaultMessage: 'Interceptors:' + })} + + + {trigger.interceptors.map((interceptor, index) => { + let interceptorName; + let interceptorType; + let content; + const namespaceText = intl.formatMessage({ + id: 'dashboard.triggerDetails.interceptorNamespace', + defaultMessage: 'Namespace:' + }); + const nameText = intl.formatMessage({ + id: 'dashboard.triggerDetails.interceptorName', + defaultMessage: 'Name:' + }); + if (interceptor.webhook) { + // Webhook Interceptor + if (!interceptor.webhook.objectRef) { + return null; + } + interceptorType = 'Webhook'; + interceptorName = interceptor.webhook.objectRef.name; + let headerValues = []; + if (interceptor.webhook.header) { + headerValues = interceptor.webhook.header.map(header => { + const headerValue = { + id: header.name, + name: header.name, + value: header.value + }; + // Concatenate values with a comma if value is an array + if (Array.isArray(header.value)) { + headerValue.value = header.value.join(', '); + } + return headerValue; + }); + } + const serviceText = intl.formatMessage({ + id: 'dashboard.triggerDetails.webhookInterceptorService', + defaultMessage: 'Service:' + }); + content = ( + <> +

{serviceText}

+
+

+ {nameText} {interceptor.webhook.objectRef.name} +

+ {interceptor.webhook.objectRef.namespace && ( +

+ {namespaceText}{' '} + {interceptor.webhook.objectRef.namespace} +

+ )} +
+ {headerValues.length !== 0 && ( + <> +

+ {intl.formatMessage({ + id: 'dashboard.triggerDetails.interceptorHeader', + defaultMessage: 'Header:' + })} +

+
+ + )} + + ); + } else if (interceptor.github || interceptor.gitlab) { + let data; + if (interceptor.github) { + // GitHub Interceptor + interceptorType = 'GitHub'; + data = interceptor.github; + } else { + // GitLab Interceptor + interceptorType = 'GitLab'; + data = interceptor.gitlab; + } + const eventTypes = data.eventTypes.join(', '); + interceptorName = eventTypes; + const secretText = intl.formatMessage({ + id: 'dashboard.triggerDetails.webhookInterceptorSecret', + defaultMessage: 'Secret:' + }); + const secretKeyText = intl.formatMessage({ + id: 'dashboard.triggerDetails.webhookInterceptorSecretKey', + defaultMessage: 'Key:' + }); + content = ( + <> +

{secretText}

+
+

+ {nameText} {data.secretRef.secretName} +

+

+ {secretKeyText} {data.secretRef.secretKey} +

+ {data.secretRef.namespace && ( +

+ {namespaceText} {data.secretRef.namespace} +

+ )} +
+

Event Types: {eventTypes}

+ + ); + } else if (interceptor.cel) { + // CEL Interceptor + interceptorType = 'CEL'; + interceptorName = interceptor.cel.filter; + const filter = intl.formatMessage({ + id: 'dashboard.triggerDetails.celInterceptorFilter', + defaultMessage: 'Filter: ' + }); + content = ( + <> +

{filter}

+ + {interceptor.cel.filter} + + + ); + } else { + return null; + } + const title = intl.formatMessage( + { + id: 'dashboard.triggerDetails.interceptorTitle', + defaultMessage: + '{interceptorNumber}. ({interceptorType}) {interceptorName}' + }, + { + interceptorNumber: index + 1, + interceptorType, + interceptorName + } + ); + return ( + + {content} + + ); + })} + + + )} ); diff --git a/packages/components/src/components/Trigger/Trigger.scss b/packages/components/src/components/Trigger/Trigger.scss index 7845f9800d..98395d508b 100644 --- a/packages/components/src/components/Trigger/Trigger.scss +++ b/packages/components/src/components/Trigger/Trigger.scss @@ -13,48 +13,43 @@ limitations under the License. @import '~carbon-components/scss/globals/scss/vars'; -.triggermain { - padding: 25px; - padding-left: 0px; - margin-bottom: 20px; - border-bottom: 0.5px dotted grey; -} +.trigger--interceptors { + margin-top: $spacing-05; -.interceptor h3 { - margin: 5px; - padding: 10px; + .trigger--interceptors-accordian { + margin-top: $spacing-03; + } } -.triggerinfo h3 { - margin: 5px; - padding: 10px; +.triggerdetails { + margin-top: $spacing-05; } .triggerresourcelinks { - margin: 10px; - padding: 10px; display: grid; - grid-template-columns: 100px 500px 100px; + margin-top: $spacing-03; + grid-template-columns: 100px 500px; grid-gap: 30px; - - .linkicon { - margin-right: 1rem; - } + line-height: 1.5rem; .resourcekind { - font-weight: bold; + font-weight: auto; } - - a { - display: flex; - overflow: hidden; - white-space: nowrap; + + .triggerresourcelink { + display: inline-block; + overflow: visible; } } -.truncate-text-end { +.interceptor--cel-filter { display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +} + +.interceptor--secret-details { + margin-left: $spacing-04; +} + +.interceptor--service-details { + margin-left: $spacing-04; } diff --git a/packages/components/src/components/Trigger/Trigger.stories.js b/packages/components/src/components/Trigger/Trigger.stories.js new file mode 100644 index 0000000000..4c1461ea8e --- /dev/null +++ b/packages/components/src/components/Trigger/Trigger.stories.js @@ -0,0 +1,91 @@ +/* +Copyright 2019 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import { storiesOf } from '@storybook/react'; + +import { Router } from 'react-router-dom'; +import { IntlProvider } from 'react-intl'; +import { createMemoryHistory } from 'history'; +import Trigger from './Trigger'; + +const route = '/'; +const history = createMemoryHistory({ initialEntries: [route] }); +const trigger = { + eventListenerNamespace: 'default', + trigger: { + name: 'my-trigger', + bindings: [ + { name: 'triggerbinding0' }, + { name: 'triggerbinding1' }, + { name: 'triggerbinding2' } + ], + template: { + name: 'triggertemplate' + }, + interceptors: [ + { + webhook: { + header: [ + { + name: 'header0', + value: 'value0' + }, + { + name: 'header1', + value: ['value1-0', 'value1-1', 'value1-2'] + } + ], + objectRef: { + apiVersion: 'v1', + kind: 'Service', + name: 'interceptor-service0', + namespace: 'foo' + } + } + }, + { + github: { + secretRef: { + secretName: 'github-secret', + secretKey: 'secret' + }, + eventTypes: ['push', 'pull_request'] + } + }, + { + gitlab: { + secretRef: { + secretName: 'gitlab-secret', + secretKey: 'secret', + namespace: 'foo' + }, + eventTypes: ['Push Hook'] + } + }, + { + cel: { + filter: "body.matches('foo', 'bar')" + } + } + ] + } +}; + +storiesOf('Trigger', module).add('default', () => ( + + + + + +)); diff --git a/packages/components/src/components/Trigger/Trigger.test.js b/packages/components/src/components/Trigger/Trigger.test.js index fc7776130e..2f5f46f702 100644 --- a/packages/components/src/components/Trigger/Trigger.test.js +++ b/packages/components/src/components/Trigger/Trigger.test.js @@ -16,131 +16,210 @@ import Trigger from './Trigger'; import { renderWithRouter } from '../../utils/test'; const fakeTrigger = { - binding: { - apiversion: 'v1alpha1', - name: 'simple-pipeline-push-binding' - }, - interceptor: { - header: [ - { - name: 'Wext-Trigger-Name', - value: 'mytrigger-tekton-pipelines-push-event' - }, - { - name: 'Wext-Repository-Url', - value: 'https://github.com/myorg/myrepo' - }, - { - name: 'Wext-Incoming-Event', - value: 'push' - }, - { - name: 'Wext-Secret-Name', - value: 'mytoken' - } - ], - objectRef: { - apiVersion: 'v1', - kind: 'Service', - name: 'tekton-webhooks-extension-validator', - namespace: 'tekton-pipelines' - } - }, - name: 'mytrigger-tekton-pipelines-push-event', - params: [ + name: 'my-fake-trigger', + bindings: [ { - name: 'webhooks-tekton-release-name', - value: 'myreleasename' + apiversion: 'v1alpha1', + name: 'triggerbinding-0' }, { - name: 'webhooks-tekton-target-namespace', - value: 'tekton-pipelines' + apiversion: 'v1alpha1', + name: 'triggerbinding-1' }, { - name: 'webhooks-tekton-service-account', - value: 'tekton-dashboard' - }, + apiversion: 'v1alpha1', + name: 'triggerbinding-2' + } + ], + template: { + apiversion: 'v1alpha1', + name: 'simple-pipeline-template' + }, + interceptors: [ { - name: 'webhooks-tekton-git-server', - value: 'github.com' + webhook: { + header: [ + { + name: 'Wext-Repository-Url', + value: 'https://github.com/myorg/myrepo' + }, + { + name: 'Wext-Incoming-Event', + value: 'wext-incoming-event-value' + }, + { + name: 'Wext-Secret-Name', + value: 'wext-secret-name-value' + }, + { + name: 'Array-Header-Name', + value: [ + 'array-header-value-0', + 'array-header-value-1', + 'array-header-value-2' + ] + } + ], + objectRef: { + apiVersion: 'v1', + kind: 'Service', + name: 'webhook-service-name', + namespace: 'webhook-service-namespace' + } + } }, { - name: 'webhooks-tekton-git-org', - value: 'myorg' + github: { + secretRef: { + secretName: 'my-github-secret', + secretKey: 'github-secret-key', + namespace: 'github-secret-namespace' + }, + eventTypes: ['github-event-0', 'github-event-1', 'github-event-2'] + } }, { - name: 'webhooks-tekton-git-repo', - value: 'myrepo' + gitlab: { + secretRef: { + secretName: 'my-gitlab-secret', + secretKey: 'gitlab-secret-key', + namespace: 'gitlab-secret-namespace' + }, + eventTypes: ['gitlab-event-0', 'gitlab-event-1', 'gitlab-event-2'] + } }, { - name: 'webhooks-tekton-docker-registry', - value: 'myregistry' + cel: { + filter: 'cel-filter' + } } - ], - template: { - apiversion: 'v1alpha1', - name: 'simple-pipeline-template' - } + ] }; describe('Trigger', () => { - it('should render all details', () => { + it('renders all details', () => { const props = { eventListenerNamespace: 'tekton-pipelines', trigger: fakeTrigger }; const { queryByText } = renderWithRouter(); expect(queryByText(/Name/i)).toBeTruthy(); + expect(queryByText(/my-fake-trigger/i)).toBeTruthy(); expect(queryByText(/TriggerBinding/i)).toBeTruthy(); + expect(queryByText(/triggerbinding-0/i)).toBeTruthy(); + expect(queryByText(/triggerbinding-1/i)).toBeTruthy(); + expect(queryByText(/triggerbinding-2/i)).toBeTruthy(); expect(queryByText(/TriggerTemplate/i)).toBeTruthy(); - expect(queryByText(/Interceptor/i)).toBeTruthy(); - expect(queryByText(/Headers/i)).toBeTruthy(); - expect(queryByText(/Parameters/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-release-name/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-target-namespace/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-service-account/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-git-server/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-git-org/i)).toBeTruthy(); - expect(queryByText(/webhooks-tekton-git-repo/i)).toBeTruthy(); - expect(queryByText(/mytrigger-tekton-pipelines-push-event/i)).toBeTruthy(); - expect(queryByText(/myreleasename/i)).toBeTruthy(); - expect(queryByText(/tekton-pipelines/i)).toBeTruthy(); - expect(queryByText(/myregistry/i)).toBeTruthy(); - expect(queryByText(/myrepo/i)).toBeTruthy(); - expect(queryByText(/myorg/i)).toBeTruthy(); - expect(queryByText(/github.com/i)).toBeTruthy(); expect(queryByText(/simple-pipeline-template/i)).toBeTruthy(); - expect(queryByText(/Wext-Trigger-Name/i)).toBeTruthy(); + expect(queryByText(/Interceptors/i)).toBeTruthy(); + // Check Webhook Interceptor + expect(queryByText(/(webhook)/i)).toBeTruthy(); + expect(queryByText(/webhook-service-name/i)).toBeTruthy(); + expect(queryByText(/Header/i)).toBeTruthy(); + expect(queryByText(/webhook-service-namespace/i)).toBeTruthy(); expect(queryByText(/Wext-Repository-Url/i)).toBeTruthy(); + expect(queryByText(/https:\/\/github.com\/myorg\/myrepo/i)).toBeTruthy(); expect(queryByText(/Wext-Incoming-Event/i)).toBeTruthy(); + expect(queryByText(/wext-incoming-event-value/i)).toBeTruthy(); expect(queryByText(/Wext-Secret-Name/i)).toBeTruthy(); + expect(queryByText(/wext-secret-name-value/i)).toBeTruthy(); + expect(queryByText(/Array-Header-Name/i)).toBeTruthy(); + expect(queryByText(/array-header-value-0/i)).toBeTruthy(); + expect(queryByText(/array-header-value-1/i)).toBeTruthy(); + expect(queryByText(/array-header-value-2/i)).toBeTruthy(); + // Check GitHub Interceptor + expect(queryByText(/(github)/i)).toBeTruthy(); + expect(queryByText(/my-github-secret/i)).toBeTruthy(); + expect(queryByText(/github-secret-key/i)).toBeTruthy(); + expect(queryByText(/github-secret-namespace/i)).toBeTruthy(); + expect(queryByText(/github-event-0/i)).toBeTruthy(); + expect(queryByText(/github-event-1/i)).toBeTruthy(); + expect(queryByText(/github-event-2/i)).toBeTruthy(); + // Check GitLab Interceptor + expect(queryByText(/(gitlab)/i)).toBeTruthy(); + expect(queryByText(/my-gitlab-secret/i)).toBeTruthy(); + expect(queryByText(/gitlab-secret-key/i)).toBeTruthy(); + expect(queryByText(/gitlab-secret-namespace/i)).toBeTruthy(); + expect(queryByText(/gitlab-event-0/i)).toBeTruthy(); + expect(queryByText(/gitlab-event-1/i)).toBeTruthy(); + expect(queryByText(/gitlab-event-2/i)).toBeTruthy(); + // Check CEL Interceptor + expect(queryByText(/(cel)/i)).toBeTruthy(); + expect(queryByText(/cel-filter/i)).toBeTruthy(); }); - it('should handle missing params and interceptor', () => { + it('handles no objectRef in webhook Interceptor', () => { const props = { eventListenerNamespace: 'tekton-pipelines', trigger: { ...fakeTrigger, - params: undefined, - interceptor: undefined + interceptors: [ + { + webhook: {} + } + ] } }; const { queryByText } = renderWithRouter(); - expect(queryByText(/Name/i)).toBeTruthy(); + expect(queryByText(/1./i)).toBeFalsy(); }); - it('should handle missing interceptor headers', () => { + it('handles empty Interceptor', () => { const props = { eventListenerNamespace: 'tekton-pipelines', trigger: { ...fakeTrigger, - interceptor: { - ...fakeTrigger.interceptor, - header: undefined - } + interceptors: [{}] + } + }; + const { queryByText } = renderWithRouter(); + expect(queryByText(/Interceptors/i)).toBeTruthy(); + }); + + it('handles no Interceptors', () => { + const props = { + eventListenerNamespace: 'tekton-pipelines', + trigger: { + ...fakeTrigger, + interceptors: [] + } + }; + const { queryByText } = renderWithRouter(); + expect(queryByText(/Interceptors/i)).toBeFalsy(); + }); + + it('handles missing Interceptors', () => { + const props = { + eventListenerNamespace: 'tekton-pipelines', + trigger: { + ...fakeTrigger, + interceptors: undefined + } + }; + const { queryByText } = renderWithRouter(); + expect(queryByText(/Interceptors/i)).toBeFalsy(); + }); + + it('handles webhook Interceptor without Header', () => { + const props = { + eventListenerNamespace: 'tekton-pipelines', + trigger: { + ...fakeTrigger, + interceptors: [ + { + webhook: { + objectRef: { + apiVersion: 'v1', + kind: 'Service', + name: 'webhook-service-name', + namespace: 'webhook-service-namespace' + } + } + } + ] } }; const { queryByText } = renderWithRouter(); - expect(queryByText(/Interceptor/i)).toBeTruthy(); + expect(queryByText(/Header/i)).toBeFalsy(); }); }); diff --git a/src/containers/EventListener/EventListener.js b/src/containers/EventListener/EventListener.js index 50aab07282..93e45154b3 100644 --- a/src/containers/EventListener/EventListener.js +++ b/src/containers/EventListener/EventListener.js @@ -14,10 +14,8 @@ limitations under the License. import React, { Component } from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; -import '../../scss/Triggers.scss'; import { injectIntl } from 'react-intl'; import { InlineNotification, Tag } from 'carbon-components-react'; - import { formatLabels } from '@tektoncd/dashboard-utils'; import { FormattedDate, @@ -32,9 +30,11 @@ import { getSelectedNamespace, isWebSocketConnected } from '../../reducers'; - import { fetchEventListener } from '../../actions/eventListeners'; +import '../../scss/Triggers.scss'; +import './EventListener.scss'; + export /* istanbul ignore next */ class EventListenerContainer extends Component { static notification({ kind, message, intl }) { const titles = { @@ -129,54 +129,71 @@ export /* istanbul ignore next */ class EventListenerContainer extends Component })} >
-

- - {intl.formatMessage({ - id: 'dashboard.metadata.dateCreated', - defaultMessage: 'Date Created:' - })} - - -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.labels', - defaultMessage: 'Labels:' - })} - - {formattedLabelsToRender.length === 0 - ? intl.formatMessage({ - id: 'dashboard.metadata.none', - defaultMessage: 'None' - }) - : formattedLabelsToRender.map(label => ( - - {label} - - ))} -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.namespace', - defaultMessage: 'Namespace:' - })} - - {eventListener.metadata.namespace} -

- {triggers.map(trigger => { - return ( - +

+ + {intl.formatMessage({ + id: 'dashboard.metadata.dateCreated', + defaultMessage: 'Date Created:' + })}{' '} + + - ); - })} +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.labels', + defaultMessage: 'Labels:' + })}{' '} + + {formattedLabelsToRender.length === 0 + ? intl.formatMessage({ + id: 'dashboard.metadata.none', + defaultMessage: 'None' + }) + : formattedLabelsToRender.map(label => ( + + {label} + + ))} +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.namespace', + defaultMessage: 'Namespace:' + })}{' '} + + {eventListener.metadata.namespace} +

+ {eventListener.spec.serviceAccountName && ( +

+ + {intl.formatMessage({ + id: 'dashboard.metadata.serviceAccount', + defaultMessage: 'Service Account:' + })}{' '} + + {eventListener.spec.serviceAccountName} +

+ )} +
+
+ {triggers.map((trigger, idx) => ( +
+ +
+ ))} +
diff --git a/src/containers/EventListener/EventListener.scss b/src/containers/EventListener/EventListener.scss new file mode 100644 index 0000000000..3f8ca53f02 --- /dev/null +++ b/src/containers/EventListener/EventListener.scss @@ -0,0 +1,24 @@ +/* +Copyright 2019 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +@import '~carbon-components/scss/globals/scss/vars'; + +.eventlistener--triggers { + margin-top: $layout-02; +} + +.eventlistener--detail-block { + margin-bottom: $layout-01; + padding: $layout-01; + background-color: $ui-02; +} diff --git a/src/containers/EventListener/EventListener.stories.js b/src/containers/EventListener/EventListener.stories.js new file mode 100644 index 0000000000..0313f01549 --- /dev/null +++ b/src/containers/EventListener/EventListener.stories.js @@ -0,0 +1,151 @@ +/* +Copyright 2019 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; +import { storiesOf } from '@storybook/react'; + +import { Router } from 'react-router-dom'; +import { createIntl, IntlProvider } from 'react-intl'; +import { createMemoryHistory } from 'history'; +import { EventListenerContainer } from './EventListener'; + +const route = '/'; +const history = createMemoryHistory({ initialEntries: [route] }); +const eventListener = { + apiVersion: 'tekton.dev/v1alpha1', + kind: 'EventListener', + metadata: { + name: 'my-eventlistener', + namespace: 'foo', + creationTimestamp: '2020-01-31T16:39:21Z', + labels: { + foo: 'bar', + bar: 'baz' + } + }, + spec: { + serviceAccountName: 'my-serviceaccount', + triggers: [ + { + eventListenerNamespace: 'default', + name: 'my-trigger', + bindings: [ + { name: 'triggerbinding0' }, + { name: 'triggerbinding1' }, + { name: 'triggerbinding2' } + ], + template: { + name: 'triggertemplate' + }, + interceptors: [ + { + webhook: { + header: [ + { + name: 'header0', + value: 'value0' + }, + { + name: 'header1', + value: ['value1-0', 'value1-1', 'value1-2'] + } + ], + objectRef: { + apiVersion: 'v1', + kind: 'Service', + name: 'interceptor-service0', + namespace: 'foo' + } + } + } + ] + }, + { + eventListenerNamespace: 'foo', + name: 'my-trigger-1', + bindings: [{ name: 'triggerbinding1' }], + template: { + name: 'triggertemplate1' + }, + interceptors: [ + { + gitlab: { + secretRef: { + secretName: 'gitlab-secret', + secretKey: 'secret', + namespace: 'foo' + }, + eventTypes: ['Push Hook'] + } + }, + { + cel: { + filter: "body.matches('foo', 'bar')" + } + } + ] + }, + { + eventListenerNamespace: 'foo', + name: 'my-trigger-2', + bindings: [{ name: 'triggerbinding2' }], + template: { + name: 'triggertemplate2' + }, + interceptors: [ + { + github: { + secretRef: { + secretName: 'github-secret', + secretKey: 'secret' + }, + eventTypes: ['push', 'pull_request'] + } + } + ] + }, + { + eventListenerNamespace: 'foo', + name: 'my-trigger-3', + bindings: [{ name: 'triggerbinding3' }], + template: { + name: 'triggertemplate3' + }, + interceptors: [] + } + ] + } +}; +const match = { + params: { + eventListenerName: 'my-eventlistener' + } +}; +const intl = createIntl({ + locale: 'en', + defaultLocale: 'en' +}); +const props = { + fetchEventListener: () => Promise.resolve(eventListener), + eventListener, + match, + intl +}; + +storiesOf('EventListenerContainer', module).add('default', () => ( + + + + + +)); diff --git a/src/containers/EventListener/EventListener.test.js b/src/containers/EventListener/EventListener.test.js index 18fa9ccea6..a917d744ab 100644 --- a/src/containers/EventListener/EventListener.test.js +++ b/src/containers/EventListener/EventListener.test.js @@ -40,42 +40,61 @@ const fakeEventListenerWithLabels = { } }, spec: { + serviceAccountName: 'my-serviceaccount', triggers: [ { - binding: { + name: 'my-trigger-0', + bindings: [ + { + apiversion: 'v1alpha1', + name: 'my-triggerbinding-0' + } + ], + template: { apiversion: 'v1alpha1', - name: 'simple-pipeline-push-binding' + name: 'my-triggertemplate-0' }, + interceptors: [ + { + cel: { filter: 'cel-filter-0' } + } + ] + }, + { + name: 'my-trigger-1', + bindings: [ + { + apiversion: 'v1alpha1', + name: 'my-triggerbinding-1' + } + ], + template: { + apiversion: 'v1alpha1', + name: 'my-triggertemplate-1' + }, + interceptors: [ + { + cel: { filter: 'cel-filter-1' } + } + ] + }, + { + name: 'my-trigger-2', + bindings: [ + { + apiversion: 'v1alpha1', + name: 'my-triggerbinding-2' + } + ], template: { apiversion: 'v1alpha1', - name: 'simple-pipeline-template' + name: 'my-triggertemplate-2' }, - interceptor: { - header: [ - { - name: 'Wext-Trigger-Name', - value: 'mywebhook1-tekton-pipelines-push-event' - }, - { - name: 'Wext-Repository-Url', - value: 'https://github.com/myorg/myrepo' - }, - { - name: 'Wext-Incoming-Event', - value: 'push' - }, - { - name: 'Wext-Secret-Name', - value: 'mytoken' - } - ], - objectRef: { - apiVersion: 'v1', - kind: 'Service', - name: 'tekton-webhooks-extension-validator', - namespace: 'tekton-pipelines' + interceptors: [ + { + cel: { filter: 'cel-filter-2' } } - } + ] } ] } @@ -103,7 +122,7 @@ it('EventListener displays with formatted labels', async () => { } }); - const { getByText } = renderWithRouter( + const { queryByText, getByText } = renderWithRouter( { ); await waitForElement(() => getByText('event-listener-with-labels')); + expect(queryByText(/foo: bar/i)).toBeTruthy(); + expect(queryByText(/bar: baz/i)).toBeTruthy(); + expect(queryByText(/my-serviceaccount/i)).toBeTruthy(); + // Check Trigger 0 + expect(queryByText(/my-trigger-0/i)).toBeTruthy(); + expect(queryByText(/my-triggerbinding-0/i)).toBeTruthy(); + expect(queryByText(/my-triggertemplate-0/i)).toBeTruthy(); + expect(queryByText(/cel-filter-0/i)).toBeTruthy(); + // Check Trigger 1 + expect(queryByText(/my-trigger-1/i)).toBeTruthy(); + expect(queryByText(/my-triggerbinding-1/i)).toBeTruthy(); + expect(queryByText(/my-triggertemplate-1/i)).toBeTruthy(); + expect(queryByText(/cel-filter-1/i)).toBeTruthy(); + // Check Trigger 2 + expect(queryByText(/my-trigger-2/i)).toBeTruthy(); + expect(queryByText(/my-triggerbinding-2/i)).toBeTruthy(); + expect(queryByText(/my-triggertemplate-2/i)).toBeTruthy(); + expect(queryByText(/cel-filter-2/i)).toBeTruthy(); }); diff --git a/src/containers/TriggerBinding/TriggerBinding.js b/src/containers/TriggerBinding/TriggerBinding.js index 0a3a2304ae..bf67f85cb9 100644 --- a/src/containers/TriggerBinding/TriggerBinding.js +++ b/src/containers/TriggerBinding/TriggerBinding.js @@ -157,45 +157,47 @@ export /* istanbul ignore next */ class TriggerBindingContainer extends Componen })} >
-

- - {intl.formatMessage({ - id: 'dashboard.metadata.dateCreated', - defaultMessage: 'Date Created:' - })} - - -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.labels', - defaultMessage: 'Labels:' - })} - - {formattedLabelsToRender.length === 0 - ? intl.formatMessage({ - id: 'dashboard.metadata.none', - defaultMessage: 'None' - }) - : formattedLabelsToRender.map(label => ( - - {label} - - ))} -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.namespace', - defaultMessage: 'Namespace:' - })} - - {triggerBinding.metadata.namespace} -

+
+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.dateCreated', + defaultMessage: 'Date Created:' + })} + + +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.labels', + defaultMessage: 'Labels:' + })} + + {formattedLabelsToRender.length === 0 + ? intl.formatMessage({ + id: 'dashboard.metadata.none', + defaultMessage: 'None' + }) + : formattedLabelsToRender.map(label => ( + + {label} + + ))} +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.namespace', + defaultMessage: 'Namespace:' + })} + + {triggerBinding.metadata.namespace} +

+
-

- - {intl.formatMessage({ - id: 'dashboard.metadata.dateCreated', - defaultMessage: 'Date Created:' - })} - - -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.labels', - defaultMessage: 'Labels:' - })} - - {formattedLabelsToRender.length === 0 - ? intl.formatMessage({ - id: 'dashboard.metadata.none', - defaultMessage: 'None' - }) - : formattedLabelsToRender.map(label => ( - - {label} - - ))} -

-

- - {intl.formatMessage({ - id: 'dashboard.metadata.namespace', - defaultMessage: 'Namespace:' - })} - - {triggerTemplate.metadata.namespace} -

+
+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.dateCreated', + defaultMessage: 'Date Created:' + })} + + +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.labels', + defaultMessage: 'Labels:' + })} + + {formattedLabelsToRender.length === 0 + ? intl.formatMessage({ + id: 'dashboard.metadata.none', + defaultMessage: 'None' + }) + : formattedLabelsToRender.map(label => ( + + {label} + + ))} +

+

+ + {intl.formatMessage({ + id: 'dashboard.metadata.namespace', + defaultMessage: 'Namespace:' + })} + + {triggerTemplate.metadata.namespace} +

+