diff --git a/internal/graphql/resolver/stock_plasmid_fp.go b/internal/graphql/resolver/stock_plasmid_fp.go index 01d1f506..c9df4ae1 100644 --- a/internal/graphql/resolver/stock_plasmid_fp.go +++ b/internal/graphql/resolver/stock_plasmid_fp.go @@ -127,23 +127,9 @@ func computeListPlasmidParams( } func buildListPlasmidFilterQuery(ctx withListPlasmidParams) IOE.IOEither[error, string] { - return F.Pipe2( - ctx.filter, - func(filter *models.PlasmidListFilter) E.Either[error, string] { - if filter == nil { - return E.Right[error]("") - } - return F.Pipe5( - filter, - resolverutils.CheckIDField, - E.Chain(resolverutils.CheckInStockField), - E.Chain(resolverutils.CheckUnverifiedPlasmidType), - E.Chain(resolverutils.CheckValidPlasmidType), - E.Map[error](resolverutils.BuildPlasmidFieldQuery), - ) - }, - IOE.FromEither[error, string], - ) + return IOE.TryCatchError(func() (string, error) { + return resolverutils.PlasmidFilterToQuery(ctx.filter) + }) } func fetchListPlasmidCollection( diff --git a/internal/graphql/resolver/stock_test.go b/internal/graphql/resolver/stock_test.go index 0a71aa85..c5640d89 100644 --- a/internal/graphql/resolver/stock_test.go +++ b/internal/graphql/resolver/stock_test.go @@ -629,42 +629,64 @@ func TestListPlasmidsUnsupportedIDFilter(t *testing.T) { require.Empty(result.Plasmids) } -func TestListPlasmidsUnverifiedRegularTypeFilter(t *testing.T) { +func TestListPlasmidsRegularTypeFilter(t *testing.T) { t.Parallel() require := require.New(t) - resolver := &QueryResolver{ - Registry: &mocks.MockRegistry{}, - Logger: mocks.TestLogger(), + mockedStockClient := new(clients.StockServiceClient) + mockedStockClient.On( + "ListPlasmids", + mock.MatchedBy(func(ctx context.Context) bool { return true }), + mock.MatchedBy(func(params *pb.StockParameters) bool { + return params.Cursor == 0 && + params.Limit == 10 && + params.Filter == "ontology==dicty_plasmid_keyword;tag==vector" + }), + ).Return(mocks.MockPlasmidCollection(), nil) + + reg := &stockClientRegistry{ + MockRegistry: &mocks.MockRegistry{ConnMap: nil}, + stockClient: mockedStockClient, } + resolver := &QueryResolver{Registry: reg, Logger: mocks.TestLogger()} cursor := 0 limit := 10 - ctx := graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover) - result, err := resolver.ListPlasmids(ctx, &cursor, &limit, &models.PlasmidListFilter{ + result, err := resolver.ListPlasmids(context.Background(), &cursor, &limit, &models.PlasmidListFilter{ PlasmidType: models.PlasmidTypeRegular, }) - require.Error(err) - require.Contains(err.Error(), "plasmid_type filter is not yet verified") - require.Empty(result.Plasmids) + require.NoError(err) + require.Len(result.Plasmids, 3) + mockedStockClient.AssertExpectations(t) } -func TestListPlasmidsUnverifiedGoldenBraidTypeFilter(t *testing.T) { +func TestListPlasmidsGoldenBraidTypeFilter(t *testing.T) { t.Parallel() require := require.New(t) - resolver := &QueryResolver{ - Registry: &mocks.MockRegistry{}, - Logger: mocks.TestLogger(), + mockedStockClient := new(clients.StockServiceClient) + mockedStockClient.On( + "ListPlasmids", + mock.MatchedBy(func(ctx context.Context) bool { return true }), + mock.MatchedBy(func(params *pb.StockParameters) bool { + return params.Cursor == 0 && + params.Limit == 10 && + params.Filter == "ontology==dicty_plasmid_keyword;tag==GB vector" + }), + ).Return(mocks.MockPlasmidCollection(), nil) + + reg := &stockClientRegistry{ + MockRegistry: &mocks.MockRegistry{ConnMap: nil}, + stockClient: mockedStockClient, } + resolver := &QueryResolver{Registry: reg, Logger: mocks.TestLogger()} cursor := 0 limit := 10 - ctx := graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover) - result, err := resolver.ListPlasmids(ctx, &cursor, &limit, &models.PlasmidListFilter{ + result, err := resolver.ListPlasmids(context.Background(), &cursor, &limit, &models.PlasmidListFilter{ PlasmidType: models.PlasmidTypeGoldenBraid, }) - require.Error(err) - require.Contains(err.Error(), "plasmid_type filter is not yet verified") - require.Empty(result.Plasmids) + require.NoError(err) + require.Len(result.Plasmids, 3) + mockedStockClient.AssertExpectations(t) } diff --git a/internal/graphql/resolverutils/plasmid_filter.go b/internal/graphql/resolverutils/plasmid_filter.go index e96436c3..427db6f5 100644 --- a/internal/graphql/resolverutils/plasmid_filter.go +++ b/internal/graphql/resolverutils/plasmid_filter.go @@ -5,21 +5,19 @@ package resolverutils import ( "fmt" + "strings" A "github.com/IBM/fp-go/v2/array" E "github.com/IBM/fp-go/v2/either" - eq "github.com/IBM/fp-go/v2/eq" F "github.com/IBM/fp-go/v2/function" O "github.com/IBM/fp-go/v2/option" P "github.com/IBM/fp-go/v2/predicate" S "github.com/IBM/fp-go/v2/string" - "github.com/dictyBase/graphql-server/internal/graphql/models" + "github.com/dictyBase/graphql-server/internal/registry" ) var ( - plasmidTypeEq = eq.FromStrictEquals[models.PlasmidType]() - isNilID = F.Pipe1( P.IsZero[*string](), P.ContraMap(func(f *models.PlasmidListFilter) *string { @@ -51,56 +49,55 @@ var ( ) }, ) +) - isRegularPlasmidType = eq.Equals(plasmidTypeEq)(models.PlasmidTypeRegular) - isGoldenBraidPlasmidType = eq.Equals(plasmidTypeEq)(models.PlasmidTypeGoldenBraid) - isUnverifiedPlasmidType = F.Pipe2( - isRegularPlasmidType, - P.Or(isGoldenBraidPlasmidType), - P.ContraMap(func(f *models.PlasmidListFilter) models.PlasmidType { - return f.PlasmidType - }), - ) - CheckUnverifiedPlasmidType = E.FromPredicate( - P.Not(isUnverifiedPlasmidType), - func(filter *models.PlasmidListFilter) error { - return fmt.Errorf( - "plasmid list filter %v: plasmid_type filter is not yet verified for stock query conversion", - filter, - ) - }, - ) - - isAllPlasmidType = F.Pipe1( - eq.Equals(plasmidTypeEq)(models.PlasmidTypeAll), - P.ContraMap(func(f *models.PlasmidListFilter) models.PlasmidType { - return f.PlasmidType - }), - ) - CheckValidPlasmidType = E.FromPredicate( - isAllPlasmidType, - func(f *models.PlasmidListFilter) error { - return fmt.Errorf("invalid plasmid type %s", f.PlasmidType.String()) - }, - ) +func PlasmidFilterToQuery(filter *models.PlasmidListFilter) (string, error) { + if filter == nil { + return "", nil + } - validateFilterPipeline = F.Flow5( + if _, err := E.UnwrapError(F.Pipe2( + filter, CheckIDField, E.Chain(CheckInStockField), - E.Chain(CheckUnverifiedPlasmidType), - E.Chain(CheckValidPlasmidType), - E.Map[error](BuildPlasmidFieldQuery), - ) -) + )); err != nil { + return "", err + } -func PlasmidFilterToQuery(filter *models.PlasmidListFilter) (string, error) { - return E.UnwrapError(F.Pipe1( - O.FromNillable(filter), - O.Fold( - F.Constant(E.Right[error]("")), - validateFilterPipeline, - ), - )) + fieldQuery := BuildPlasmidFieldQuery(filter) + typeQuery, err := plasmidTypeQuery(filter) + if err != nil { + return fieldQuery, err + } + if fieldQuery == "" { + return typeQuery, nil + } + if typeQuery == "" { + return fieldQuery, nil + } + + return strings.Join([]string{fieldQuery, typeQuery}, ";"), nil +} + +func plasmidTypeQuery(filter *models.PlasmidListFilter) (string, error) { + switch filter.PlasmidType { + case models.PlasmidTypeAll: + return "", nil + case models.PlasmidTypeRegular: + return fmt.Sprintf( + "ontology==%s;tag==%s", + registry.DictyPlasmidPropOntology, + registry.RegularPlasmidTag, + ), nil + case models.PlasmidTypeGoldenBraid: + return fmt.Sprintf( + "ontology==%s;tag==%s", + registry.DictyPlasmidPropOntology, + registry.GoldenBraidPlasmidTag, + ), nil + default: + return "", fmt.Errorf("invalid plasmid type %s", filter.PlasmidType.String()) + } } func BuildPlasmidFieldQuery(filter *models.PlasmidListFilter) string { diff --git a/internal/graphql/resolverutils/plasmid_filter_test.go b/internal/graphql/resolverutils/plasmid_filter_test.go index abab0318..13e625c0 100644 --- a/internal/graphql/resolverutils/plasmid_filter_test.go +++ b/internal/graphql/resolverutils/plasmid_filter_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/dictyBase/graphql-server/internal/graphql/models" + "github.com/dictyBase/graphql-server/internal/registry" "github.com/stretchr/testify/require" ) @@ -58,22 +59,45 @@ func TestPlasmidFilterToQueryPlasmidTypeAllOnly(t *testing.T) { require.Equal(t, "", query) } -func TestPlasmidFilterToQueryPlasmidTypeRegularUnverified(t *testing.T) { +func TestPlasmidFilterToQueryPlasmidTypeRegularOnly(t *testing.T) { t.Parallel() - _, err := PlasmidFilterToQuery(&models.PlasmidListFilter{ + query, err := PlasmidFilterToQuery(&models.PlasmidListFilter{ PlasmidType: models.PlasmidTypeRegular, }) - require.Error(t, err) - require.Contains(t, err.Error(), "plasmid_type filter is not yet verified") + require.NoError(t, err) + require.Equal( + t, + "ontology=="+registry.DictyPlasmidPropOntology+";tag=="+registry.RegularPlasmidTag, + query, + ) } -func TestPlasmidFilterToQueryPlasmidTypeGoldenBraidUnverified(t *testing.T) { +func TestPlasmidFilterToQueryPlasmidTypeGoldenBraidOnly(t *testing.T) { t.Parallel() - _, err := PlasmidFilterToQuery(&models.PlasmidListFilter{ + query, err := PlasmidFilterToQuery(&models.PlasmidListFilter{ PlasmidType: models.PlasmidTypeGoldenBraid, }) - require.Error(t, err) - require.Contains(t, err.Error(), "plasmid_type filter is not yet verified") + require.NoError(t, err) + require.Equal( + t, + "ontology=="+registry.DictyPlasmidPropOntology+";tag=="+registry.GoldenBraidPlasmidTag, + query, + ) +} + +func TestPlasmidFilterToQueryCombinedSummaryAndRegularType(t *testing.T) { + t.Parallel() + summary := "test" + query, err := PlasmidFilterToQuery(&models.PlasmidListFilter{ + Summary: &summary, + PlasmidType: models.PlasmidTypeRegular, + }) + require.NoError(t, err) + require.Equal( + t, + "summary=~test;ontology=="+registry.DictyPlasmidPropOntology+";tag=="+registry.RegularPlasmidTag, + query, + ) } func TestPlasmidFilterToQueryInvalidPlasmidType(t *testing.T) { diff --git a/internal/registry/registry.go b/internal/registry/registry.go index 632f9d51..5f7985ab 100644 --- a/internal/registry/registry.go +++ b/internal/registry/registry.go @@ -39,8 +39,8 @@ const ( MutmethodTag = "mutagenesis method" MuttypeTag = "mutant type" GenoTag = "genotype" - GoldenBraidPlasmidTag = "golden braid" - RegularPlasmidTag = "regular plasmid" + GoldenBraidPlasmidTag = "GB vector" + RegularPlasmidTag = "vector" SynTag = "synonym" EmptyValue = "novalue" S3Bucket = "s3bucket"