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  }