github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/broadcast/syshandler_network_org_test.go (about) 1 // Copyright © 2021 Kaleido, Inc. 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package broadcast 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "testing" 24 25 "github.com/kaleido-io/firefly/mocks/databasemocks" 26 "github.com/kaleido-io/firefly/mocks/identitymocks" 27 "github.com/kaleido-io/firefly/pkg/fftypes" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/mock" 30 ) 31 32 func TestHandleSystemBroadcastOrgOk(t *testing.T) { 33 bm, cancel := newTestBroadcast(t) 34 defer cancel() 35 36 org := &fftypes.Organization{ 37 ID: fftypes.NewUUID(), 38 Name: "org1", 39 Identity: "0x12345", 40 Parent: "0x23456", 41 Description: "my org", 42 Profile: fftypes.JSONObject{"some": "info"}, 43 } 44 b, err := json.Marshal(&org) 45 assert.NoError(t, err) 46 data := &fftypes.Data{ 47 Value: fftypes.Byteable(b), 48 } 49 50 mii := bm.identity.(*identitymocks.Plugin) 51 mii.On("Resolve", mock.Anything, "0x23456").Return(&fftypes.Identity{OnChain: "0x23456"}, nil) 52 mdi := bm.database.(*databasemocks.Plugin) 53 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x23456").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Identity: "0x23456"}, nil) 54 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x12345").Return(nil, nil) 55 mdi.On("GetOrganizationByName", mock.Anything, "org1").Return(nil, nil) 56 mdi.On("GetOrganizationByID", mock.Anything, org.ID).Return(nil, nil) 57 mdi.On("UpsertOrganization", mock.Anything, mock.Anything, true).Return(nil) 58 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 59 Header: fftypes.MessageHeader{ 60 Namespace: "ns1", 61 Author: "0x23456", 62 Tag: string(fftypes.SystemTagDefineOrganization), 63 }, 64 }, []*fftypes.Data{data}) 65 assert.True(t, valid) 66 assert.NoError(t, err) 67 68 mii.AssertExpectations(t) 69 mdi.AssertExpectations(t) 70 } 71 72 func TestHandleSystemBroadcastOrgDupOk(t *testing.T) { 73 bm, cancel := newTestBroadcast(t) 74 defer cancel() 75 76 org := &fftypes.Organization{ 77 ID: fftypes.NewUUID(), 78 Name: "org1", 79 Identity: "0x12345", 80 Parent: "0x23456", 81 Description: "my org", 82 Profile: fftypes.JSONObject{"some": "info"}, 83 } 84 b, err := json.Marshal(&org) 85 assert.NoError(t, err) 86 data := &fftypes.Data{ 87 Value: fftypes.Byteable(b), 88 } 89 90 mii := bm.identity.(*identitymocks.Plugin) 91 mii.On("Resolve", mock.Anything, "0x23456").Return(&fftypes.Identity{OnChain: "0x23456"}, nil) 92 mdi := bm.database.(*databasemocks.Plugin) 93 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x23456").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Identity: "0x23456"}, nil) 94 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x12345").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Identity: "0x12345", Parent: "0x23456"}, nil) 95 mdi.On("UpsertOrganization", mock.Anything, mock.Anything, true).Return(nil) 96 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 97 Header: fftypes.MessageHeader{ 98 Namespace: "ns1", 99 Author: "0x23456", 100 Tag: string(fftypes.SystemTagDefineOrganization), 101 }, 102 }, []*fftypes.Data{data}) 103 assert.True(t, valid) 104 assert.NoError(t, err) 105 106 mii.AssertExpectations(t) 107 mdi.AssertExpectations(t) 108 } 109 110 func TestHandleSystemBroadcastOrgDupMismatch(t *testing.T) { 111 bm, cancel := newTestBroadcast(t) 112 defer cancel() 113 114 org := &fftypes.Organization{ 115 ID: fftypes.NewUUID(), 116 Name: "org1", 117 Identity: "0x12345", 118 Parent: "0x23456", 119 Description: "my org", 120 Profile: fftypes.JSONObject{"some": "info"}, 121 } 122 b, err := json.Marshal(&org) 123 assert.NoError(t, err) 124 data := &fftypes.Data{ 125 Value: fftypes.Byteable(b), 126 } 127 128 mii := bm.identity.(*identitymocks.Plugin) 129 mii.On("Resolve", mock.Anything, "0x23456").Return(&fftypes.Identity{OnChain: "0x23456"}, nil) 130 mdi := bm.database.(*databasemocks.Plugin) 131 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x23456").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Identity: "0x23456"}, nil) 132 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x12345").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Identity: "0x12345", Parent: "0x9999"}, nil) 133 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 134 Header: fftypes.MessageHeader{ 135 Namespace: "ns1", 136 Author: "0x23456", 137 Tag: string(fftypes.SystemTagDefineOrganization), 138 }, 139 }, []*fftypes.Data{data}) 140 assert.False(t, valid) 141 assert.NoError(t, err) 142 143 mii.AssertExpectations(t) 144 mdi.AssertExpectations(t) 145 } 146 147 func TestHandleSystemBroadcastOrgUpsertFail(t *testing.T) { 148 bm, cancel := newTestBroadcast(t) 149 defer cancel() 150 151 org := &fftypes.Organization{ 152 ID: fftypes.NewUUID(), 153 Name: "org1", 154 Identity: "0x12345", 155 Description: "my org", 156 Profile: fftypes.JSONObject{"some": "info"}, 157 } 158 b, err := json.Marshal(&org) 159 assert.NoError(t, err) 160 data := &fftypes.Data{ 161 Value: fftypes.Byteable(b), 162 } 163 164 mii := bm.identity.(*identitymocks.Plugin) 165 mii.On("Resolve", mock.Anything, "0x12345").Return(&fftypes.Identity{OnChain: "0x12345"}, nil) 166 mdi := bm.database.(*databasemocks.Plugin) 167 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x12345").Return(nil, nil) 168 mdi.On("GetOrganizationByName", mock.Anything, "org1").Return(nil, nil) 169 mdi.On("GetOrganizationByID", mock.Anything, org.ID).Return(nil, nil) 170 mdi.On("UpsertOrganization", mock.Anything, mock.Anything, true).Return(fmt.Errorf("pop")) 171 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 172 Header: fftypes.MessageHeader{ 173 Namespace: "ns1", 174 Author: "0x12345", 175 Tag: string(fftypes.SystemTagDefineOrganization), 176 }, 177 }, []*fftypes.Data{data}) 178 assert.False(t, valid) 179 assert.EqualError(t, err, "pop") 180 181 mii.AssertExpectations(t) 182 mdi.AssertExpectations(t) 183 } 184 185 func TestHandleSystemBroadcastOrgGetOrgFail(t *testing.T) { 186 bm, cancel := newTestBroadcast(t) 187 defer cancel() 188 189 org := &fftypes.Organization{ 190 ID: fftypes.NewUUID(), 191 Name: "org1", 192 Identity: "0x12345", 193 Description: "my org", 194 Profile: fftypes.JSONObject{"some": "info"}, 195 } 196 b, err := json.Marshal(&org) 197 assert.NoError(t, err) 198 data := &fftypes.Data{ 199 Value: fftypes.Byteable(b), 200 } 201 202 mii := bm.identity.(*identitymocks.Plugin) 203 mii.On("Resolve", mock.Anything, "0x12345").Return(&fftypes.Identity{OnChain: "0x12345"}, nil) 204 mdi := bm.database.(*databasemocks.Plugin) 205 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x12345").Return(nil, fmt.Errorf("pop")) 206 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 207 Header: fftypes.MessageHeader{ 208 Namespace: "ns1", 209 Author: "0x12345", 210 Tag: string(fftypes.SystemTagDefineOrganization), 211 }, 212 }, []*fftypes.Data{data}) 213 assert.False(t, valid) 214 assert.EqualError(t, err, "pop") 215 216 mii.AssertExpectations(t) 217 mdi.AssertExpectations(t) 218 } 219 220 func TestHandleSystemBroadcastOrgAuthorMismatch(t *testing.T) { 221 bm, cancel := newTestBroadcast(t) 222 defer cancel() 223 224 org := &fftypes.Organization{ 225 ID: fftypes.NewUUID(), 226 Name: "org1", 227 Identity: "0x12345", 228 Description: "my org", 229 Profile: fftypes.JSONObject{"some": "info"}, 230 } 231 b, err := json.Marshal(&org) 232 assert.NoError(t, err) 233 data := &fftypes.Data{ 234 Value: fftypes.Byteable(b), 235 } 236 237 mii := bm.identity.(*identitymocks.Plugin) 238 mii.On("Resolve", mock.Anything, "0x12345").Return(&fftypes.Identity{OnChain: "0x12345"}, nil) 239 mdi := bm.database.(*databasemocks.Plugin) 240 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 241 Header: fftypes.MessageHeader{ 242 Namespace: "ns1", 243 Author: "0x23456", 244 Tag: string(fftypes.SystemTagDefineOrganization), 245 }, 246 }, []*fftypes.Data{data}) 247 assert.False(t, valid) 248 assert.NoError(t, err) 249 250 mii.AssertExpectations(t) 251 mdi.AssertExpectations(t) 252 } 253 254 func TestHandleSystemBroadcastOrgResolveFail(t *testing.T) { 255 bm, cancel := newTestBroadcast(t) 256 defer cancel() 257 258 org := &fftypes.Organization{ 259 ID: fftypes.NewUUID(), 260 Name: "org1", 261 Identity: "0x12345", 262 Description: "my org", 263 Profile: fftypes.JSONObject{"some": "info"}, 264 } 265 b, err := json.Marshal(&org) 266 assert.NoError(t, err) 267 data := &fftypes.Data{ 268 Value: fftypes.Byteable(b), 269 } 270 271 mii := bm.identity.(*identitymocks.Plugin) 272 mii.On("Resolve", mock.Anything, "0x12345").Return(nil, fmt.Errorf("pop")) 273 mdi := bm.database.(*databasemocks.Plugin) 274 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 275 Header: fftypes.MessageHeader{ 276 Namespace: "ns1", 277 Author: "0x23456", 278 Tag: string(fftypes.SystemTagDefineOrganization), 279 }, 280 }, []*fftypes.Data{data}) 281 assert.False(t, valid) 282 assert.NoError(t, err) 283 284 mii.AssertExpectations(t) 285 mdi.AssertExpectations(t) 286 } 287 288 func TestHandleSystemBroadcastGetParentFail(t *testing.T) { 289 bm, cancel := newTestBroadcast(t) 290 defer cancel() 291 292 org := &fftypes.Organization{ 293 ID: fftypes.NewUUID(), 294 Name: "org1", 295 Identity: "0x12345", 296 Parent: "0x23456", 297 Description: "my org", 298 Profile: fftypes.JSONObject{"some": "info"}, 299 } 300 b, err := json.Marshal(&org) 301 assert.NoError(t, err) 302 data := &fftypes.Data{ 303 Value: fftypes.Byteable(b), 304 } 305 306 mdi := bm.database.(*databasemocks.Plugin) 307 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x23456").Return(nil, fmt.Errorf("pop")) 308 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 309 Header: fftypes.MessageHeader{ 310 Namespace: "ns1", 311 Author: "0x23456", 312 Tag: string(fftypes.SystemTagDefineOrganization), 313 }, 314 }, []*fftypes.Data{data}) 315 assert.False(t, valid) 316 assert.EqualError(t, err, "pop") 317 318 mdi.AssertExpectations(t) 319 } 320 321 func TestHandleSystemBroadcastGetParentNotFound(t *testing.T) { 322 bm, cancel := newTestBroadcast(t) 323 defer cancel() 324 325 org := &fftypes.Organization{ 326 ID: fftypes.NewUUID(), 327 Name: "org1", 328 Identity: "0x12345", 329 Parent: "0x23456", 330 Description: "my org", 331 Profile: fftypes.JSONObject{"some": "info"}, 332 } 333 b, err := json.Marshal(&org) 334 assert.NoError(t, err) 335 data := &fftypes.Data{ 336 Value: fftypes.Byteable(b), 337 } 338 339 mdi := bm.database.(*databasemocks.Plugin) 340 mdi.On("GetOrganizationByIdentity", mock.Anything, "0x23456").Return(nil, nil) 341 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 342 Header: fftypes.MessageHeader{ 343 Namespace: "ns1", 344 Author: "0x23456", 345 Tag: string(fftypes.SystemTagDefineOrganization), 346 }, 347 }, []*fftypes.Data{data}) 348 assert.False(t, valid) 349 assert.NoError(t, err) 350 351 mdi.AssertExpectations(t) 352 } 353 354 func TestHandleSystemBroadcastValidateFail(t *testing.T) { 355 bm, cancel := newTestBroadcast(t) 356 defer cancel() 357 358 org := &fftypes.Organization{ 359 ID: fftypes.NewUUID(), 360 Name: "org1", 361 Identity: "0x12345", 362 Description: string(make([]byte, 4097)), 363 } 364 b, err := json.Marshal(&org) 365 assert.NoError(t, err) 366 data := &fftypes.Data{ 367 Value: fftypes.Byteable(b), 368 } 369 370 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 371 Header: fftypes.MessageHeader{ 372 Namespace: "ns1", 373 Author: "0x23456", 374 Tag: string(fftypes.SystemTagDefineOrganization), 375 }, 376 }, []*fftypes.Data{data}) 377 assert.False(t, valid) 378 assert.NoError(t, err) 379 } 380 381 func TestHandleSystemBroadcastUnmarshalFail(t *testing.T) { 382 bm, cancel := newTestBroadcast(t) 383 defer cancel() 384 385 data := &fftypes.Data{ 386 Value: fftypes.Byteable(`!json`), 387 } 388 389 valid, err := bm.HandleSystemBroadcast(context.Background(), &fftypes.Message{ 390 Header: fftypes.MessageHeader{ 391 Namespace: "ns1", 392 Author: "0x23456", 393 Tag: string(fftypes.SystemTagDefineOrganization), 394 }, 395 }, []*fftypes.Data{data}) 396 assert.False(t, valid) 397 assert.NoError(t, err) 398 }