UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

739 lines 89.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const cloud_assembly_schema_1 = require("@aws-cdk/cloud-assembly-schema"); const client_elastic_load_balancing_v2_1 = require("@aws-sdk/client-elastic-load-balancing-v2"); const api_1 = require("../../lib/api"); const load_balancers_1 = require("../../lib/context-providers/load-balancers"); const mock_sdk_1 = require("../util/mock-sdk"); const mockSDK = new (class extends mock_sdk_1.MockSdkProvider { forEnvironment() { return Promise.resolve({ sdk: new api_1.SDK(mock_sdk_1.FAKE_CREDENTIAL_CHAIN, mockSDK.defaultRegion, {}), didAssumeRole: false }); } })(); beforeEach(() => { (0, mock_sdk_1.restoreSdkMocksToDefault)(); }); describe('load balancer context provider plugin', () => { test('errors when no matches are found', async () => { // GIVEN const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerArn: 'arn:load-balancer1', })).rejects.toThrow('No load balancers found matching {"account":"1234","region":"us-east-1","loadBalancerType":"application","loadBalancerArn":"arn:load-balancer1"}'); }); test('errors when multiple load balancers match', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer1', DNSName: 'dns1.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer2', DNSName: 'dns2.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }); const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [{ key: 'some', value: 'tag' }], })).rejects.toThrow('Multiple load balancers found matching {"account":"1234","region":"us-east-1","loadBalancerType":"application","loadBalancerTags":[{"key":"some","value":"tag"}]} - please provide more specific criteria'); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeTagsCommand, { ResourceArns: ['arn:load-balancer1', 'arn:load-balancer2'], }); }); test('looks up by arn', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client.on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand).resolves({ LoadBalancers: [ { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer1', DNSName: 'dns.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, ], }); const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN const result = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerArn: 'arn:load-balancer1', }); // THEN expect(result.ipAddressType).toEqual('ipv4'); expect(result.loadBalancerArn).toEqual('arn:load-balancer1'); expect(result.loadBalancerCanonicalHostedZoneId).toEqual('Z1234'); expect(result.loadBalancerDnsName).toEqual('dns.example.com'); expect(result.securityGroupIds).toEqual(['sg-1234']); expect(result.vpcId).toEqual('vpc-1234'); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: ['arn:load-balancer1'], }); }); test('looks up by tags', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer1', DNSName: 'dns1.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer2', DNSName: 'dns2.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [ { Key: 'some', Value: 'tag' }, { Key: 'second', Value: 'tag2' }, ], }, ], }); const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN const result = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [ { key: 'some', value: 'tag' }, { key: 'second', value: 'tag2' }, ], }); expect(result.loadBalancerArn).toEqual('arn:load-balancer2'); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeTagsCommand, { ResourceArns: ['arn:load-balancer1', 'arn:load-balancer2'], }); }); test('looks up by tags - query by subset', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer2', DNSName: 'dns2.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer2', Tags: [ // Load balancer has two tags... { Key: 'some', Value: 'tag' }, { Key: 'second', Value: 'tag2' }, ], }, ], }); const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN const result = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [ // ...but we are querying for only one of them { key: 'second', value: 'tag2' }, ], }); expect(result.loadBalancerArn).toEqual('arn:load-balancer2'); }); test('filters by type', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { IpAddressType: 'ipv4', Type: 'network', LoadBalancerArn: 'arn:load-balancer1', DNSName: 'dns1.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', }, { IpAddressType: 'ipv4', Type: 'application', LoadBalancerArn: 'arn:load-balancer2', DNSName: 'dns2.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }); const provider = new load_balancers_1.LoadBalancerContextProviderPlugin(mockSDK); // WHEN const loadBalancer = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerTags: [{ key: 'some', value: 'tag' }], loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, }); expect(loadBalancer.loadBalancerArn).toEqual('arn:load-balancer2'); }); }); describe('load balancer listener context provider plugin', () => { test('errors when no associated load balancers match', async () => { // GIVEN const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [{ key: 'some', value: 'tag' }], })).rejects.toThrow('No associated load balancers found for load balancer listener query {"account":"1234","region":"us-east-1","loadBalancerType":"application","loadBalancerTags":[{"key":"some","value":"tag"}]}'); }); test('errors when no listeners match', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { LoadBalancerArn: 'arn:load-balancer', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { LoadBalancerArn: 'arn:load-balancer', ListenerArn: 'arn:listener', Port: 80, Protocol: 'HTTP', }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerArn: 'arn:load-balancer', listenerPort: 443, listenerProtocol: cloud_assembly_schema_1.LoadBalancerListenerProtocol.HTTPS, })).rejects.toThrow('No load balancer listeners found matching {"account":"1234","region":"us-east-1","loadBalancerType":"application","loadBalancerArn":"arn:load-balancer","listenerPort":443,"listenerProtocol":"HTTPS"}'); }); test('errors when multiple listeners match', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { LoadBalancerArn: 'arn:load-balancer', Type: 'application', }, { LoadBalancerArn: 'arn:load-balancer2', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { LoadBalancerArn: 'arn:load-balancer', ListenerArn: 'arn:listener', Port: 80, Protocol: 'HTTP', }, { LoadBalancerArn: 'arn:load-balancer2', ListenerArn: 'arn:listener2', Port: 80, Protocol: 'HTTP', }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [{ key: 'some', value: 'tag' }], listenerPort: 80, listenerProtocol: cloud_assembly_schema_1.LoadBalancerListenerProtocol.HTTP, })).rejects.toThrow('Multiple load balancer listeners found matching {"account":"1234","region":"us-east-1","loadBalancerType":"application","loadBalancerTags":[{"key":"some","value":"tag"}],"listenerPort":80,"listenerProtocol":"HTTP"} - please provide more specific criteria'); }); test('looks up by listener arn', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { LoadBalancerArn: 'arn:load-balancer-arn', SecurityGroups: ['sg-1234', 'sg-2345'], Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { ListenerArn: 'arn:listener-arn', LoadBalancerArn: 'arn:load-balancer-arn', Port: 999, }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN const listener = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, listenerArn: 'arn:listener-arn', }); // THEN expect(listener.listenerArn).toEqual('arn:listener-arn'); expect(listener.listenerPort).toEqual(999); expect(listener.securityGroupIds).toEqual(['sg-1234', 'sg-2345']); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: ['arn:load-balancer-arn'], }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeListenersCommand, { ListenerArns: ['arn:listener-arn'], }); }); test('looks up by associated load balancer arn', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { LoadBalancerArn: 'arn:load-balancer-arn1', SecurityGroups: ['sg-1234'], Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { // This one ListenerArn: 'arn:listener-arn1', LoadBalancerArn: 'arn:load-balancer-arn1', Port: 80, }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN const listener = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerArn: 'arn:load-balancer-arn1', }); // THEN expect(listener.listenerArn).toEqual('arn:listener-arn1'); expect(listener.listenerPort).toEqual(80); expect(listener.securityGroupIds).toEqual(['sg-1234']); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: ['arn:load-balancer-arn1'], }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeListenersCommand, { LoadBalancerArn: 'arn:load-balancer-arn1', }); }); test('looks up by associated load balancer tags', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { // This one should have the wrong tags LoadBalancerArn: 'arn:load-balancer-arn1', SecurityGroups: ['sg-1234', 'sg-2345'], Type: 'application', }, { // Expecting this one LoadBalancerArn: 'arn:load-balancer-arn2', SecurityGroups: ['sg-3456', 'sg-4567'], Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { // This one ListenerArn: 'arn:listener-arn1', LoadBalancerArn: 'arn:load-balancer-arn2', Port: 80, }, { ListenerArn: 'arn:listener-arn2', LoadBalancerArn: 'arn:load-balancer-arn2', Port: 999, }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer-arn1', Tags: [], }, { // Expecting this one ResourceArn: 'arn:load-balancer-arn2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN const listener = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [{ key: 'some', value: 'tag' }], listenerPort: 999, }); // THEN expect(listener.listenerArn).toEqual('arn:listener-arn2'); expect(listener.listenerPort).toEqual(999); expect(listener.securityGroupIds).toEqual(['sg-3456', 'sg-4567']); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: undefined, }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeListenersCommand, { LoadBalancerArn: 'arn:load-balancer-arn2', }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeTagsCommand, { ResourceArns: ['arn:load-balancer-arn1', 'arn:load-balancer-arn2'], }); }); test('looks up by listener port and protocol', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { // Shouldn't have any matching listeners IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer1', DNSName: 'dns1.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-1234'], VpcId: 'vpc-1234', Type: 'application', }, { // Should have a matching listener IpAddressType: 'ipv4', LoadBalancerArn: 'arn:load-balancer2', DNSName: 'dns2.example.com', CanonicalHostedZoneId: 'Z1234', SecurityGroups: ['sg-2345'], VpcId: 'vpc-1234', Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolvesOnce({ Listeners: [ { // Wrong port, wrong protocol => no match ListenerArn: 'arn:listener-arn1', LoadBalancerArn: 'arn:load-balancer1', Protocol: 'HTTP', Port: 80, }, { // Wrong protocol, right port => no match ListenerArn: 'arn:listener-arn3', LoadBalancerArn: 'arn:load-balancer1', Protocol: 'HTTPS', Port: 443, }, { // Wrong port, right protocol => no match ListenerArn: 'arn:listener-arn4', LoadBalancerArn: 'arn:load-balancer1', Protocol: 'TCP', Port: 999, }, ], }) .resolvesOnce({ Listeners: [ { // Wrong port, wrong protocol => no match ListenerArn: 'arn:listener-arn5', LoadBalancerArn: 'arn:load-balancer2', Protocol: 'HTTP', Port: 80, }, { // Right port, right protocol => match ListenerArn: 'arn:listener-arn6', LoadBalancerArn: 'arn:load-balancer2', Port: 443, Protocol: 'TCP', }, ], }); mock_sdk_1.mockElasticLoadBalancingV2Client.on(client_elastic_load_balancing_v2_1.DescribeTagsCommand).resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN const listener = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.APPLICATION, loadBalancerTags: [{ key: 'some', value: 'tag' }], listenerProtocol: cloud_assembly_schema_1.LoadBalancerListenerProtocol.TCP, listenerPort: 443, }); // THEN expect(listener.listenerArn).toEqual('arn:listener-arn6'); expect(listener.listenerPort).toEqual(443); expect(listener.securityGroupIds).toEqual(['sg-2345']); }); test('filters by associated load balancer type', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { // This one has wrong type => no match LoadBalancerArn: 'arn:load-balancer-arn1', SecurityGroups: [], Type: 'application', }, { // Right type => match LoadBalancerArn: 'arn:load-balancer-arn2', SecurityGroups: [], Type: 'network', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { ListenerArn: 'arn:listener-arn2', LoadBalancerArn: 'arn:load-balancer-arn2', Port: 443, }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeTagsCommand) .resolves({ TagDescriptions: [ { ResourceArn: 'arn:load-balancer-arn1', Tags: [{ Key: 'some', Value: 'tag' }], }, { ResourceArn: 'arn:load-balancer-arn2', Tags: [{ Key: 'some', Value: 'tag' }], }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN const listener = await provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.NETWORK, loadBalancerTags: [{ key: 'some', value: 'tag' }], listenerPort: 443, }); // THEN expect(listener.listenerArn).toEqual('arn:listener-arn2'); expect(listener.listenerPort).toEqual(443); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: undefined, }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeListenersCommand, { LoadBalancerArn: 'arn:load-balancer-arn2', }); }); test('errors when associated load balancer is wrong type', async () => { // GIVEN mock_sdk_1.mockElasticLoadBalancingV2Client .on(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand) .resolves({ LoadBalancers: [ { // This one has wrong type => no match LoadBalancerArn: 'arn:load-balancer-arn1', SecurityGroups: [], Type: 'application', }, ], }) .on(client_elastic_load_balancing_v2_1.DescribeListenersCommand) .resolves({ Listeners: [ { ListenerArn: 'arn:listener-arn1', LoadBalancerArn: 'arn:load-balancer-arn1', Port: 443, }, ], }); const provider = new load_balancers_1.LoadBalancerListenerContextProviderPlugin(mockSDK); // WHEN await expect(provider.getValue({ account: '1234', region: 'us-east-1', loadBalancerType: cloud_assembly_schema_1.LoadBalancerType.NETWORK, listenerArn: 'arn:listener-arn1', })).rejects.toThrow('No associated load balancer found for listener arn arn:listener-arn1'); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeLoadBalancersCommand, { LoadBalancerArns: ['arn:load-balancer-arn1'], }); expect(mock_sdk_1.mockElasticLoadBalancingV2Client).toHaveReceivedCommandWith(client_elastic_load_balancing_v2_1.DescribeListenersCommand, { ListenerArns: ['arn:listener-arn1'], }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC1iYWxhbmNlcnMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxvYWQtYmFsYW5jZXJzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwRUFBZ0c7QUFDaEcsZ0dBSW1EO0FBQ25ELHVDQUF1RDtBQUN2RCwrRUFHb0Q7QUFDcEQsK0NBSzBCO0FBRTFCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFNLFNBQVEsMEJBQWU7SUFDekMsY0FBYztRQUNuQixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxTQUFHLENBQUMsZ0NBQXFCLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNuSCxDQUFDO0NBQ0YsQ0FBQyxFQUFFLENBQUM7QUFFTCxVQUFVLENBQUMsR0FBRyxFQUFFO0lBQ2QsSUFBQSxtQ0FBd0IsR0FBRSxDQUFDO0FBQzdCLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLHVDQUF1QyxFQUFFLEdBQUcsRUFBRTtJQUNyRCxJQUFJLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEQsUUFBUTtRQUNSLE1BQU0sUUFBUSxHQUFHLElBQUksa0RBQWlDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFaEUsT0FBTztRQUNQLE1BQU0sTUFBTSxDQUNWLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDaEIsT0FBTyxFQUFFLE1BQU07WUFDZixNQUFNLEVBQUUsV0FBVztZQUNuQixnQkFBZ0IsRUFBRSx3Q0FBZ0IsQ0FBQyxXQUFXO1lBQzlDLGVBQWUsRUFBRSxvQkFBb0I7U0FDdEMsQ0FBQyxDQUNILENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FDZixrSkFBa0osQ0FDbkosQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLDJDQUEyQyxFQUFFLEtBQUssSUFBSSxFQUFF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