@spinnaker/core 2026.0.2 → 2026.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/ci/igor.service.d.ts +0 -1
  2. package/dist/domain/ITrigger.d.ts +1 -11
  3. package/dist/index.js +36 -36
  4. package/dist/index.js.map +1 -1
  5. package/dist/managed/graphql/client.d.ts +1 -1
  6. package/dist/managed/graphql/graphql-sdk.d.ts +9 -9
  7. package/dist/pipeline/config/stages/bakeManifest/ManifestRenderers.d.ts +2 -2
  8. package/dist/pipeline/config/triggers/Triggers.d.ts +1 -0
  9. package/dist/pipeline/config/triggers/index.d.ts +0 -1
  10. package/package.json +3 -3
  11. package/src/application/search/react-ultimate-pagination.d.ts +1 -1
  12. package/src/ci/igor.service.ts +0 -1
  13. package/src/domain/ITrigger.ts +1 -13
  14. package/src/help/help.contents.ts +1 -9
  15. package/src/pipeline/config/pipelineConfigView.html +1 -0
  16. package/src/pipeline/config/stages/bakeManifest/ManifestRenderers.ts +2 -2
  17. package/src/pipeline/config/stages/createLoadBalancer/createLoadBalancerStage.js +45 -28
  18. package/src/pipeline/config/stages/createLoadBalancer/createLoadBalancerStage.spec.js +101 -0
  19. package/src/pipeline/config/triggers/MetadataPageContent.spec.tsx +140 -0
  20. package/src/pipeline/config/triggers/Triggers.spec.tsx +80 -0
  21. package/src/pipeline/config/triggers/Triggers.tsx +6 -1
  22. package/src/pipeline/config/triggers/index.ts +0 -1
  23. package/src/pipeline/config/triggers/triggers.module.ts +1 -0
  24. package/src/pipeline/pipeline.module.ts +0 -2
  25. package/src/presentation/ReactModal.spec.tsx +72 -0
  26. package/src/presentation/ReactModal.tsx +12 -2
  27. package/dist/pipeline/config/stages/wercker/WerckerExecutionLabel.d.ts +0 -7
  28. package/dist/pipeline/config/stages/wercker/modal/addParameter.controller.modal.d.ts +0 -10
  29. package/dist/pipeline/config/stages/wercker/werckerExecutionDetails.controller.d.ts +0 -18
  30. package/dist/pipeline/config/stages/wercker/werckerStage.d.ts +0 -51
  31. package/dist/pipeline/config/stages/wercker/werckerStage.module.d.ts +0 -1
  32. package/dist/pipeline/config/triggers/wercker/WerckerTrigger.d.ts +0 -13
  33. package/dist/pipeline/config/triggers/wercker/WerckerTriggerTemplate.d.ts +0 -7
  34. package/dist/pipeline/config/triggers/wercker/wercker.trigger.d.ts +0 -1
  35. package/src/pipeline/config/stages/wercker/WerckerExecutionLabel.tsx +0 -32
  36. package/src/pipeline/config/stages/wercker/modal/addParameter.controller.modal.ts +0 -19
  37. package/src/pipeline/config/stages/wercker/modal/addParameter.html +0 -48
  38. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.controller.spec.ts +0 -79
  39. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.controller.ts +0 -55
  40. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.html +0 -79
  41. package/src/pipeline/config/stages/wercker/werckerStage.controller.spec.ts +0 -152
  42. package/src/pipeline/config/stages/wercker/werckerStage.html +0 -150
  43. package/src/pipeline/config/stages/wercker/werckerStage.module.ts +0 -18
  44. package/src/pipeline/config/stages/wercker/werckerStage.ts +0 -232
  45. package/src/pipeline/config/triggers/wercker/WerckerTrigger.tsx +0 -122
  46. package/src/pipeline/config/triggers/wercker/WerckerTriggerTemplate.tsx +0 -13
  47. package/src/pipeline/config/triggers/wercker/wercker.trigger.ts +0 -28
@@ -1,5 +1,5 @@
1
1
  import { ApolloClient } from '@apollo/client';
2
2
  export declare const createApolloClient: () => {
3
3
  client: ApolloClient<import("@apollo/client").NormalizedCacheObject>;
4
- onRefresh: () => Promise<import("@apollo/client").ApolloQueryResult<any>[]>;
4
+ onRefresh: () => Promise<import("@apollo/client").InteropApolloQueryResult<any>[]>;
5
5
  };
@@ -814,7 +814,7 @@ export declare const FetchApplicationDocument: Apollo.DocumentNode;
814
814
  * },
815
815
  * });
816
816
  */
817
- export declare function useFetchApplicationQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationQuery, FetchApplicationQueryVariables>): Apollo.QueryResult<FetchApplicationQuery, Exact<{
817
+ export declare function useFetchApplicationQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationQuery, FetchApplicationQueryVariables>): Apollo.InteropQueryResult<FetchApplicationQuery, Exact<{
818
818
  appName: string;
819
819
  statuses?: MdArtifactStatusInEnvironment | MdArtifactStatusInEnvironment[];
820
820
  }>>;
