github.com/weaviate/weaviate@v1.24.6/usecases/objects/validation/phone_numbers_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package validation 13 14 import ( 15 "context" 16 "errors" 17 "fmt" 18 "testing" 19 20 "github.com/stretchr/testify/assert" 21 "github.com/stretchr/testify/require" 22 "github.com/weaviate/weaviate/entities/models" 23 "github.com/weaviate/weaviate/usecases/config" 24 ) 25 26 func TestPropertyOfTypePhoneNumberValidation(t *testing.T) { 27 type test struct { 28 name string 29 phone interface{} // "phone" property in schema 30 expectedErr error 31 expectedResult *models.PhoneNumber 32 } 33 34 tests := []test{ 35 { 36 name: "phone of wrong type", 37 phone: "how about a string", 38 expectedErr: errors.New("invalid phoneNumber property 'phone' on class 'Person': " + 39 "phoneNumber must be a map, but got: string"), 40 }, 41 { 42 name: "phone map missing all keys", 43 phone: map[string]interface{}{}, 44 expectedErr: errors.New("invalid phoneNumber property 'phone' on class 'Person': " + 45 "phoneNumber is missing required field 'input'"), 46 }, 47 { 48 name: "input is not a string", 49 phone: map[string]interface{}{ 50 "input": 1234, 51 }, 52 expectedErr: errors.New("invalid phoneNumber property 'phone' on class 'Person': " + 53 "phoneNumber.input must be a string"), 54 }, 55 { 56 name: "default country is not a string", 57 phone: map[string]interface{}{ 58 "input": "1234", 59 "defaultCountry": 7, 60 }, 61 expectedErr: errors.New("invalid phoneNumber property 'phone' on class 'Person': " + 62 "phoneNumber.defaultCountry must be a string"), 63 }, 64 { 65 name: "with only input set", 66 phone: map[string]interface{}{ 67 "input": "+491711234567", 68 }, 69 expectedErr: nil, 70 expectedResult: &models.PhoneNumber{ 71 Valid: true, 72 Input: "+491711234567", 73 InternationalFormatted: "+49 171 1234567", 74 CountryCode: 49, 75 National: 1711234567, 76 NationalFormatted: "0171 1234567", 77 }, 78 }, 79 { 80 name: "with national number and country uppercased", 81 phone: map[string]interface{}{ 82 "input": "01711234567", 83 "defaultCountry": "DE", 84 }, 85 expectedErr: nil, 86 expectedResult: &models.PhoneNumber{ 87 Valid: true, 88 DefaultCountry: "DE", 89 Input: "01711234567", 90 InternationalFormatted: "+49 171 1234567", 91 CountryCode: 49, 92 National: 1711234567, 93 NationalFormatted: "0171 1234567", 94 }, 95 }, 96 { 97 name: "with national number, but missing defaultCountry", 98 phone: map[string]interface{}{ 99 "input": "01711234567", 100 }, 101 expectedErr: fmt.Errorf("invalid phoneNumber property 'phone' on class 'Person': " + 102 "invalid phone number: invalid or missing defaultCountry - " + 103 "this field is optional if the specified number is in the international format, " + 104 "but required if the number is in national format, use ISO 3166-1 alpha-2"), 105 }, 106 { 107 name: "with national number and country uppercased", 108 phone: map[string]interface{}{ 109 "input": "01711234567", 110 "defaultCountry": "de", 111 }, 112 expectedErr: nil, 113 expectedResult: &models.PhoneNumber{ 114 Valid: true, 115 DefaultCountry: "DE", 116 Input: "01711234567", 117 InternationalFormatted: "+49 171 1234567", 118 CountryCode: 49, 119 National: 1711234567, 120 NationalFormatted: "0171 1234567", 121 }, 122 }, 123 { 124 name: "with national number and various special characters", 125 phone: map[string]interface{}{ 126 "input": "(0)171-123 456 7", 127 "defaultCountry": "de", 128 }, 129 expectedErr: nil, 130 expectedResult: &models.PhoneNumber{ 131 Valid: true, 132 DefaultCountry: "DE", 133 Input: "(0)171-123 456 7", 134 InternationalFormatted: "+49 171 1234567", 135 CountryCode: 49, 136 National: 1711234567, 137 NationalFormatted: "0171 1234567", 138 }, 139 }, 140 { 141 name: "with international number and optional zero after country code", 142 phone: map[string]interface{}{ 143 "input": "+49 (0) 171 123 456 7", 144 "defaultCountry": "de", 145 }, 146 expectedErr: nil, 147 expectedResult: &models.PhoneNumber{ 148 Valid: true, 149 DefaultCountry: "DE", 150 Input: "+49 (0) 171 123 456 7", 151 InternationalFormatted: "+49 171 1234567", 152 CountryCode: 49, 153 National: 1711234567, 154 NationalFormatted: "0171 1234567", 155 }, 156 }, 157 } 158 159 for _, test := range tests { 160 t.Run(test.name, func(t *testing.T) { 161 config := &config.WeaviateConfig{} 162 validator := New(fakeExists, config, nil) 163 164 obj := &models.Object{ 165 Class: "Person", 166 Properties: map[string]interface{}{ 167 "phone": test.phone, 168 }, 169 } 170 schema := testSchema() 171 err := validator.properties(context.Background(), schema.Objects.Classes[0], obj, nil) 172 assert.Equal(t, test.expectedErr, err) 173 if err != nil { 174 return 175 } 176 phone, ok := obj.Properties.(map[string]interface{})["phone"] 177 require.True(t, ok) 178 assert.Equal(t, test.expectedResult, phone) 179 }) 180 } 181 }