describe( 'The article-browser-widget', () => {

   let vueComponent;
   let data;

   beforeEach( axMocks.setupForWidget() );

   beforeEach( () => {
      axMocks.widget.configure( {
         articles: {
            resource: 'articles'
         },
         selection: {
            resource: 'selectedArticle'
         }
      } );
   } );

   beforeEach( axMocks.widget.load );
   beforeEach( () => {
      data = object.deepClone( resourceData );
      ({ vueComponent } = axMocks.widget);
   } );

   afterEach( axMocks.tearDown );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   it( 'subscribes to didReplace events of the articles resource', () => {
      expect( vueComponent.eventBus.subscribe )
         .toHaveBeenCalledWith( 'didReplace.articles', jasmine.any( Function ) );
   } );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   describe( 'when the list of articles is replaced', () => {

      beforeEach( () => {
         axMocks.eventBus.publish( 'didReplace.articles', {
            resource: 'articles',
            data
         } );
         axMocks.eventBus.flush();
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'resets the article selection', () => {
         expect( vueComponent.eventBus.publish ).toHaveBeenCalledWith( 'didReplace.selectedArticle', {
            resource: 'selectedArticle',
            data: null
         } );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      describe( 'and the user selects an article', () => {

         beforeEach( () => {
            vueComponent.selectArticle( vueComponent.articles[ 1 ] );
         } );

         /////////////////////////////////////////////////////////////////////////////////////////////////////

         it( 'the configured selection resource is replaced', () => {
            expect( vueComponent.eventBus.publish ).toHaveBeenCalledWith( 'didReplace.selectedArticle', {
               resource: 'selectedArticle',
               data: vueComponent.articles[ 1 ]
            } );
         } );

      } );

   } );

} );
Esempio n. 2
0
describe( 'A chart-widget', () => {
   let widgetEventBus;
   let widgetScope;
   let testEventBus;

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   beforeEach( axMocks.setupForWidget() );

   beforeEach( () => {
      axMocks.widget.configure( 'timeSeries.resource', 'timeSeriesData' );
      axMocks.widget.configure( 'chart.type', 'multiBarChart' );
   } );

   beforeEach( axMocks.widget.load );

   beforeEach( () => {
      widgetScope = axMocks.widget.$scope;
      widgetEventBus = axMocks.widget.axEventBus;
      testEventBus = axMocks.eventBus;

      widgetScope.api = {
         updateWithOptions: jasmine.createSpy( 'updateWithOptions' )
      };
   } );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   afterEach( axMocks.tearDown );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   describe( 'with feature timeSeries and feature chart', () => {

      beforeEach( () => {
         testEventBus.publish( 'didReplace.timeSeriesData', {
            resource: 'timeSeriesData',
            data: specData.originalResource
         } );
         testEventBus.flush();

         widgetScope.api.updateWithOptions.calls.reset();
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'acts as a slave of the resource and displays the chart', () => {
         expect( widgetEventBus.subscribe ).toHaveBeenCalledWith(
            'didReplace.timeSeriesData', jasmine.any( Function ) );
         expect( widgetScope.resources.timeSeries ).toEqual( specData.originalResource );
      } );

      /////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'converts the resource data to chart model and displays the chart', () => {
         expect( widgetScope.model.data ).toEqual( specData.expectedChartModel );
      } );

      /////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'sets the labels for chart from resource', () => {
         expect( widgetScope.model.options.chart.xAxis.axisLabel )
            .toEqual( specData.originalResource.timeLabel );
         expect( widgetScope.model.options.chart.yAxis.axisLabel )
            .toEqual( specData.originalResource.valueLabel );
      } );

      /////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'replaces the resource and model after receiving a new resource', () => {
         testEventBus.publish( 'didReplace.timeSeriesData', {
            resource: 'timeSeriesData',
            data: specData.otherResource
         } );
         testEventBus.flush();
         expect( widgetScope.resources.timeSeries ).toEqual( specData.otherResource );
         expect( widgetScope.model.data ).toEqual( specData.expectedChartModelForOtherResource );
      } );

      /////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'updates the resource after receiving a patch with new values only', () => {
         testEventBus.publish( 'didUpdate.timeSeriesData', {
            resource: 'timeSeriesData',
            patches: specData.patchesWithNewValuesOnly
         } );
         testEventBus.flush();
         expect( widgetScope.api.updateWithOptions ).not.toHaveBeenCalled();

         const modifiedChartModel = ax.object.deepClone( specData.expectedChartModel );
         modifiedChartModel[ 0 ].values[ 0 ].y = 32;
         modifiedChartModel[ 1 ].values[ 2 ].y = 22;
         expect( widgetScope.model.data ).toEqual( modifiedChartModel );
      } );

      /////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'updates the resource after receiving a patch with new values and a new label', () => {
         testEventBus.publish( 'didUpdate.timeSeriesData', {
            resource: 'timeSeriesData',
            patches: specData.patchesWithNewValuesAndLabel
         } );
         testEventBus.flush();
         expect( widgetScope.api.updateWithOptions ).toHaveBeenCalled();

         const modifiedChartModel = ax.object.deepClone( specData.expectedChartModel );
         modifiedChartModel[ 0 ].values[ 0 ].y = 32;
         modifiedChartModel[ 1 ].key = 'New Company';
         modifiedChartModel[ 1 ].values[ 2 ].y = 22;
         expect( widgetScope.model.data ).toEqual( modifiedChartModel );
      } );
   } );
} );
describe( 'A table-editor-widget', () => {
   let widgetEventBus;
   let widgetScope;
   let testEventBus;

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   beforeEach( axMocks.setupForWidget() );

   beforeEach( () => {
      axMocks.widget.configure( 'timeSeries.resource', 'timeSeriesData' );
   } );

   beforeEach( axMocks.widget.load );

   beforeEach( () => {
      widgetScope = axMocks.widget.$scope;
      widgetEventBus = axMocks.widget.axEventBus;
      testEventBus = axMocks.eventBus;
   } );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   afterEach( axMocks.tearDown );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   describe( 'with feature timeSeries', () => {

      beforeEach( () => {

         testEventBus.publish( 'didReplace.timeSeriesData', {
            resource: 'timeSeriesData',
            data: specData.originalResource
         } );
         testEventBus.flush();
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'acts as a slave for the configured resource', () => {
         expect( widgetEventBus.subscribe )
               .toHaveBeenCalledWith( 'didReplace.timeSeriesData', jasmine.any( Function ) );
         expect( widgetEventBus.subscribe )
               .toHaveBeenCalledWith( 'didUpdate.timeSeriesData', jasmine.any( Function ) );
         expect( widgetScope.resources.timeSeries ).toEqual( specData.originalResource );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'shows the published resource as the data model of the table', () => {
         expect( widgetScope.model.tableModel ).toEqual( specData.expectedTableModel );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'publishes a didUpdate event after the user changed a data value', () => {
         widgetScope.model.tableModel[ 1 ][ 1 ] = 11;
         widgetScope.$emit( 'axTableEditor.afterChange' );

         const expectedResource = ax.object.deepClone( specData.originalResource );
         expectedResource.series[ 0 ].values[ 0 ] = 11;
         const patch = patterns.json.createPatch( specData.originalResource, expectedResource );

         expect( widgetEventBus.publish )
               .toHaveBeenCalledWith( 'didUpdate.timeSeriesData', {
                  resource: 'timeSeriesData',
                  patches: patch
               }, jasmine.any( Object ) );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'ignores rows on which the time grid tick is removed in the didUpdate event data', () => {
         widgetScope.model.tableModel[ 2 ][ 0 ] = null;
         widgetScope.$emit( 'axTableEditor.afterChange' );

         const expectedResource = specData.expectedResourceWithRemovedTimeGridTick;
         const patch = patterns.json.createPatch( specData.originalResource, expectedResource );

         expect( widgetEventBus.publish )
               .toHaveBeenCalledWith( 'didUpdate.timeSeriesData', {
                  resource: 'timeSeriesData',
                  patches: patch
               }, jasmine.any( Object ) );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'ignores columns on which the series label is removed in the didUpdate event data', () => {
         widgetScope.model.tableModel[ 0 ][ 2 ] = null;
         widgetScope.$emit( 'axTableEditor.afterChange' );

         const expectedResource = specData.expectedResourceWithRemovedSeriesLabel;
         const patch = patterns.json.createPatch( specData.originalResource, expectedResource );

         expect( widgetEventBus.publish )
               .toHaveBeenCalledWith( 'didUpdate.timeSeriesData', {
                  resource: 'timeSeriesData',
                  patches: patch
               }, jasmine.any( Object ) );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'replaces the resource and model after receiving a new resource', () => {
         testEventBus.publish( 'didReplace.timeSeriesData', {
            resource: 'timeSeriesData',
            data: specData.otherResource
         } );
         testEventBus.flush();
         expect( widgetScope.resources.timeSeries ).toEqual( specData.otherResource );
         expect( widgetScope.model.tableModel ).toEqual( specData.expectedTableModelForOtherResource );
      } );
   } );

} );
describe( 'A data-provider-widget', () => {
   let $httpBackend;
   let widgetEventBus;
   let widgetScope;

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   const widgetConfiguration = {
      data: {
         resource: 'timeSeriesData',
         items: [
            {
               title: 'Data-Set-1',
               location: 'data-set-1.json'
            },
            {
               title: 'Data-Set-2',
               location: 'data-set-2.json'
            },
            {
               title: 'Data-Set-Non-Existing',
               location: 'data-set-non-existing.json'
            }
         ]
      }
   };

   beforeEach( axMocks.setupForWidget() );

   beforeEach( () => {
      axMocks.widget.configure( widgetConfiguration );
      axMocks.widget.whenServicesAvailable( () => {
         angular.mock.inject( $injector => {
            $httpBackend = $injector.get( '$httpBackend' );
         } );
      } );
   } );

   beforeEach( axMocks.widget.load );

   beforeEach( () => {
      widgetScope = axMocks.widget.$scope;
      widgetEventBus = axMocks.widget.axEventBus;
   } );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   afterEach( axMocks.tearDown );

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////

   describe( 'with feature data', () => {

      afterEach( () => {
         $httpBackend.verifyNoOutstandingExpectation();
         $httpBackend.verifyNoOutstandingRequest();
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'publishes a didReplace event with the file content of the new location' +
          'when the corresponding button is pressed', () => {
         $httpBackend.expectGET( 'data-set-2.json' ).respond( specData.dataSet2 );

         widgetScope.useItem(widgetConfiguration.data.items[ 1 ] );
         $httpBackend.flush();

         expect( widgetEventBus.publish ).toHaveBeenCalledWith( 'didReplace.timeSeriesData', {
            resource: 'timeSeriesData',
            data: specData.dataSet2
         }, jasmine.any( Object )
         );
      } );

      ////////////////////////////////////////////////////////////////////////////////////////////////////////

      it( 'publishes a didEncounterError event if the new location is not available', () => {
         $httpBackend.expectGET( 'data-set-non-existing.json' ).respond( 404, 'Not Found' );

         widgetScope.useItem(widgetConfiguration.data.items[ 2 ] );
         $httpBackend.flush();

         expect( widgetEventBus.publish ).toHaveBeenCalledWith(
            'didEncounterError.HTTP_GET', jasmine.any( Object ), jasmine.any( Object ) );
      } );

   } );
} );