github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/processors/query/query-params-impl_test.go (about)

     1  /*
     2   * Copyright (c) 2021-present unTill Pro, Ltd.
     3   */
     4  
     5  package queryprocessor
     6  
     7  import (
     8  	"context"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/voedger/voedger/pkg/appparts"
    13  	"github.com/voedger/voedger/pkg/iauthnzimpl"
    14  	"github.com/voedger/voedger/pkg/iprocbus"
    15  	"github.com/voedger/voedger/pkg/istructs"
    16  	"github.com/voedger/voedger/pkg/itokensjwt"
    17  	imetrics "github.com/voedger/voedger/pkg/metrics"
    18  	ibus "github.com/voedger/voedger/staging/src/github.com/untillpro/airs-ibus"
    19  )
    20  
    21  func TestWrongTypes(t *testing.T) {
    22  	require := require.New(t)
    23  	serviceChannel := make(iprocbus.ServiceChannel)
    24  	errs := make(chan error)
    25  	resultSenderClosableFactory := func(ctx context.Context, sender ibus.ISender) IResultSenderClosable {
    26  		return &testResultSenderClosable{
    27  			startArraySection: func(sectionType string, path []string) { t.Fatal() },
    28  			sendElement:       func(name string, element interface{}) (err error) { t.Fatal(); return nil },
    29  			close: func(err error) {
    30  				errs <- err
    31  			},
    32  		}
    33  	}
    34  	done := make(chan struct{})
    35  	authn := iauthnzimpl.NewDefaultAuthenticator(iauthnzimpl.TestSubjectRolesGetter, iauthnzimpl.TestIsDeviceAllowedFuncs)
    36  	authz := iauthnzimpl.NewDefaultAuthorizer()
    37  
    38  	appDef, appStructsProvider, appTokens := getTestCfg(require, nil)
    39  
    40  	appParts, cleanAppParts, err := appparts.New(appStructsProvider)
    41  	require.NoError(err)
    42  	defer cleanAppParts()
    43  	appParts.DeployApp(appName, appDef, partCount, appEngines)
    44  	appParts.DeployAppPartitions(appName, []istructs.PartitionID{partID})
    45  
    46  	queryProcessor := ProvideServiceFactory()(
    47  		serviceChannel,
    48  		resultSenderClosableFactory,
    49  		appParts,
    50  		3, // maxPrepareQueries
    51  		imetrics.Provide(), "vvm", authn, authz, itokensjwt.TestTokensJWT(), nil)
    52  	ctx, cancel := context.WithCancel(context.Background())
    53  	go func() {
    54  		queryProcessor.Run(ctx)
    55  		close(done)
    56  	}()
    57  
    58  	tests := []struct {
    59  		name string
    60  		body string
    61  		err  string
    62  	}{
    63  		{
    64  			name: "Elements must be an array",
    65  			body: `{"elements":{}}`,
    66  			err:  "elements: field 'elements' must be an array of objects: field type mismatch",
    67  		},
    68  		{
    69  			name: "Element must be an object",
    70  			body: `{"elements":[45]}`,
    71  			err:  "elements: each member must be an object: wrong type",
    72  		},
    73  		{
    74  			name: "Element path is wrong",
    75  			body: `{"elements":[{"path":45}]}`,
    76  			err:  "elements: element: field 'path' must be a string: field type mismatch",
    77  		},
    78  		{
    79  			name: "Element fields must be an array",
    80  			body: `{"elements":[{"fields":{}}]}`,
    81  			err:  "elements: element: field 'fields' must be an array of objects: field type mismatch",
    82  		},
    83  		{
    84  			name: "Element fields must be a string or an array of strings",
    85  			body: `{"elements":[{"fields":[4]}]}`,
    86  			err:  "elements: element: must be a sting or an array of strings: wrong type",
    87  		},
    88  		{
    89  			name: "Element refs must be an array",
    90  			body: `{"elements":[{"refs":{}}]}`,
    91  			err:  "elements: element: field 'refs' must be an array of objects: field type mismatch",
    92  		},
    93  		{
    94  			name: "Ref field parameters length must be 2",
    95  			body: `{"elements":[{"refs":[[]]}]}`,
    96  			err:  "elements: element: field 'ref' parameters length must be 2 but got 0",
    97  		},
    98  		{
    99  			name: "Ref field parameters type must be a string",
   100  			body: `{"elements":[{"refs":[["id",1]]}]}`,
   101  			err:  "elements: element: field 'ref' parameter must a string: wrong type",
   102  		},
   103  		{
   104  			name: "Ref field parameters type must be a string",
   105  			body: `{"elements":[{"refs":[[1,1]]}]}`,
   106  			err:  "elements: element: field 'ref' parameter must a string",
   107  		},
   108  		{
   109  			name: "Filters must be an array",
   110  			body: `{"filters":{}}`,
   111  			err:  "filters: field 'filters' must be an array of objects: field type mismatch",
   112  		},
   113  		{
   114  			name: "Filter args not found",
   115  			body: `{"filters":[{}]}`,
   116  			err:  "filters: filter: field 'args' must be present: not found",
   117  		},
   118  		{
   119  			name: "Filter expr not found",
   120  			body: `{"filters":[{"args":{}}]}`,
   121  			err:  "filters: filter: field 'expr' missing: fields are missed",
   122  		},
   123  		{
   124  			name: "Filter expr is unknown",
   125  			body: `{"filters":[{"args":{},"expr":"<<<"}]}`,
   126  			err:  "filters: filter: expr: filter '<<<' is unknown: wrong type",
   127  		},
   128  		{
   129  			name: "Filter field must be present",
   130  			body: `{"filters":[{"expr":"eq","args":{}}]}`,
   131  			err:  "filters: 'eq' filter: field 'field' missing: fields are missed",
   132  		},
   133  		{
   134  			name: "Filter value must be present",
   135  			body: `{"filters":[{"expr":"eq","args":{"field":"id"}}]}`,
   136  			err:  "filters: 'eq' filter: field 'value' must be present: not found",
   137  		},
   138  		{
   139  			name: "Equals filter wrong args",
   140  			body: `{"filters":[{"expr":"eq","args":""}]}`,
   141  			err:  "filters: 'eq' filter: field 'args' must be an object: wrong type",
   142  		},
   143  		{
   144  			name: "Equals filter options must be an object",
   145  			body: `{"filters":[{"expr":"eq","args":{"field":"id","value":1,"options":[]}}]}`,
   146  			err:  "filters: 'eq' filter: field 'options' must be an object: field type mismatch",
   147  		},
   148  		{
   149  			name: "Equals filter epsilon must be a float64",
   150  			body: `{"filters":[{"expr":"eq","args":{"field":"id","value":1,"options":{"epsilon":"wrong"}}}]}`,
   151  			err:  "filters: 'eq' filter: field 'epsilon' must be a float64: field type mismatch",
   152  		},
   153  		{
   154  			name: "Not equals filter wrong args",
   155  			body: `{"filters":[{"expr":"notEq","args":""}]}`,
   156  			err:  "filters: 'notEq' filter: field 'args' must be an object: wrong type",
   157  		},
   158  		{
   159  			name: "Not equals filter epsilon must be a float64",
   160  			body: `{"filters":[{"expr":"notEq","args":{"field":"id","value":1,"options":{"epsilon":"wrong"}}}]}`,
   161  			err:  "filters: 'notEq' filter: field 'epsilon' must be a float64: field type mismatch",
   162  		},
   163  		{
   164  			name: "Greater filter wrong args",
   165  			body: `{"filters":[{"expr":"gt","args":""}]}`,
   166  			err:  "filters: 'gt' filter: field 'args' must be an object: wrong type",
   167  		},
   168  		{
   169  			name: "Less filter wrong args",
   170  			body: `{"filters":[{"expr":"lt","args":""}]}`,
   171  			err:  "filters: 'lt' filter: field 'args' must be an object: wrong type",
   172  		},
   173  		{
   174  			name: "And filter wrong args",
   175  			body: `{"filters":[{"expr":"and","args":""}]}`,
   176  			err:  "filters: 'and' filter: field 'args' must be an array: wrong type",
   177  		},
   178  		{
   179  			name: "And filter wrong member",
   180  			body: `{"filters":[{"expr":"and","args":[""]}]}`,
   181  			err:  "filters: 'and' filter: each 'args' member must be an object: wrong type",
   182  		},
   183  		{
   184  			name: "And filter error in member",
   185  			body: `{"filters":[{"expr":"and","args":[{}]}]}`,
   186  			err:  "filters: 'and' filter: filter: field 'args' must be present: not found",
   187  		},
   188  		{
   189  			name: "Or filter wrong args",
   190  			body: `{"filters":[{"expr":"or","args":""}]}`,
   191  			err:  "filters: 'or' filter: field 'args' must be an array: wrong type",
   192  		},
   193  		{
   194  			name: "Or filter wrong member",
   195  			body: `{"filters":[{"expr":"or","args":[""]}]}`,
   196  			err:  "filters: 'or' filter: each 'args' member must be an object: wrong type",
   197  		},
   198  		{
   199  			name: "Or filter error in member",
   200  			body: `{"filters":[{"expr":"or","args":[{}]}]}`,
   201  			err:  "filters: 'or' filter: filter: field 'args' must be present: not found",
   202  		},
   203  		{
   204  			name: "And filter error in equals filter",
   205  			body: `{"filters":[{"expr":"and","args":[{"expr":"eq","args":{"field":"wrong","value":"wrong"}}]}]}`,
   206  			err:  "filters: 'and' filter: 'eq' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   207  		},
   208  		{
   209  			name: "Or filter error in equals filter",
   210  			body: `{"filters":[{"expr":"or","args":[{"expr":"eq","args":{"field":"wrong","value":"wrong"}}]}]}`,
   211  			err:  "filters: 'or' filter: 'eq' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   212  		},
   213  		{
   214  			name: "And filter error in first equals filter",
   215  			body: `{"elements":[{"fields":["sys.ID"]}],"filters":[{"expr":"and","args":[{"expr":"eq","args":{"field":"wrong","value":"wrong"}},{"expr":"eq","args":{"field":"sys.ID","value":1}}]}]}`,
   216  			err:  "filters: 'and' filter: 'eq' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   217  		},
   218  		{
   219  			name: "OrderBy must be an array",
   220  			body: `{"orderBy":{}}`,
   221  			err:  "orderBy: field 'orderBy' must be an array of objects: field type mismatch",
   222  		},
   223  		{
   224  			name: "OrderBy field not found",
   225  			body: `{"orderBy":[{}]}`,
   226  			err:  "orderBy: orderBy: field 'field' missing: fields are missed",
   227  		},
   228  		{
   229  			name: "OrderBy desc must be a boolean",
   230  			body: `{"orderBy":[{"field":"","desc":"wrong"}]}`,
   231  			err:  "orderBy: orderBy: field 'desc' must be a boolean: field type mismatch",
   232  		},
   233  		{
   234  			name: "Count must be a int64",
   235  			body: `{"count":{}}`,
   236  			err:  "field 'count' must be an int64: field type mismatch",
   237  		},
   238  		{
   239  			name: "StartFrom must be a int64",
   240  			body: `{"startFrom":{}}`,
   241  			err:  "field 'startFrom' must be an int64: field type mismatch",
   242  		},
   243  		{
   244  			name: "Root element fields must be present in result fields",
   245  			body: `{"elements":[{"path":"not/root"},{"fields":["wrong"]}]}`,
   246  			err:  "elements: root element fields has field 'wrong' that is unexpected in root fields, please remove it: unexpected",
   247  		},
   248  		{
   249  			name: "Equals filter field must be present in root element fields/refs",
   250  			body: `{"elements":[{"fields":["sys.ID"]}],"filters":[{"expr":"eq","args":{"field":"wrong","value":1}}]}`,
   251  			err:  "filters: 'eq' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   252  		},
   253  		{
   254  			name: "Not equals filter field must be present in root element fields/refs",
   255  			body: `{"elements":[{"fields":["sys.ID"]}],"filters":[{"expr":"notEq","args":{"field":"wrong","value":1}}]}`,
   256  			err:  "filters: 'notEq' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   257  		},
   258  		{
   259  			name: "Greater filter field must be present in root element fields/refs",
   260  			body: `{"elements":[{"fields":["sys.ID"]}],"filters":[{"expr":"gt","args":{"field":"wrong","value":1}}]}`,
   261  			err:  "filters: 'gt' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   262  		},
   263  		{
   264  			name: "Less filter field must be present in root element fields/refs",
   265  			body: `{"elements":[{"fields":["sys.ID"]}],"filters":[{"expr":"lt","args":{"field":"wrong","value":1}}]}`,
   266  			err:  "filters: 'lt' filter has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   267  		},
   268  		{
   269  			name: "Order by field must be present in root element fields/refs",
   270  			body: `{"elements":[{"fields":["sys.ID"]}],"orderBy":[{"field":"wrong"}]}`,
   271  			err:  "orderBy has field 'wrong' that is absent in root element fields/refs, please add or change it: unexpected",
   272  		},
   273  		{
   274  			name: "Each element must have unique path",
   275  			body: `{"elements":[{"fields":["sys.ID"],"path":"article"},{"fields":["sys.ID"],"path":"article"}]}`,
   276  			err:  "elements: path 'article' must be unique",
   277  		},
   278  	}
   279  
   280  	sysToken := getSystemToken(appTokens)
   281  	for _, test := range tests {
   282  		t.Run(test.name, func(t *testing.T) {
   283  			qm := NewQueryMessage(context.Background(), appName, partID, wsID, nil, []byte(test.body), qNameFunction, "", sysToken)
   284  			serviceChannel <- qm
   285  			err := <-errs
   286  			require.Contains(err.Error(), test.err)
   287  		})
   288  	}
   289  	cancel()
   290  	<-done
   291  }