-
Notifications
You must be signed in to change notification settings - Fork 900
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(artifacts): deleting expected artifact removes stale references (#…
- Loading branch information
Scott Bloch-Wehba-Seaward
committed
Apr 5, 2018
1 parent
6701afa
commit bd91225
Showing
8 changed files
with
213 additions
and
13 deletions.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
app/scripts/modules/core/src/artifact/ArtifactReferenceService.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { ArtifactReferenceServiceProvider } from './ArtifactReferenceService'; | ||
|
||
const stage = (mixin: any) => Object.assign({}, { | ||
name: 'name', | ||
type: 'foobar', | ||
refId: 'x', | ||
requisiteStageRefIds: [] | ||
}, mixin); | ||
|
||
describe('ArtifactReferenceService', () => { | ||
let svc: ArtifactReferenceServiceProvider; | ||
|
||
beforeEach(() => { | ||
svc = new ArtifactReferenceServiceProvider(); | ||
}); | ||
|
||
describe('removeReferenceFromStages', () => { | ||
it('deletes reference from stage', () => { | ||
const stages = [stage({ foo: 'bar' })]; | ||
const refs = () => [['foo']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('bar', stages); | ||
expect(stages[0].foo).toBe(undefined); | ||
}); | ||
|
||
it('deletes multiple references from a stage if registered to do so', () => { | ||
const stages = [stage({ 'deployedManifest': 'foo', 'requiredArtifactIds': 'foo' })]; | ||
const refs = () => [ | ||
['deployedManifest'], | ||
['requiredArtifactIds'] | ||
]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('foo', stages); | ||
expect(stages[0].deployedManifest).toBe(undefined); | ||
expect(stages[0].requiredArtifactIds).toBe(undefined); | ||
}); | ||
|
||
it('doesnt delete reference from stage if reference doesnt match', () => { | ||
const stages = [ | ||
stage({ foo: 'ref1' }), | ||
stage({ foo: 'ref2' }), | ||
]; | ||
const refs = () => [['foo']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref1', stages); | ||
expect(stages[0].foo).toBe(undefined); | ||
expect(stages[1].foo).toBe('ref2'); | ||
}); | ||
|
||
it('doesnt delete reference if reference doesnt exist', () => { | ||
const stages = [stage({ foo: 'ref1' })]; | ||
const refs = () => [['foo', 'bar']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref1', stages); | ||
expect(stages[0].foo).toBe('ref1'); | ||
}); | ||
|
||
it('deletes nested references', () => { | ||
const stages = [stage({ foo: [{ baz: 'ref1' }] })]; | ||
const refs = () => [['foo', 0, 'baz']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref1', stages); | ||
expect(stages[0].foo[0].baz).toBe(undefined); | ||
}); | ||
|
||
it('doesnt delete nested references if reference doesnt match', () => { | ||
const stages = [ | ||
stage({ foo: [{ baz: 'ref1' }] }), | ||
stage({ foo: [{ baz: 'ref2' }] }), | ||
]; | ||
const refs = () => [['foo', 0, 'baz']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref1', stages); | ||
expect(stages[0].foo[0].baz).toBe(undefined); | ||
expect(stages[1].foo[0].baz).toBe('ref2'); | ||
}); | ||
|
||
it('splices nested reference from array', () => { | ||
const stages = [ stage({ path: { to: { reference: ['ref1', 'ref2', 'ref3'] } } }) ]; | ||
const refs = () => [['path', 'to', 'reference', 1]]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref2', stages); | ||
expect(stages[0].path.to.reference.length).toBe(2); | ||
expect(stages[0].path.to.reference[0]).toBe('ref1'); | ||
expect(stages[0].path.to.reference[1]).toBe('ref3'); | ||
}); | ||
|
||
it('doesnt splice nested reference from array if reference doesnt match', () => { | ||
const stages = [stage({ path: { to: { reference: ['ref1', 'ref2', 'ref3'] } } })]; | ||
const refs = () => [['path', 'to', 'reference', 1]]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('not found reference', stages); | ||
expect(stages[0].path.to.reference.length).toBe(3); | ||
expect(stages[0].path.to.reference[0]).toBe('ref1'); | ||
expect(stages[0].path.to.reference[1]).toBe('ref2'); | ||
expect(stages[0].path.to.reference[2]).toBe('ref3'); | ||
}); | ||
|
||
it('splices nested reference from array when only the path to the array is given', () => { | ||
const stages = [stage({ path: { to: { reference: ['ref1', 'ref2', 'ref3'] } } })]; | ||
const refs = () => [['path', 'to', 'reference']]; | ||
svc.registerReference('stage', refs); | ||
svc.removeReferenceFromStages('ref2', stages); | ||
expect(stages[0].path.to.reference.length).toBe(2); | ||
expect(stages[0].path.to.reference[0]).toBe('ref1'); | ||
expect(stages[0].path.to.reference[1]).toBe('ref3'); | ||
}); | ||
}); | ||
}); |
57 changes: 57 additions & 0 deletions
57
app/scripts/modules/core/src/artifact/ArtifactReferenceService.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { module } from 'angular'; | ||
import { IStage } from 'core/domain' | ||
import { isEmpty, get } from 'lodash'; | ||
|
||
type SupportedStage = 'stage'; | ||
|
||
interface IWalker { | ||
(refContainer: any): (string|number)[][]; | ||
} | ||
|
||
interface IReference { | ||
category: SupportedStage; | ||
walker: IWalker; | ||
} | ||
|
||
export class ArtifactReferenceServiceProvider { | ||
private references: IReference[] = []; | ||
|
||
public $get() { | ||
return this; | ||
} | ||
|
||
public registerReference(category: SupportedStage, walker: any) { | ||
this.references.push({ category, walker }); | ||
} | ||
|
||
public removeReferenceFromStages(reference: string, stages: IStage[]) { | ||
(stages || []).forEach(stage => { | ||
this.references.forEach(ref => { | ||
const paths: (string|number)[][] = ref.walker(stage).filter(path => !isEmpty(path)); | ||
paths.map(p => p.slice(0)).forEach(path => { | ||
let tail = path.pop(); | ||
let obj = stage; | ||
if (path.length > 0) { | ||
obj = get(stage, path); | ||
} | ||
if (Array.isArray(obj[tail])) { | ||
obj = obj[tail]; | ||
tail = obj.indexOf(reference); | ||
} | ||
if (obj[tail] !== reference) { | ||
return; | ||
} | ||
if (Array.isArray(obj)) { | ||
obj.splice(tail as number, 1); | ||
} else { | ||
delete obj[tail]; | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
|
||
export const ARTIFACT_REFERENCE_SERVICE_PROVIDER = 'spinnaker.core.artifacts.referenceServiceProvider'; | ||
module(ARTIFACT_REFERENCE_SERVICE_PROVIDER, []) | ||
.provider('artifactReferenceService', ArtifactReferenceServiceProvider); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './expectedArtifactSelector.component'; | ||
export * from './expectedArtifact.service'; | ||
export * from './imageSourceSelector.component'; | ||
export * from './ArtifactReferenceService'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters