@@ -10,11 +10,14 @@ import (
1010 "github.com/stretchr/testify/assert"
1111 "github.com/stretchr/testify/require"
1212
13+ "github.com/openmeterio/openmeter/openmeter/app"
1314 "github.com/openmeterio/openmeter/openmeter/meter"
1415 "github.com/openmeterio/openmeter/openmeter/productcatalog"
1516 "github.com/openmeterio/openmeter/openmeter/productcatalog/addon"
1617 "github.com/openmeterio/openmeter/openmeter/productcatalog/feature"
1718 pctestutils "github.com/openmeterio/openmeter/openmeter/productcatalog/testutils"
19+ "github.com/openmeterio/openmeter/openmeter/taxcode"
20+ tctestutils "github.com/openmeterio/openmeter/openmeter/taxcode/testutils"
1821 "github.com/openmeterio/openmeter/openmeter/testutils"
1922 "github.com/openmeterio/openmeter/pkg/clock"
2023 "github.com/openmeterio/openmeter/pkg/datetime"
@@ -438,5 +441,108 @@ func TestPostgresAdapter(t *testing.T) {
438441 })
439442 }
440443 })
444+
445+ t .Run ("ListTaxCodeFilter" , func (t * testing.T ) {
446+ testListAddonTaxCodeFilter (t , env )
447+ })
448+ })
449+ }
450+
451+ func testListAddonTaxCodeFilter (t * testing.T , env * pctestutils.TestEnv ) {
452+ t .Helper ()
453+
454+ ns := pctestutils .NewTestNamespace (t )
455+
456+ // Create two tax codes with distinct Stripe app mappings so the add-on service
457+ // can resolve them and populate the rate-card tax_code_id FK.
458+ tcEnv := tctestutils .NewTestEnvFromClient (t , env .Client , env .Logger )
459+
460+ taxA := tcEnv .CreateTaxCode (t , ns , taxcode.CreateTaxCodeInput {
461+ Key : "tax-a" ,
462+ Name : "Tax A" ,
463+ AppMappings : taxcode.TaxCodeAppMappings {
464+ {AppType : app .AppTypeStripe , TaxCode : "txcd_20000001" },
465+ },
466+ })
467+
468+ taxB := tcEnv .CreateTaxCode (t , ns , taxcode.CreateTaxCodeInput {
469+ Key : "tax-b" ,
470+ Name : "Tax B" ,
471+ AppMappings : taxcode.TaxCodeAppMappings {
472+ {AppType : app .AppTypeStripe , TaxCode : "txcd_20000002" },
473+ },
474+ })
475+
476+ // Helper: build a minimal add-on input with a FlatFeeRateCard referencing the given taxCodeID.
477+ makeAddonInput := func (key string , taxCodeID string ) addon.CreateAddonInput {
478+ input := pctestutils .NewTestAddon (t , ns ,
479+ & productcatalog.FlatFeeRateCard {
480+ RateCardMeta : productcatalog.RateCardMeta {
481+ Key : "rc-1" ,
482+ Name : "RC 1" ,
483+ TaxConfig : & productcatalog.TaxConfig {
484+ TaxCodeID : lo .ToPtr (taxCodeID ),
485+ },
486+ },
487+ },
488+ )
489+ input .Addon .AddonMeta .Key = key
490+ return input
491+ }
492+
493+ // given: two add-ons each referencing a different tax code
494+ addonA , err := env .Addon .CreateAddon (t .Context (), makeAddonInput ("addon-a" , taxA .ID ))
495+ require .NoError (t , err , "creating addonA must not fail" )
496+
497+ addonB , err := env .Addon .CreateAddon (t .Context (), makeAddonInput ("addon-b" , taxB .ID ))
498+ require .NoError (t , err , "creating addonB must not fail" )
499+
500+ t .Run ("filter by taxA returns only addonA" , func (t * testing.T ) {
501+ // when: listing add-ons filtered by taxA
502+ result , err := env .AddonRepository .ListAddons (t .Context (), addon.ListAddonsInput {
503+ Namespaces : []string {ns },
504+ TaxCodes : & filter.FilterString {In : lo .ToPtr ([]string {taxA .ID })},
505+ Page : pagination.Page {PageSize : 100 , PageNumber : 1 },
506+ })
507+
508+ // then: only addonA is returned
509+ require .NoError (t , err )
510+ ids := addonIDs (result )
511+ require .ElementsMatch (t , []string {addonA .ID }, ids )
512+ })
513+
514+ t .Run ("filter by taxB returns only addonB" , func (t * testing.T ) {
515+ // when: listing add-ons filtered by taxB
516+ result , err := env .AddonRepository .ListAddons (t .Context (), addon.ListAddonsInput {
517+ Namespaces : []string {ns },
518+ TaxCodes : & filter.FilterString {In : lo .ToPtr ([]string {taxB .ID })},
519+ Page : pagination.Page {PageSize : 100 , PageNumber : 1 },
520+ })
521+
522+ // then: only addonB is returned
523+ require .NoError (t , err )
524+ ids := addonIDs (result )
525+ require .ElementsMatch (t , []string {addonB .ID }, ids )
441526 })
527+
528+ t .Run ("filter by nonexistent tax code returns empty" , func (t * testing.T ) {
529+ // when: listing add-ons filtered by a tax code id that doesn't exist
530+ result , err := env .AddonRepository .ListAddons (t .Context (), addon.ListAddonsInput {
531+ Namespaces : []string {ns },
532+ TaxCodes : & filter.FilterString {In : lo .ToPtr ([]string {"01000000000000000000000000" })},
533+ Page : pagination.Page {PageSize : 100 , PageNumber : 1 },
534+ })
535+
536+ // then: no add-ons are returned
537+ require .NoError (t , err )
538+ require .Empty (t , result .Items )
539+ })
540+ }
541+
542+ func addonIDs (result pagination.Result [addon.Addon ]) []string {
543+ ids := make ([]string , 0 , len (result .Items ))
544+ for _ , a := range result .Items {
545+ ids = append (ids , a .ID )
546+ }
547+ return ids
442548}
0 commit comments