@@ -842,7 +842,7 @@ export declare const FetchCurrentVersionDocument: Apollo.DocumentNode;
842
842
  * },
843
843
  * });
844
844
  */
845
- export declare function useFetchCurrentVersionQuery(baseOptions: Apollo.QueryHookOptions<FetchCurrentVersionQuery, FetchCurrentVersionQueryVariables>): Apollo.QueryResult<FetchCurrentVersionQuery, Exact<{
845
+ export declare function useFetchCurrentVersionQuery(baseOptions: Apollo.QueryHookOptions<FetchCurrentVersionQuery, FetchCurrentVersionQueryVariables>): Apollo.InteropQueryResult<FetchCurrentVersionQuery, Exact<{
846
846
  appName: string;
847
847
  }>>;
848
848
  export declare function useFetchCurrentVersionLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchCurrentVersionQuery, FetchCurrentVersionQueryVariables>): Apollo.LazyQueryResultTuple<FetchCurrentVersionQuery, Exact<{
@@ -869,7 +869,7 @@ export declare const FetchVersionsHistoryDocument: Apollo.DocumentNode;
869
869
  * },
870
870
  * });
871
871
  */
872
- export declare function useFetchVersionsHistoryQuery(baseOptions: Apollo.QueryHookOptions<FetchVersionsHistoryQuery, FetchVersionsHistoryQueryVariables>): Apollo.QueryResult<FetchVersionsHistoryQuery, Exact<{
872
+ export declare function useFetchVersionsHistoryQuery(baseOptions: Apollo.QueryHookOptions<FetchVersionsHistoryQuery, FetchVersionsHistoryQueryVariables>): Apollo.InteropQueryResult<FetchVersionsHistoryQuery, Exact<{
873
873
  appName: string;
874
874
  limit?: number;
875
875
  }>>;
@@ -897,7 +897,7 @@ export declare const FetchPinnedVersionsDocument: Apollo.DocumentNode;
897
897
  * },
898
898
  * });
899
899
  */
900
- export declare function useFetchPinnedVersionsQuery(baseOptions: Apollo.QueryHookOptions<FetchPinnedVersionsQuery, FetchPinnedVersionsQueryVariables>): Apollo.QueryResult<FetchPinnedVersionsQuery, Exact<{
900
+ export declare function useFetchPinnedVersionsQuery(baseOptions: Apollo.QueryHookOptions<FetchPinnedVersionsQuery, FetchPinnedVersionsQueryVariables>): Apollo.InteropQueryResult<FetchPinnedVersionsQuery, Exact<{
901
901
  appName: string;
902
902
  }>>;
903
903
  export declare function useFetchPinnedVersionsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchPinnedVersionsQuery, FetchPinnedVersionsQueryVariables>): Apollo.LazyQueryResultTuple<FetchPinnedVersionsQuery, Exact<{
@@ -924,7 +924,7 @@ export declare const FetchVersionDocument: Apollo.DocumentNode;
924
924
  * },
925
925
  * });
926
926
  */
927
- export declare function useFetchVersionQuery(baseOptions: Apollo.QueryHookOptions<FetchVersionQuery, FetchVersionQueryVariables>): Apollo.QueryResult<FetchVersionQuery, Exact<{
927
+ export declare function useFetchVersionQuery(baseOptions: Apollo.QueryHookOptions<FetchVersionQuery, FetchVersionQueryVariables>): Apollo.InteropQueryResult<FetchVersionQuery, Exact<{
928
928
  appName: string;
929
929
  versions?: string | string[];
930
930
  }>>;
@@ -952,7 +952,7 @@ export declare const FetchResourceStatusDocument: Apollo.DocumentNode;
952
952
  * },
953
953
  * });
954
954
  */
955
- export declare function useFetchResourceStatusQuery(baseOptions: Apollo.QueryHookOptions<FetchResourceStatusQuery, FetchResourceStatusQueryVariables>): Apollo.QueryResult<FetchResourceStatusQuery, Exact<{
955
+ export declare function useFetchResourceStatusQuery(baseOptions: Apollo.QueryHookOptions<FetchResourceStatusQuery, FetchResourceStatusQueryVariables>): Apollo.InteropQueryResult<FetchResourceStatusQuery, Exact<{
956
956
  appName: string;
957
957
  }>>;
958
958
  export declare function useFetchResourceStatusLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchResourceStatusQuery, FetchResourceStatusQueryVariables>): Apollo.LazyQueryResultTuple<FetchResourceStatusQuery, Exact<{
@@ -978,7 +978,7 @@ export declare const FetchNotificationsDocument: Apollo.DocumentNode;
978
978
  * },
979
979
  * });
980
980
  */
