import { assert } from 'chai' ; import { DeviceTypeService } from '../blockchain-facade/DeviceTypeService' ; describe ( 'DeviceTypeService tests' , ( ) => { const deviceTypeService = new DeviceTypeService ( [ [ 'Solar' ] , [ 'Solar' , 'Photovoltaic' ] , [ 'Solar' , 'Photovoltaic' , 'Roof mounted' ] , [ 'Solar' , 'Photovoltaic' , 'Ground mounted' ] , [ 'Solar' , 'Photovoltaic' , 'Classic silicon' ] , [ 'Solar' , 'Concentration' ] , [ 'Wind' ] , [ 'Wind' , 'Onshore' ] , [ 'Wind' , 'Offshore' ] , [ 'Marine' ] , [ 'Marine' , 'Tidal' ] , [ 'Marine' , 'Tidal' , 'Inshore' ] , [ 'Marine' , 'Tidal' , 'Offshore' ] , [ 'Marine' , 'Wave' ] , [ 'Marine' , 'Wave' , 'Onshore' ] , [ 'Marine' , 'Wave' , 'Offshore' ] , [ 'Marine' , 'Currents' ] , [ 'Marine' , 'Pressure' ] , [ 'Marine' , 'Thermal' ] , [ 'Liquid' ] , [ 'Thermal' ] ] ) ; it ( 'should return device type structure' , ( ) => { assert . isNotNull ( deviceTypeService . deviceTypes ) ; } ) ; it ( 'should encode device types' , ( ) => { const encoded = deviceTypeService . encode ( [ [ 'Solar' , 'Concentration' ] , [ 'Wind' , 'Offshore' ] , [ 'Marine' , 'Tidal' , 'Inshore' ] ] ) ; const expectedResult = [ 'Solar;Concentration' , 'Wind;Offshore' , 'Marine;Tidal;Inshore' ] ; assert . deepEqual ( encoded , expectedResult ) ; } ) ; describe ( 'includesDeviceType()' , ( ) => { it ( 'should decode device types' , ( ) => { const decoded = deviceTypeService . decode ( [ 'Solar;Concentration' , 'Wind;Offshore' , 'Marine;Tidal;Inshore' ] ) ; const expectedResult = [ [ 'Solar' , 'Concentration' ] , [ 'Wind' , 'Offshore' ] , [ 'Marine' , 'Tidal' , 'Inshore' ] ] ; assert . deepEqual ( decoded , expectedResult ) ; } ) ; it ( 'should decode device types' , ( ) => { const decoded = deviceTypeService . decode ( [ 'Solar;Concentration' , 'Wind;Offshore' , 'Marine;Tidal;Inshore' ] ) ; const expectedResult = [ [ 'Solar' , 'Concentration' ] , [ 'Wind' , 'Offshore' ] , [ 'Marine' , 'Tidal' , 'Inshore' ] ] ; assert . deepEqual ( decoded , expectedResult ) ; } ) ; it ( 'should find demanded device types when types matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' ] ; const supplyDeviceTypes = 'Solar;Concentration' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should find demanded device types when current has one of matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' , 'Wind' ] ; const supplyDeviceTypes = 'Solar;Concentration' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should not find demanded device types when types matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' ] ; const supplyDeviceTypes = 'Wind;Onshore' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; it ( 'should correctly handle cases where level one types are included with deeper types of the same category' , ( ) => { const TEST_MATRIX = [ [ [ 'Solar' ] , 'Solar;Photovoltaic;Roof mounted' , true ] , [ [ 'Marine' , 'Marine;Tidal' ] , 'Marine;Tidal;Inshore' , true ] , [ [ 'Marine' , 'Marine;Tidal' , 'Marine;Tidal;Offshore' ] , 'Marine;Tidal;Inshore' , false ] , [ [ 'Wind' , 'Wind;Onshore' ] , 'Wind;Onshore' , true ] , [ [ 'Wind' , 'Wind;Onshore' , 'Solar' ] , 'Wind;Onshore' , true ] , [ [ 'Wind' , 'Wind;Onshore' ] , 'Wind;Offshore' , false ] , [ [ 'Wind' , 'Wind;Onshore' , 'Solar;Photovoltaic' ] , 'Wind;Offshore' , false ] , [ [ 'Wind' , 'Wind;Onshore' , 'Wind;Offshore' ] , 'Wind' , false ] , [ [ 'Wind;Onshore' , 'Wind;Offshore' ] , 'Wind' , false ] , [ [ 'Marine' , 'Marine;Tidal' ] , 'Marine' , false ] ] ; for ( const [ deviceTypes , typeToCheck , expectedResult ] of TEST_MATRIX ) { assert . equal ( deviceTypeService . includesDeviceType ( typeToCheck as string , deviceTypes as string [ ] ) , expectedResult ) ; } } ) ; it ( 'should find demanded device types when demanded devices are less specific than current' , ( ) => { const demandDeviceTypes = [ 'Solar' ] ; const supplyDeviceTypes = 'Solar;Photovoltaic;Roof mounted' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should not find demanded device types when demanded devices are more specific than current' , ( ) => { const demandDeviceTypes = [ 'Marine;Tidal;Inshore' ] ; const supplyDeviceTypes = 'Marine;Tidal' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; it ( 'should not find demanded device types when demanded devices are more specific than current' , ( ) => { const demandDeviceTypes = [ 'Marine;Tidal;Inshore' ] ; const supplyDeviceTypes = 'Marine;Tidal' ; const res = deviceTypeService . includesDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; } ) ; describe ( 'includesDeviceTypeMany' , ( ) => { it ( 'should find demanded device types when types matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' ] ; const supplyDeviceTypes = [ 'Solar;Concentration' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should find demanded device types when current has one of matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' , 'Wind' ] ; const supplyDeviceTypes = [ 'Solar;Concentration' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should not find demanded device types when types matches' , ( ) => { const demandDeviceTypes = [ 'Solar;Concentration' ] ; const supplyDeviceTypes = [ 'Wind;Onshore' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; it ( 'should correctly handle cases where level one types are included with deeper types of the same category' , ( ) => { const TEST_MATRIX = [ [ [ 'Solar' ] , [ 'Solar;Photovoltaic;Roof mounted' , 'Wind' ] , true ] , [ [ 'Marine' , 'Marine;Tidal' ] , [ 'Marine;Tidal;Inshore' , 'Solar' ] , true ] , [ [ 'Marine' , 'Marine;Tidal' , 'Marine;Tidal;Offshore' ] , [ 'Marine;Tidal;Inshore' ] , false ] , [ [ 'Wind' , 'Wind;Onshore' ] , [ 'Wind;Onshore' ] , true ] , [ [ 'Wind' , 'Wind;Onshore' , 'Solar' ] , [ 'Wind;Onshore' ] , true ] , [ [ 'Wind' , 'Wind;Onshore' ] , [ 'Wind;Offshore' ] , false ] , [ [ 'Wind' , 'Wind;Onshore' , 'Solar;Photovoltaic' ] , [ 'Wind;Offshore' , 'Marine' ] , false ] , [ [ 'Wind' , 'Wind;Onshore' , 'Wind;Offshore' ] , [ 'Wind' , 'Solar' ] , false ] , [ [ 'Wind;Onshore' , 'Wind;Offshore' ] , [ 'Wind' , 'Solar' ] , false ] , [ [ 'Marine' , 'Marine;Tidal' ] , [ 'Marine' , 'Solar' ] , false ] ] ; for ( const [ deviceTypes , typeToCheck , expectedResult ] of TEST_MATRIX ) { assert . equal ( deviceTypeService . includesSomeDeviceType ( typeToCheck as string [ ] , deviceTypes as string [ ] ) , expectedResult ) ; } } ) ; it ( 'should find demanded device types when demanded devices are less specific than current' , ( ) => { const demandDeviceTypes = [ 'Solar' ] ; const supplyDeviceTypes = [ 'Solar;Photovoltaic;Roof mounted' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isTrue ( res ) ; } ) ; it ( 'should not find demanded device types when demanded devices are more specific than current' , ( ) => { const demandDeviceTypes = [ 'Marine;Tidal;Inshore' ] ; const supplyDeviceTypes = [ 'Marine;Tidal' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; it ( 'should not find demanded device types when demanded devices are more specific than current' , ( ) => { const demandDeviceTypes = [ 'Marine;Tidal;Inshore' ] ; const supplyDeviceTypes = [ 'Marine;Tidal' ] ; const res = deviceTypeService . includesSomeDeviceType ( supplyDeviceTypes , demandDeviceTypes ) ; assert . isFalse ( res ) ; } ) ; } ) ; describe ( 'filterForHighestSpecificity()' , ( ) => { it ( 'returns an empty array when empty array passed' , ( ) => { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( [ ] ) , [ ] ) ; } ) ; it ( 'should preserve level level 1 types if no higher specificity' , ( ) => { const TEST_MATRIX = [ [ [ 'Wind' , 'Solar' , 'Marine' ] , [ 'Wind' , 'Solar' , 'Marine' ] ] , [ [ 'Liquid' ] , [ 'Liquid' ] ] ] ; for ( const [ unfiltered , expectedFiltered ] of TEST_MATRIX ) { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( unfiltered ) , expectedFiltered ) ; } } ) ; it ( 'correctly filters out level 1 types if level 2 types of the same category are present' , ( ) => { const TEST_MATRIX = [ [ [ 'Solar' , 'Solar;Photovoltaic' ] , [ 'Solar;Photovoltaic' ] ] , [ [ 'Solar' , 'Solar;Photovoltaic' , 'Wind' ] , [ 'Solar;Photovoltaic' , 'Wind' ] ] , [ [ 'Solar' , 'Solar;Photovoltaic' , 'Wind' , 'Wind;Onshore' ] , [ 'Solar;Photovoltaic' , 'Wind;Onshore' ] ] ] ; for ( const [ unfiltered , expectedFiltered ] of TEST_MATRIX ) { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( unfiltered ) , expectedFiltered ) ; } } ) ; it ( 'should preserve level 2 types if level 1 type of the same category is not present' , ( ) => { const TEST_MATRIX = [ [ [ 'Wind;Offshore' , 'Wind;Onshore' ] , [ 'Wind;Offshore' , 'Wind;Onshore' ] ] , [ [ 'Solar' , 'Solar;Photovoltaic' , 'Wind;Offshore' , 'Wind;Onshore' ] , [ 'Solar;Photovoltaic' , 'Wind;Offshore' , 'Wind;Onshore' ] ] ] ; for ( const [ unfiltered , expectedFiltered ] of TEST_MATRIX ) { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( unfiltered ) , expectedFiltered ) ; } } ) ; it ( 'correctly filters out level 1 and 2 types if level 3 types of the same category are present' , ( ) => { const TEST_MATRIX = [ [ [ 'Solar' , 'Solar;Photovoltaic' , 'Solar;Photovoltaic;Roof mounted' ] , [ 'Solar;Photovoltaic;Roof mounted' ] ] , [ [ 'Solar' , 'Solar;Photovoltaic' , 'Solar;Photovoltaic;Roof mounted' , 'Marine' , 'Marine;Tidal' , 'Marine;Tidal;Inshore' ] , [ 'Solar;Photovoltaic;Roof mounted' , 'Marine;Tidal;Inshore' ] ] ] ; for ( const [ unfiltered , expectedFiltered ] of TEST_MATRIX ) { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( unfiltered ) , expectedFiltered ) ; } } ) ; it ( 'should preserve level 3 types if level 2 type of the same category is not present' , ( ) => { const TEST_MATRIX = [ [ [ 'Solar;Photovoltaic;Roof mounted' ] , [ 'Solar;Photovoltaic;Roof mounted' ] ] , [ [ 'Solar;Photovoltaic;Roof mounted' , 'Marine;Tidal;Inshore' ] , [ 'Solar;Photovoltaic;Roof mounted' , 'Marine;Tidal;Inshore' ] ] ] ; for ( const [ unfiltered , expectedFiltered ] of TEST_MATRIX ) { assert . deepEqual ( deviceTypeService . filterForHighestSpecificity ( unfiltered ) , expectedFiltered ) ; } } ) ; } ) ; } ) ;