github.com/sacloud/iaas-api-go@v1.12.0/search/filter_test.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package search
    16  
    17  import (
    18  	"encoding/json"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  type inputKeyValue struct {
    26  	key       FilterKey
    27  	condition interface{}
    28  }
    29  
    30  func TestFilter(t *testing.T) {
    31  	loc := time.FixedZone("Asia/Tokyo", 9*60*60)
    32  
    33  	cases := []struct {
    34  		conditions []*inputKeyValue
    35  		expect     string
    36  	}{
    37  		// default is OpEqual, OR match
    38  		{
    39  			conditions: []*inputKeyValue{
    40  				{
    41  					key:       Key("field"), // same as KeyWithOp("fields", OpEqual)
    42  					condition: "value",
    43  				},
    44  			},
    45  			expect: `{"field":["value"]}`,
    46  		},
    47  		// with comparison operator
    48  		{
    49  			conditions: []*inputKeyValue{
    50  				{
    51  					key:       KeyWithOp("field", OpLessEqual),
    52  					condition: "1",
    53  				},
    54  			},
    55  			expect: `{"field\u003c=":"1"}`,
    56  		},
    57  		// with EqualExpression
    58  		{
    59  			conditions: []*inputKeyValue{
    60  				{
    61  					key:       Key("field"),
    62  					condition: AndEqual("value1", "value2"),
    63  				},
    64  			},
    65  			expect: `{"field":"value1%20value2"}`,
    66  		},
    67  		// escape query string
    68  		{
    69  			conditions: []*inputKeyValue{
    70  				{
    71  					key:       Key("field"),
    72  					condition: AndEqual("00:00:5E:00:53:00", "00:00:5E:00:53:01"),
    73  				},
    74  			},
    75  			expect: `{"field":"00:00:5E:00:53:00%2000:00:5E:00:53:01"}`,
    76  		},
    77  		// multiple keys(AND)
    78  		{
    79  			conditions: []*inputKeyValue{
    80  				{
    81  					key:       Key("field1"),
    82  					condition: "value1",
    83  				},
    84  				{
    85  					key:       Key("field2"),
    86  					condition: "value2",
    87  				},
    88  			},
    89  			expect: `{"field1":["value1"],"field2":["value2"]}`,
    90  		},
    91  		// array values(AND)
    92  		{
    93  			conditions: []*inputKeyValue{
    94  				{
    95  					key:       Key("field1"),
    96  					condition: []string{"value1", "value2"},
    97  				},
    98  			},
    99  			expect: `{"field1":[["value1","value2"]]}`,
   100  		},
   101  		// multiple keys with same key, different operator
   102  		{
   103  			conditions: []*inputKeyValue{
   104  				{
   105  					key:       KeyWithOp("field", OpLessEqual),
   106  					condition: "1",
   107  				},
   108  				{
   109  					key:       KeyWithOp("field", OpGreaterThan),
   110  					condition: "2",
   111  				},
   112  			},
   113  			expect: `{"field\u003c=":"1","field\u003e":"2"}`,
   114  		},
   115  		// example of same as API document - https://developer.sakura.ad.jp/cloud/api/1.1/
   116  		{
   117  			conditions: []*inputKeyValue{
   118  				{
   119  					key:       Key("Name"),
   120  					condition: AndEqual("test", "example"),
   121  				},
   122  				{
   123  					key:       Key("Zone.Name"),
   124  					condition: OrEqual("is1a", "is1b"),
   125  				},
   126  				{
   127  					key:       KeyWithOp("CreatedAt", OpLessThan),
   128  					condition: time.Date(2011, 9, 1, 0, 0, 0, 0, loc),
   129  				},
   130  			},
   131  			expect: `{"CreatedAt\u003c":"2011-09-01T00:00:00+09:00","Name":"test%20example","Zone.Name":["is1a","is1b"]}`,
   132  		},
   133  	}
   134  
   135  	for _, tc := range cases {
   136  		filter := Filter{}
   137  		for _, kv := range tc.conditions {
   138  			filter[kv.key] = kv.condition
   139  		}
   140  
   141  		data, err := json.Marshal(filter)
   142  		require.NoError(t, err)
   143  		require.Equal(t, tc.expect, string(data))
   144  	}
   145  }