981
- export declare function useFetchNotificationsQuery(baseOptions: Apollo.QueryHookOptions<FetchNotificationsQuery, FetchNotificationsQueryVariables>): Apollo.QueryResult<FetchNotificationsQuery, Exact<{
981
+ export declare function useFetchNotificationsQuery(baseOptions: Apollo.QueryHookOptions<FetchNotificationsQuery, FetchNotificationsQueryVariables>): Apollo.InteropQueryResult<FetchNotificationsQuery, Exact<{
982
982
  appName: string;
983
983
  }>>;
984
984
  export declare function useFetchNotificationsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchNotificationsQuery, FetchNotificationsQueryVariables>): Apollo.LazyQueryResultTuple<FetchNotificationsQuery, Exact<{
@@ -1004,7 +1004,7 @@ export declare const FetchApplicationManagementDataDocument: Apollo.DocumentNode
1004
1004
  * },
1005
1005
  * });
1006
1006
  */
1007
- export declare function useFetchApplicationManagementDataQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationManagementDataQuery, FetchApplicationManagementDataQueryVariables>): Apollo.QueryResult<FetchApplicationManagementDataQuery, Exact<{
1007
+ export declare function useFetchApplicationManagementDataQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationManagementDataQuery, FetchApplicationManagementDataQueryVariables>): Apollo.InteropQueryResult<FetchApplicationManagementDataQuery, Exact<{
1008
1008
  appName: string;
1009
1009
  }>>;
1010
1010
  export declare function useFetchApplicationManagementDataLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchApplicationManagementDataQuery, FetchApplicationManagementDataQueryVariables>): Apollo.LazyQueryResultTuple<FetchApplicationManagementDataQuery, Exact<{
@@ -1030,7 +1030,7 @@ export declare const FetchApplicationManagementStatusDocument: Apollo.DocumentNo
1030
1030
  * },
1031
1031
  * });
1032
1032
  */
1033
- export declare function useFetchApplicationManagementStatusQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationManagementStatusQuery, FetchApplicationManagementStatusQueryVariables>): Apollo.QueryResult<FetchApplicationManagementStatusQuery, Exact<{
1033
+ export declare function useFetchApplicationManagementStatusQuery(baseOptions: Apollo.QueryHookOptions<FetchApplicationManagementStatusQuery, FetchApplicationManagementStatusQueryVariables>): Apollo.InteropQueryResult<FetchApplicationManagementStatusQuery, Exact<{
1034
1034
  appName: string;
1035
1035
  }>>;
1036
1036
  export declare function useFetchApplicationManagementStatusLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FetchApplicationManagementStatusQuery, FetchApplicationManagementStatusQueryVariables>): Apollo.LazyQueryResultTuple<FetchApplicationManagementStatusQuery, Exact<{
@@ -5,6 +5,6 @@ export declare enum ManifestRenderers {
5
5
  KUSTOMIZE = "KUSTOMIZE",
6
6
  KUSTOMIZE4 = "KUSTOMIZE4"
7
7
  }
8
- export declare const HELM_RENDERERS: Readonly<ManifestRenderers[]>;
8
+ export declare const HELM_RENDERERS: readonly ManifestRenderers[];
9
9
  export declare const HELMFILE_RENDERER: Readonly<ManifestRenderers>;
10
- export declare const KUSTOMIZE_RENDERERS: Readonly<ManifestRenderers[]>;
10
+ export declare const KUSTOMIZE_RENDERERS: readonly ManifestRenderers[];
@@ -4,6 +4,7 @@ import type { IPipeline } from '../../../domain';
4
4
  export interface ITriggersProps {
5
5
  application: Application;
6
6
  pipeline: IPipeline;
7
+ pipelineConfig?: IPipeline;
7
8
  fieldUpdated: () => void;
8
9
  updatePipelineConfig: (changes: Partial<IPipeline>) => void;
9
10
  revertCount: number;
@@ -11,4 +11,3 @@ import './plugin/plugin.trigger';
11
11
  import './pubsub/pubsub.trigger';
12
12
  import './travis/travis.trigger';
13
13
  import './webhook/webhook.trigger';
14
- import './wercker/wercker.trigger';
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/spinnaker/spinnaker.git"
6
6
  },
7
7
  "license": "Apache-2.0",
8
- "version": "2026.0.2",
8
+ "version": "2026.1.0",
9
9
  "module": "dist/index.js",
10
10
  "typings": "dist/index.d.ts",
11
11
  "publishConfig": {
@@ -59,7 +59,7 @@
59
59
  "jquery-textcomplete": "1.6.1",
60
60
  "js-worker-search": "npm:js-worker-search-uuid-fix@^1.4.2",
61
61
  "js-yaml": "3.13.1",
62
- "lodash": "4.17.23",
62
+ "lodash": "4.18.1",
63
63
  "lodash-decorators": "4.5.0",
64
64
  "luxon": "1.23.0",
65
65
  "memoize-one": "6.0.0",
@@ -128,5 +128,5 @@
128
128
  "shx": "0.3.3",
129
129
  "typescript": "5.0.4"
130
130
  },
131
- "gitHead": "f81cd582f8abad99f82ee96ae11cdfb59a0c643c"
131
+ "gitHead": "b43289872672de89234911de45d1cba0dd18373f"
132
132
  }
