github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/privatemessaging/recipients_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 privatemessaging
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/kaleido-io/firefly/mocks/databasemocks"
    25  	"github.com/kaleido-io/firefly/pkg/fftypes"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/mock"
    28  )
    29  
    30  func TestResolveMemberListNewGroupE2E(t *testing.T) {
    31  
    32  	pm, cancel := newTestPrivateMessaging(t)
    33  	defer cancel()
    34  
    35  	mdi := pm.database.(*databasemocks.Plugin)
    36  	nodeID := fftypes.NewUUID()
    37  	orgID := fftypes.NewUUID()
    38  	var dataID *fftypes.UUID
    39  	mdi.On("GetOrganizationByName", pm.ctx, mock.Anything).Return(&fftypes.Organization{ID: orgID, Identity: "localorg"}, nil)
    40  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{{ID: nodeID, Name: "node1", Owner: "localorg"}}, nil)
    41  	mdi.On("GetGroups", pm.ctx, mock.Anything).Return([]*fftypes.Group{}, nil)
    42  	mdi.On("UpsertGroup", pm.ctx, mock.Anything, true).Return(nil)
    43  	ud := mdi.On("UpsertData", pm.ctx, mock.Anything, true, false).Return(nil)
    44  	ud.RunFn = func(a mock.Arguments) {
    45  		data := a[1].(*fftypes.Data)
    46  		assert.Equal(t, fftypes.ValidatorTypeSystemDefinition, data.Validator)
    47  		assert.Equal(t, fftypes.SystemNamespace, data.Namespace)
    48  		var group fftypes.Group
    49  		err := json.Unmarshal(data.Value, &group)
    50  		assert.NoError(t, err)
    51  		assert.Len(t, group.Members, 1)
    52  		assert.Equal(t, "localorg", group.Members[0].Identity)
    53  		assert.Equal(t, *nodeID, *group.Members[0].Node)
    54  		assert.Nil(t, group.Ledger)
    55  		dataID = data.ID
    56  	}
    57  	um := mdi.On("UpsertMessage", pm.ctx, mock.Anything, false, false).Return(nil).Once()
    58  	um.RunFn = func(a mock.Arguments) {
    59  		msg := a[1].(*fftypes.Message)
    60  		assert.Equal(t, fftypes.MessageTypeGroupInit, msg.Header.Type)
    61  		assert.Equal(t, fftypes.SystemNamespace, msg.Header.Namespace)
    62  		assert.Len(t, msg.Data, 1)
    63  		assert.Equal(t, *dataID, *msg.Data[0].ID)
    64  	}
    65  
    66  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
    67  		Group: &fftypes.InputGroup{
    68  			Members: []fftypes.MemberInput{
    69  				{Identity: "localorg"},
    70  			},
    71  		},
    72  	})
    73  	assert.NoError(t, err)
    74  	mdi.AssertExpectations(t)
    75  
    76  }
    77  
    78  func TestResolveMemberListExistingGroup(t *testing.T) {
    79  
    80  	pm, cancel := newTestPrivateMessaging(t)
    81  	defer cancel()
    82  
    83  	mdi := pm.database.(*databasemocks.Plugin)
    84  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(&fftypes.Organization{ID: fftypes.NewUUID()}, nil)
    85  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{{ID: fftypes.NewUUID(), Name: "node1", Owner: "localorg"}}, nil)
    86  	mdi.On("GetGroups", pm.ctx, mock.Anything).Return([]*fftypes.Group{
    87  		{Hash: fftypes.NewRandB32()},
    88  	}, nil)
    89  
    90  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
    91  		Group: &fftypes.InputGroup{
    92  			Members: []fftypes.MemberInput{
    93  				{Identity: "org1"},
    94  			},
    95  		},
    96  	})
    97  	assert.NoError(t, err)
    98  	mdi.AssertExpectations(t)
    99  
   100  }
   101  
   102  func TestResolveMemberListGetGroupsFail(t *testing.T) {
   103  
   104  	pm, cancel := newTestPrivateMessaging(t)
   105  	defer cancel()
   106  
   107  	mdi := pm.database.(*databasemocks.Plugin)
   108  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(&fftypes.Organization{ID: fftypes.NewUUID()}, nil)
   109  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{{ID: fftypes.NewUUID(), Name: "node1", Owner: "localorg"}}, nil)
   110  	mdi.On("GetGroups", pm.ctx, mock.Anything).Return(nil, fmt.Errorf("pop"))
   111  
   112  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
   113  		Group: &fftypes.InputGroup{
   114  			Members: []fftypes.MemberInput{
   115  				{Identity: "org1"},
   116  			},
   117  		},
   118  	})
   119  	assert.EqualError(t, err, "pop")
   120  	mdi.AssertExpectations(t)
   121  
   122  }
   123  
   124  func TestResolveMemberListMissingLocalMember(t *testing.T) {
   125  
   126  	pm, cancel := newTestPrivateMessaging(t)
   127  	defer cancel()
   128  
   129  	mdi := pm.database.(*databasemocks.Plugin)
   130  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(&fftypes.Organization{ID: fftypes.NewUUID()}, nil)
   131  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{{ID: fftypes.NewUUID(), Name: "node2", Owner: "org1"}}, nil)
   132  
   133  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
   134  		Group: &fftypes.InputGroup{
   135  			Members: []fftypes.MemberInput{
   136  				{Identity: "org1"},
   137  			},
   138  		},
   139  	})
   140  	assert.Regexp(t, "FF10225", err)
   141  	mdi.AssertExpectations(t)
   142  
   143  }
   144  
   145  func TestResolveMemberListNodeNotFound(t *testing.T) {
   146  
   147  	pm, cancel := newTestPrivateMessaging(t)
   148  	defer cancel()
   149  
   150  	mdi := pm.database.(*databasemocks.Plugin)
   151  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(&fftypes.Organization{ID: fftypes.NewUUID()}, nil)
   152  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{}, nil)
   153  
   154  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
   155  		Group: &fftypes.InputGroup{
   156  			Members: []fftypes.MemberInput{
   157  				{Identity: "org1"},
   158  			},
   159  		},
   160  	})
   161  	assert.Regexp(t, "FF10233", err)
   162  	mdi.AssertExpectations(t)
   163  
   164  }
   165  
   166  func TestResolveMemberOrgNameNotFound(t *testing.T) {
   167  
   168  	pm, cancel := newTestPrivateMessaging(t)
   169  	defer cancel()
   170  
   171  	mdi := pm.database.(*databasemocks.Plugin)
   172  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(nil, nil)
   173  	mdi.On("GetOrganizationByIdentity", pm.ctx, "org1").Return(nil, nil)
   174  
   175  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
   176  		Group: &fftypes.InputGroup{
   177  			Members: []fftypes.MemberInput{
   178  				{Identity: "org1"},
   179  			},
   180  		},
   181  	})
   182  	assert.Regexp(t, "FF10223", err)
   183  	mdi.AssertExpectations(t)
   184  
   185  }
   186  
   187  func TestResolveMemberNodeOwnedParentOrg(t *testing.T) {
   188  
   189  	pm, cancel := newTestPrivateMessaging(t)
   190  	defer cancel()
   191  
   192  	orgID := fftypes.NewUUID()
   193  	mdi := pm.database.(*databasemocks.Plugin)
   194  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(&fftypes.Organization{ID: fftypes.NewUUID(), Parent: "id-org2"}, nil)
   195  	mdi.On("GetOrganizationByIdentity", pm.ctx, "id-org2").Return(&fftypes.Organization{ID: orgID}, nil)
   196  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{}, nil).Once()
   197  	mdi.On("GetNodes", pm.ctx, mock.Anything).Return([]*fftypes.Node{{ID: fftypes.NewUUID(), Name: "node1", Owner: "localorg"}}, nil)
   198  	mdi.On("GetGroups", pm.ctx, mock.Anything).Return([]*fftypes.Group{{Hash: fftypes.NewRandB32()}}, nil)
   199  
   200  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{Identifier: "0x12345"}, &fftypes.MessageInput{
   201  		Group: &fftypes.InputGroup{
   202  			Members: []fftypes.MemberInput{
   203  				{Identity: "org1"},
   204  			},
   205  		},
   206  	})
   207  	assert.NoError(t, err)
   208  	mdi.AssertExpectations(t)
   209  
   210  }
   211  
   212  func TestResolveOrgFail(t *testing.T) {
   213  	pm, cancel := newTestPrivateMessaging(t)
   214  	defer cancel()
   215  
   216  	mdi := pm.database.(*databasemocks.Plugin)
   217  	mdi.On("GetOrganizationByName", pm.ctx, "org1").Return(nil, fmt.Errorf("pop"))
   218  
   219  	_, err := pm.resolveOrg(pm.ctx, "org1")
   220  	assert.Regexp(t, "pop", err)
   221  	mdi.AssertExpectations(t)
   222  
   223  }
   224  
   225  func TestResolveOrgByIDFail(t *testing.T) {
   226  	pm, cancel := newTestPrivateMessaging(t)
   227  	defer cancel()
   228  
   229  	orgID := fftypes.NewUUID()
   230  
   231  	mdi := pm.database.(*databasemocks.Plugin)
   232  	mdi.On("GetOrganizationByID", pm.ctx, uuidMatches(orgID)).Return(&fftypes.Organization{ID: orgID}, nil)
   233  
   234  	org, err := pm.resolveOrg(pm.ctx, orgID.String())
   235  	assert.NoError(t, err)
   236  	assert.Equal(t, *orgID, *org.ID)
   237  
   238  }
   239  
   240  func TestGetNodeFail(t *testing.T) {
   241  	pm, cancel := newTestPrivateMessaging(t)
   242  	defer cancel()
   243  
   244  	mdi := pm.database.(*databasemocks.Plugin)
   245  	mdi.On("GetNode", pm.ctx, "org1", "id-node1").Return(nil, fmt.Errorf("pop"))
   246  
   247  	_, err := pm.resolveNode(pm.ctx, &fftypes.Organization{Identity: "org1"}, "id-node1")
   248  	assert.Regexp(t, "pop", err)
   249  	mdi.AssertExpectations(t)
   250  
   251  }
   252  
   253  func TestResolveNodeByIDNoResult(t *testing.T) {
   254  	pm, cancel := newTestPrivateMessaging(t)
   255  	defer cancel()
   256  
   257  	mdi := pm.database.(*databasemocks.Plugin)
   258  	mdi.On("GetNodeByID", pm.ctx, mock.Anything).Return(nil, nil)
   259  
   260  	_, err := pm.resolveNode(pm.ctx, &fftypes.Organization{}, fftypes.NewUUID().String())
   261  	assert.Regexp(t, "FF10224", err)
   262  	mdi.AssertExpectations(t)
   263  
   264  }
   265  
   266  func TestResolveReceipientListExisting(t *testing.T) {
   267  	pm, cancel := newTestPrivateMessaging(t)
   268  	defer cancel()
   269  
   270  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{}, &fftypes.MessageInput{
   271  		Message: fftypes.Message{
   272  			Header: fftypes.MessageHeader{
   273  				Group: fftypes.NewRandB32(),
   274  			},
   275  		},
   276  	})
   277  	assert.NoError(t, err)
   278  }
   279  
   280  func TestResolveReceipientListEmptyList(t *testing.T) {
   281  	pm, cancel := newTestPrivateMessaging(t)
   282  	defer cancel()
   283  
   284  	err := pm.resolveReceipientList(pm.ctx, &fftypes.Identity{}, &fftypes.MessageInput{})
   285  	assert.Regexp(t, "FF10219", err)
   286  }