diff --git a/awx/ui/client/src/job-results/job-results.controller.js b/awx/ui/client/src/job-results/job-results.controller.js index 58302e97b6..454eed3e6e 100644 --- a/awx/ui/client/src/job-results/job-results.controller.js +++ b/awx/ui/client/src/job-results/job-results.controller.js @@ -1,4 +1,4 @@ -export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile) { +export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log) { var getTowerLinks = function() { var getTowerLink = function(key) { if ($scope.job.related[key]) { @@ -104,6 +104,8 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count' $scope.followTooltip = "Currently following standard out as it comes in. Click to unfollow."; } + $scope.events = {}; + // EVENT STUFF BELOW // This is where the async updates to the UI actually happen. @@ -153,10 +155,21 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count' if(change === 'stdout'){ // put stdout elements in stdout container + + // this scopes the event to that particular + // block of stdout. + // If you need to see the event a particular + // stdout block is from, you can: + // angular.element($0).scope().event + $scope.events[mungedEvent.counter] = $scope.$new(); + $scope.events[mungedEvent.counter] + .event = mungedEvent; + angular .element(".JobResultsStdOut-stdoutContainer") .append($compile(mungedEvent - .stdout)($scope)); + .stdout)($scope.events[mungedEvent + .counter])); // move the followAnchor to the bottom of the // container @@ -166,6 +179,11 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count' // if follow is engaged, // scroll down to the followAnchor if ($scope.followEngaged) { + if (!$scope.followScroll) { + $scope.followScroll = function() { + $log.error("follow scroll undefined, standard out directive not loaded yet?"); + }; + } $scope.followScroll(); } } diff --git a/awx/ui/tests/spec/job-results/job-results.controller-test.js b/awx/ui/tests/spec/job-results/job-results.controller-test.js index 11e5275cd2..2f34a42803 100644 --- a/awx/ui/tests/spec/job-results/job-results.controller-test.js +++ b/awx/ui/tests/spec/job-results/job-results.controller-test.js @@ -4,7 +4,7 @@ describe('Controller: jobResultsController', () => { // Setup let jobResultsController; - let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q; + let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log; jobData = { related: {} @@ -39,7 +39,6 @@ describe('Controller: jobResultsController', () => { 'populate', 'markProcessed' ]); - $compile = jasmine.createSpy('$compile'); $provide.value('jobData', jobData); $provide.value('jobDataOptions', jobDataOptions); @@ -50,12 +49,11 @@ describe('Controller: jobResultsController', () => { $provide.value('ParseVariableString', ParseVariableString); $provide.value('jobResultsService', jobResultsService); $provide.value('eventQueue', eventQueue); - $provide.value('$compile', $compile); }); }; let injectVals = () => { - angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend) => { + angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_) => { // when you call $scope.$apply() (which you need to do to // to get inside of .then blocks to test), something is // causing a request for all static files. @@ -81,6 +79,7 @@ describe('Controller: jobResultsController', () => { ParseVariableString.and.returnValue(jobData.extra_vars); jobResultsService = _jobResultsService_; eventQueue = _eventQueue_; + $log = _$log_; jobResultsService.getEvents.and .returnValue($q.when(eventResolve)); @@ -99,7 +98,8 @@ describe('Controller: jobResultsController', () => { ParseTypeChange: ParseTypeChange, jobResultsService: jobResultsService, eventQueue: eventQueue, - $compile: $compile + $compile: $compile, + $log: $log }); }); }; @@ -554,6 +554,31 @@ describe('Controller: jobResultsController', () => { }); }); - // TODO: stdout change tests + describe('populate - stdout', () => { + beforeEach(() => { + + populateResolve = { + counter: 12, + stdout: "line", + changes: ['stdout'] + }; + + bootstrapTest(); + + spyOn($log, 'error'); + + $scope.followEngaged = true; + + $scope.$apply(); + }); + + it('creates new child scope for the event', () => { + expect($scope.events[12].event).toBe(populateResolve); + + // in unit test, followScroll should not be defined as + // directive has not been instantiated + expect($log.error).toHaveBeenCalledWith("follow scroll undefined, standard out directive not loaded yet?"); + }); + }); }); });