@@ -22,7 +22,7 @@ declare module 'react-ultimate-pagination' {
22
22
 
23
23
  export function createUltimatePagination(options: {
24
24
  itemTypeToComponent: ItemTypeToComponent;
25
- WrapperComponent: React.ComponentClass = 'div';
25
+ WrapperComponent?: React.ComponentClass | string;
26
26
  }): React.ComponentClass<IUltimatePaginationProps>;
27
27
  export interface ItemTypes {
28
28
  PAGE: 'PAGE';
@@ -6,7 +6,6 @@ import type { IBuild, IGcbTrigger, IJobConfig } from '../domain';
6
6
  export enum BuildServiceType {
7
7
  Jenkins = 'jenkins',
8
8
  Travis = 'travis',
9
- Wercker = 'wercker',
10
9
  Concourse = 'concourse',
11
10
  }
12
11
 
@@ -51,13 +51,7 @@ export interface IBuildTrigger extends ITrigger {
51
51
  project: string;
52
52
  propertyFile?: string;
53
53
  master: string;
54
- type: 'jenkins' | 'travis' | 'wercker' | 'concourse';
55
- }
56
-
57
- export interface IWerckerTrigger extends IBuildTrigger {
58
- app: string;
59
- pipeline: string;
60
- type: 'wercker';
54
+ type: 'jenkins' | 'travis' | 'concourse';
61
55
  }
62
56
 
63
57
  export interface IConcourseTrigger extends IBuildTrigger {
@@ -94,9 +88,3 @@ export interface IWebhookTrigger extends ITrigger {
94
88
  export interface ICDEventsTrigger extends IWebhookTrigger {
95
89
  attributeConstraints: { [key: string]: string };
96
90
  }
97
-
98
- export interface IWerckerTrigger extends IBuildTrigger {
99
- app: string;
100
- pipeline: string;
101
- type: 'wercker';
102
- }
@@ -351,12 +351,6 @@ const helpContents: { [key: string]: string } = {
351
351
  If Travis reports the build status as UNSTABLE,
352
352
  Spinnaker will mark the stage as TERMINAL; subsequent execution will be determined based on the configuration of the
353
353
  <b>If build fails</b> option for this stage.`,
354
- 'pipeline.config.wercker.markUnstableAsSuccessful.true':
355
- 'If Wercker reports the build status as UNSTABLE, Spinnaker will mark the stage as SUCCEEDED and continue execution of the pipeline.',
356
- 'pipeline.config.wercker.markUnstableAsSuccessful.false': `
357
- If Wercker reports the build status as UNSTABLE,
358
- Spinnaker will mark the stage as FAILED; subsequent execution will be determined based on the configuration of the
359
- <b>If build fails</b> option for this stage.`,
360
354
  'pipeline.config.cron.expression':
361
355
  '<strong>Format (Year is optional)</strong><p><samp>Seconds Minutes Hour DayOfMonth Month DayOfWeek (Year)</samp></p>' +
362
356
  '<p><strong>Example: every 30 minutes</strong></p><samp>0 0/30 * * * ?</samp>' +
@@ -488,11 +482,9 @@ const helpContents: { [key: string]: string } = {
488
482
  'if unchecked, marks the stage as successful right away without waiting for the Jenkins job to complete',
489
483
  'travis.waitForCompletion':
490
484
  'if unchecked, marks the stage as successful right away without waiting for the Travis job to complete',
491
- 'wercker.waitForCompletion':
492
- 'if unchecked, marks the stage as successful right away without waiting for the Wercker job to complete',
493
485
  'script.waitForCompletion':
494
486
  'if unchecked, marks the stage as successful right away without waiting for the script to complete',
495
- // eslint-disable-next-line no-useless-escape
487
+
496
488
  'markdown.examples': `
497
489
  Some examples of markdown syntax: <br/> \`*italic*\` <br/> \`**bold**\` <br/> \`[link text](http://url-goes-here)\`
498
490
  `,
@@ -5,6 +5,7 @@
5
5
  application="application"
6
6
  field-updated="stageFieldUpdated"
7
7
  pipeline="isV2TemplatedPipeline ? pipeline : pipelineConfig"
8
+ pipeline-config="pipelineConfig"
8
9
  update-pipeline-config="updatePipelineConfig"
9
10
  revert-count="viewState.revertCount"
10
11
  >
@@ -6,9 +6,9 @@ export enum ManifestRenderers {
6
6
  KUSTOMIZE4 = 'KUSTOMIZE4',
7
7
  }
8
8
 
9
- export const HELM_RENDERERS: Readonly<ManifestRenderers[]> = [ManifestRenderers.HELM2, ManifestRenderers.HELM3];
9
+ export const HELM_RENDERERS: readonly ManifestRenderers[] = [ManifestRenderers.HELM2, ManifestRenderers.HELM3];
10
10
  export const HELMFILE_RENDERER: Readonly<ManifestRenderers> = ManifestRenderers.HELMFILE;
11
- export const KUSTOMIZE_RENDERERS: Readonly<ManifestRenderers[]> = [
11
+ export const KUSTOMIZE_RENDERERS: readonly ManifestRenderers[] = [
12
12
  ManifestRenderers.KUSTOMIZE,
13
13
  ManifestRenderers.KUSTOMIZE4,
14
14
  ];
@@ -30,23 +30,50 @@ angular
30
30
  $scope.stage.loadBalancers = $scope.stage.loadBalancers || [];
31
31
  }
32
32
 
33
+ function appendLoadBalancers(loadBalancers) {
34
+ if (Array.isArray(loadBalancers)) {
35
+ $scope.stage.loadBalancers.push(...loadBalancers);
36
+ } else if (loadBalancers) {
37
+ $scope.stage.loadBalancers.push(loadBalancers);
38
+ }
39
+ }
40
+
41
+ function updateLoadBalancerAtIndex(loadBalancer, index) {
42
+ if (Array.isArray(loadBalancer)) {
43
+ $scope.stage.loadBalancers.splice(index, 1, ...loadBalancer);
44
+ } else if (loadBalancer) {
45
+ $scope.stage.loadBalancers[index] = loadBalancer;
46
+ }
47
+ }
48
+
49
+ function openLoadBalancerModal(config, loadBalancer, isNew) {
50
+ if (config.pipelineCreateLoadBalancerModal) {
51
+ return config.pipelineCreateLoadBalancerModal({
52
+ application: $scope.application,
53
+ loadBalancer,
54
+ isNew,
55
+ $uibModal,
56
+ });
57
+ }
58
+ return $uibModal.open({
59
+ templateUrl: config.createLoadBalancerTemplateUrl,
60
+ controller: `${config.createLoadBalancerController} as ctrl`,
61
+ size: 'lg',
62
+ resolve: {
63
+ application: () => $scope.application,
64
+ loadBalancer: () => loadBalancer,
65
+ isNew: () => isNew,
66
+ forPipelineConfig: () => true,
67
+ },
68
+ }).result;
69
+ }
70
+
33
71
  this.addLoadBalancer = function () {
34
72
  ProviderSelectionService.selectProvider($scope.application, 'loadBalancer').then(function (selectedProvider) {
35
73
  const config = CloudProviderRegistry.getValue(selectedProvider, 'loadBalancer');
36
- $uibModal
37
- .open({
38
- templateUrl: config.createLoadBalancerTemplateUrl,
39
- controller: `${config.createLoadBalancerController} as ctrl`,
40
- size: 'lg',
41
- resolve: {
42
- application: () => $scope.application,
43
- loadBalancer: () => null,
44
- isNew: () => true,
45
- forPipelineConfig: () => true,
46
- },
47
- })
48
- .result.then(function (newLoadBalancer) {
49
- $scope.stage.loadBalancers.push(newLoadBalancer);
74
+ openLoadBalancerModal(config, null, true)
75
+ .then(function (newLoadBalancer) {
76
+ appendLoadBalancers(newLoadBalancer);
50
77
  })
51
78
  .catch(() => {});
52
79
  });
@@ -55,20 +82,10 @@ angular
55
82
  this.editLoadBalancer = function (loadBalancer, index) {
56
83
  ProviderSelectionService.selectProvider($scope.application, 'loadBalancer').then(function (selectedProvider) {
57
84
  const config = CloudProviderRegistry.getValue(selectedProvider, 'loadBalancer');
58
- $uibModal
59
- .open({
60
- templateUrl: config.createLoadBalancerTemplateUrl,
61
- controller: `${config.createLoadBalancerController} as ctrl`,
62
- size: 'lg',
63
- resolve: {
64
- application: () => $scope.application,
65
- loadBalancer: () => angular.copy(loadBalancer),
66
- isNew: () => false,
67
- forPipelineConfig: () => true,
68
- },
69
- })
70
- .result.then(function (updatedLoadBalancer) {
71
- $scope.stage.loadBalancers[index] = updatedLoadBalancer;
85
+ const loadBalancerCopy = angular.copy(loadBalancer);
86
+ openLoadBalancerModal(config, loadBalancerCopy, false)
87
+ .then(function (updatedLoadBalancer) {
88
+ updateLoadBalancerAtIndex(updatedLoadBalancer, index);
72
89
  })
73
90
  .catch(() => {});
74
91
  });
@@ -0,0 +1,101 @@
1
+ import { CloudProviderRegistry, ProviderSelectionService } from '../../../../cloudProvider';
2
+ import { name as moduleName } from './createLoadBalancerStage';
3
+
4
+ describe('createLoadBalancerStageCtrl', function () {
5
+ beforeEach(() => {
6
+ window.module(moduleName);
7
+ });
8
+
9
+ beforeEach(
10
+ window.inject(function ($controller, $rootScope, $q) {
11
+ this.$scope = $rootScope.$new();
12
+ this.$scope.stage = {};
13
+ this.$scope.application = {};
14
+ this.$uibModal = {
15
+ open: jasmine.createSpy('open').and.returnValue({ result: $q.when([{ name: 'lb1' }, { name: 'lb2' }]) }),
16
+ };
17
+
18
+ spyOn(ProviderSelectionService, 'selectProvider').and.returnValue($q.when('gce'));
19
+ this.cloudProviderConfig = {
20
+ createLoadBalancerTemplateUrl: 'template',
21
+ createLoadBalancerController: 'ctrl',
22
+ };
23
+ spyOn(CloudProviderRegistry, 'getValue').and.callFake(() => this.cloudProviderConfig);
24
+
25
+ this.ctrl = $controller('createLoadBalancerStageCtrl', {
26
+ $scope: this.$scope,
27
+ $uibModal: this.$uibModal,
28
+ });
29
+ this.$rootScope = $rootScope;
30
+ this.$q = $q;
31
+ }),
32
+ );
33
+
34
+ it('flattens array results when adding load balancers', function () {
35
+ this.ctrl.addLoadBalancer();
36
+ this.$rootScope.$digest();
37
+
38
+ expect(this.$scope.stage.loadBalancers).toEqual([{ name: 'lb1' }, { name: 'lb2' }]);
39
+ });
40
+
41
+ it('splices array results when editing a load balancer', function () {
42
+ this.$scope.stage.loadBalancers = [{ name: 'old' }];
43
+ this.$uibModal.open.and.returnValue({ result: this.$q.when([{ name: 'new1' }, { name: 'new2' }]) });
44
+
45
+ this.ctrl.editLoadBalancer(this.$scope.stage.loadBalancers[0], 0);
46
+ this.$rootScope.$digest();
47
+
48
+ expect(this.$scope.stage.loadBalancers).toEqual([{ name: 'new1' }, { name: 'new2' }]);
49
+ });
50
+
51
+ it('uses provider hook when adding load balancers', function () {
52
+ const hookResult = { name: 'hook-lb' };
53
+ this.cloudProviderConfig.pipelineCreateLoadBalancerModal = jasmine
54
+ .createSpy('pipelineCreateLoadBalancerModal')
55
+ .and.returnValue(this.$q.when(hookResult));
56
+
57
+ this.ctrl.addLoadBalancer();
58
+ this.$rootScope.$digest();
59
+
60
+ expect(this.cloudProviderConfig.pipelineCreateLoadBalancerModal).toHaveBeenCalledWith(
61
+ jasmine.objectContaining({
62
+ application: this.$scope.application,
63
+ loadBalancer: null,
64
+ isNew: true,
65
+ $uibModal: this.$uibModal,
66
+ }),
67
+ );
68
+ expect(this.$uibModal.open).not.toHaveBeenCalled();
69
+ expect(this.$scope.stage.loadBalancers).toEqual([hookResult]);
70
+ });
71
+
72
+ it('uses provider hook when editing a load balancer', function () {
73
+ this.$scope.stage.loadBalancers = [{ name: 'old' }];
74
+ const hookResult = { name: 'updated' };
75
+ this.cloudProviderConfig.pipelineCreateLoadBalancerModal = jasmine
76
+ .createSpy('pipelineCreateLoadBalancerModal')
77
+ .and.returnValue(this.$q.when(hookResult));
78
+
79
+ this.ctrl.editLoadBalancer(this.$scope.stage.loadBalancers[0], 0);
80
+ this.$rootScope.$digest();
81
+
82
+ const hookArgs = this.cloudProviderConfig.pipelineCreateLoadBalancerModal.calls.mostRecent().args[0];
83
+ expect(hookArgs.loadBalancer).toEqual({ name: 'old' });
84
+ expect(hookArgs.loadBalancer).not.toBe(this.$scope.stage.loadBalancers[0]);
85
+ expect(hookArgs.isNew).toBe(false);
86
+ expect(this.$uibModal.open).not.toHaveBeenCalled();
87
+ expect(this.$scope.stage.loadBalancers).toEqual([hookResult]);
88
+ });
89
+
90
+ it('flattens array results when hook returns array', function () {
91
+ this.cloudProviderConfig.pipelineCreateLoadBalancerModal = jasmine
92
+ .createSpy('pipelineCreateLoadBalancerModal')
93
+ .and.returnValue(this.$q.when([{ name: 'hook1' }, { name: 'hook2' }]));
94
+
95
+ this.ctrl.addLoadBalancer();
96
+ this.$rootScope.$digest();
97
+
98
+ expect(this.$uibModal.open).not.toHaveBeenCalled();
99
+ expect(this.$scope.stage.loadBalancers).toEqual([{ name: 'hook1' }, { name: 'hook2' }]);
100
+ });
101
+ });
@@ -0,0 +1,140 @@
1
+ import { mount } from 'enzyme';
2
+ import React from 'react';
3
+
4
+ import { MetadataPage } from './MetadataPageContent';
5
+ import type { IPipeline, IPipelineTag } from '../../../domain';
6
+
7
+ describe('<MetadataPageContent />', () => {
8
+ let updatePipelineConfigSpy: jasmine.Spy;
9
+
10
+ const makePipeline = (overrides: Partial<IPipeline> = {}): IPipeline => ({
11
+ application: 'products',
12
+ id: 'pipeline-1',
13
+ keepWaitingPipelines: false,
14
+ limitConcurrent: true,
15
+ name: 'test-pipeline',
16
+ parameterConfig: [],
17
+ stages: [],
18
+ triggers: [],
19
+ ...overrides,
20
+ });
21
+
22
+ beforeEach(() => {
23
+ updatePipelineConfigSpy = jasmine.createSpy('updatePipelineConfig');
24
+ });
25
+
26
+ describe('Rendering tags', () => {
27
+ it('renders tag rows when pipeline has tags', () => {
28
+ const tags: IPipelineTag[] = [
29
+ { name: 'service', value: 'products' },
30
+ { name: 'type', value: 'scale' },
31
+ ];
32
+ const pipeline = makePipeline({ tags });
33
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
34
+
35
+ const tagInputs = wrapper.find('table.tags tbody tr');
36
+ expect(tagInputs.length).toBe(2);
37
+
38
+ const nameInputs = wrapper.find('table.tags tbody input[type="text"]');
39
+ expect(nameInputs.at(0).prop('value')).toBe('service');
40
+ expect(nameInputs.at(1).prop('value')).toBe('products');
41
+ expect(nameInputs.at(2).prop('value')).toBe('type');
42
+ expect(nameInputs.at(3).prop('value')).toBe('scale');
43
+ });
44
+
45
+ it('renders no tag rows when pipeline.tags is undefined', () => {
46
+ const pipeline = makePipeline();
47
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
48
+
49
+ const tagRows = wrapper.find('table.tags tbody tr');
50
+ expect(tagRows.length).toBe(0);
51
+ });
52
+
53
+ it('renders no tag rows when pipeline.tags is an empty array', () => {
54
+ const pipeline = makePipeline({ tags: [] });
55
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
56
+
57
+ const tagRows = wrapper.find('table.tags tbody tr');
58
+ expect(tagRows.length).toBe(0);
59
+ });
60
+ });
61
+
62
+ describe('V2 templated pipeline plan vs instance config', () => {
63
+ it('renders no tags when given the Orca plan which does not include instance-level tags', () => {
64
+ const instanceConfig = makePipeline({
65
+ tags: [
66
+ { name: 'service', value: 'products' },
67
+ { name: 'type', value: 'eval' },
68
+ ],
69
+ });
70
+
71
+ const orcaPlan = makePipeline({
72
+ name: instanceConfig.name,
73
+ // Orca plan does NOT include instance-level tags
74
+ });
75
+
76
+ const wrapper = mount(<MetadataPage pipeline={orcaPlan} updatePipelineConfig={updatePipelineConfigSpy} />);
77
+ const tagRows = wrapper.find('table.tags tbody tr');
78
+ expect(tagRows.length).toBe(0);
79
+ });
80
+
81
+ it('renders tags when given the raw instance config directly', () => {
82
+ const instanceConfig = makePipeline({
83
+ tags: [
84
+ { name: 'service', value: 'products' },
85
+ { name: 'type', value: 'eval' },
86
+ ],
87
+ });
88
+
89
+ const wrapper = mount(<MetadataPage pipeline={instanceConfig} updatePipelineConfig={updatePipelineConfigSpy} />);
90
+ const tagRows = wrapper.find('table.tags tbody tr');
91
+ expect(tagRows.length).toBe(2);
92
+ });
93
+ });
94
+
95
+ describe('Adding a tag', () => {
96
+ it('calls updatePipelineConfig with new empty tag appended', () => {
97
+ const pipeline = makePipeline({
98
+ tags: [{ name: 'service', value: 'products' }],
99
+ });
100
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
101
+
102
+ wrapper.find('button.add-new').simulate('click');
103
+ expect(updatePipelineConfigSpy).toHaveBeenCalledTimes(1);
104
+ expect(updatePipelineConfigSpy).toHaveBeenCalledWith({
105
+ tags: [
106
+ { name: 'service', value: 'products' },
107
+ { name: '', value: '' },
108
+ ],
109
+ });
110
+ });
111
+
112
+ it('creates the first tag when pipeline has no tags', () => {
113
+ const pipeline = makePipeline();
114
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
115
+
116
+ wrapper.find('button.add-new').simulate('click');
117
+ expect(updatePipelineConfigSpy).toHaveBeenCalledTimes(1);
118
+ expect(updatePipelineConfigSpy).toHaveBeenCalledWith({
119
+ tags: [{ name: '', value: '' }],
120
+ });
121
+ });
122
+ });
123
+
124
+ describe('Deleting a tag', () => {
125
+ it('removes the tag at the clicked index', () => {
126
+ const tags: IPipelineTag[] = [
127
+ { name: 'service', value: 'products' },
128
+ { name: 'type', value: 'scale' },
129
+ ];
130
+ const pipeline = makePipeline({ tags });
131
+ const wrapper = mount(<MetadataPage pipeline={pipeline} updatePipelineConfig={updatePipelineConfigSpy} />);
132
+
133
+ wrapper.find('.glyphicon-trash').at(0).simulate('click');
134
+ expect(updatePipelineConfigSpy).toHaveBeenCalledTimes(1);
135
+ expect(updatePipelineConfigSpy).toHaveBeenCalledWith({
136
+ tags: [{ name: 'type', value: 'scale' }],
137
+ });
138
+ });
139
+ });
140
+ });
@@ -0,0 +1,80 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+
4
+ import { MetadataPageContent } from './MetadataPageContent';
5
+ import { Triggers } from './Triggers';
6
+ import { ApplicationModelBuilder } from '../../../application';
7
+ import type { IPipeline, IPipelineTag } from '../../../domain';
8
+
9
+ describe('<Triggers />', () => {
10
+ const makePipeline = (overrides: Partial<IPipeline> = {}): IPipeline => ({
11
+ application: 'products',
12
+ id: 'pipeline-1',
13
+ keepWaitingPipelines: false,
14
+ limitConcurrent: true,
15
+ name: 'test-pipeline',
16
+ parameterConfig: [],
17
+ stages: [],
18
+ triggers: [],
19
+ ...overrides,
20
+ });
21
+
22
+ const instanceTags: IPipelineTag[] = [
23
+ { name: 'service', value: 'products' },
24
+ { name: 'type', value: 'eval' },
25
+ ];
26
+
27
+ let defaultProps: any;
28
+
29
+ beforeEach(() => {
30
+ defaultProps = {
31
+ application: ApplicationModelBuilder.createApplicationForTests('products'),
32
+ fieldUpdated: jasmine.createSpy('fieldUpdated'),
33
+ updatePipelineConfig: jasmine.createSpy('updatePipelineConfig'),
34
+ revertCount: 0,
35
+ };
36
+ });
37
+
38
+ describe('MetadataPageContent pipeline prop routing', () => {
39
+ it('receives the plan pipeline when pipelineConfig is not provided', () => {
40
+ const plan = makePipeline({ name: 'test-pipeline' });
41
+
42
+ const wrapper = shallow(<Triggers {...defaultProps} pipeline={plan} />);
43
+ const metadataContent = wrapper.find(MetadataPageContent);
44
+
45
+ expect(metadataContent.prop('pipeline')).toBe(plan);
46
+ expect(metadataContent.prop('pipeline').tags).toBeUndefined();
47
+ });
48
+
49
+ it('receives the raw config instead of the plan when pipelineConfig is provided', () => {
50
+ const plan = makePipeline({ name: 'test-pipeline' });
51
+ const rawConfig = makePipeline({ name: 'test-pipeline', tags: instanceTags });
52
+
53
+ const wrapper = shallow(<Triggers {...defaultProps} pipeline={plan} pipelineConfig={rawConfig} />);
54
+ const metadataContent = wrapper.find(MetadataPageContent);
55
+
56
+ expect(metadataContent.prop('pipeline')).toBe(rawConfig);
57
+ expect(metadataContent.prop('pipeline').tags).toEqual(instanceTags);
58
+ });
59
+
60
+ it('uses pipeline directly for standard non-templated pipelines without pipelineConfig', () => {
61
+ const standardPipeline = makePipeline({
62
+ tags: [{ name: 'env', value: 'prod' }],
63
+ });
64
+
65
+ const wrapper = shallow(<Triggers {...defaultProps} pipeline={standardPipeline} />);
66
+ const metadataContent = wrapper.find(MetadataPageContent);
67
+
68
+ expect(metadataContent.prop('pipeline')).toBe(standardPipeline);
69
+ expect(metadataContent.prop('pipeline').tags).toEqual([{ name: 'env', value: 'prod' }]);
70
+ });
71
+
72
+ it('passes updatePipelineConfig through to MetadataPageContent', () => {
73
+ const pipeline = makePipeline();
74
+ const wrapper = shallow(<Triggers {...defaultProps} pipeline={pipeline} />);
75
+ const metadataContent = wrapper.find(MetadataPageContent);
76
+
77
+ expect(metadataContent.prop('updatePipelineConfig')).toBe(defaultProps.updatePipelineConfig);
78
+ });
79
+ });
80
+ });