github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/database/sqlcommon/organization_sql_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 sqlcommon
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"fmt"
    23  	"testing"
    24  
    25  	"github.com/DATA-DOG/go-sqlmock"
    26  	"github.com/kaleido-io/firefly/internal/log"
    27  	"github.com/kaleido-io/firefly/pkg/database"
    28  	"github.com/kaleido-io/firefly/pkg/fftypes"
    29  	"github.com/stretchr/testify/assert"
    30  )
    31  
    32  func TestOrganizationsE2EWithDB(t *testing.T) {
    33  	log.SetLevel("debug")
    34  
    35  	s := newQLTestProvider(t)
    36  	defer s.Close()
    37  	ctx := context.Background()
    38  
    39  	// Create a new organization entry
    40  	organization := &fftypes.Organization{
    41  		ID:       fftypes.NewUUID(),
    42  		Message:  fftypes.NewUUID(),
    43  		Name:     "org1",
    44  		Identity: "0x12345",
    45  		Created:  fftypes.Now(),
    46  	}
    47  	err := s.UpsertOrganization(ctx, organization, true)
    48  	assert.NoError(t, err)
    49  
    50  	// Check we get the exact same organization back
    51  	organizationRead, err := s.GetOrganizationByIdentity(ctx, organization.Identity)
    52  	assert.NoError(t, err)
    53  	assert.NotNil(t, organizationRead)
    54  	organizationJson, _ := json.Marshal(&organization)
    55  	organizationReadJson, _ := json.Marshal(&organizationRead)
    56  	assert.Equal(t, string(organizationJson), string(organizationReadJson))
    57  
    58  	// Rejects attempt to update ID
    59  	err = s.UpsertOrganization(context.Background(), &fftypes.Organization{
    60  		ID:       fftypes.NewUUID(),
    61  		Identity: "0x12345",
    62  	}, true)
    63  	assert.Equal(t, database.IDMismatch, err)
    64  
    65  	// Update the organization (this is testing what's possible at the database layer,
    66  	// and does not account for the verification that happens at the higher level)
    67  	organizationUpdated := &fftypes.Organization{
    68  		ID:          nil, // as long as we don't specify one we're fine
    69  		Message:     fftypes.NewUUID(),
    70  		Name:        "org1",
    71  		Parent:      "0x23456",
    72  		Identity:    "0x12345",
    73  		Description: "organization1",
    74  		Profile:     fftypes.JSONObject{"some": "info"},
    75  		Created:     fftypes.Now(),
    76  	}
    77  	err = s.UpsertOrganization(context.Background(), organizationUpdated, true)
    78  	assert.NoError(t, err)
    79  
    80  	// Check we get the exact same data back - note the removal of one of the organization elements
    81  	organizationRead, err = s.GetOrganizationByName(ctx, organization.Name)
    82  	assert.NoError(t, err)
    83  	organizationJson, _ = json.Marshal(&organizationUpdated)
    84  	organizationReadJson, _ = json.Marshal(&organizationRead)
    85  	assert.Equal(t, string(organizationJson), string(organizationReadJson))
    86  
    87  	// Query back the organization
    88  	fb := database.OrganizationQueryFactory.NewFilter(ctx)
    89  	filter := fb.And(
    90  		fb.Eq("description", string(organizationUpdated.Description)),
    91  		fb.Eq("identity", organizationUpdated.Identity),
    92  	)
    93  	organizationRes, err := s.GetOrganizations(ctx, filter)
    94  	assert.NoError(t, err)
    95  	assert.Equal(t, 1, len(organizationRes))
    96  	organizationReadJson, _ = json.Marshal(organizationRes[0])
    97  	assert.Equal(t, string(organizationJson), string(organizationReadJson))
    98  
    99  	// Update
   100  	updateTime := fftypes.Now()
   101  	up := database.OrganizationQueryFactory.NewUpdate(ctx).Set("created", updateTime)
   102  	err = s.UpdateOrganization(ctx, organizationUpdated.ID, up)
   103  	assert.NoError(t, err)
   104  
   105  	// Test find updated value
   106  	filter = fb.And(
   107  		fb.Eq("identity", organizationUpdated.Identity),
   108  		fb.Eq("created", updateTime.String()),
   109  	)
   110  	organizations, err := s.GetOrganizations(ctx, filter)
   111  	assert.NoError(t, err)
   112  	assert.Equal(t, 1, len(organizations))
   113  }
   114  
   115  func TestUpsertOrganizationFailBegin(t *testing.T) {
   116  	s, mock := newMockProvider().init()
   117  	mock.ExpectBegin().WillReturnError(fmt.Errorf("pop"))
   118  	err := s.UpsertOrganization(context.Background(), &fftypes.Organization{}, true)
   119  	assert.Regexp(t, "FF10114", err)
   120  	assert.NoError(t, mock.ExpectationsWereMet())
   121  }
   122  
   123  func TestUpsertOrganizationFailSelect(t *testing.T) {
   124  	s, mock := newMockProvider().init()
   125  	mock.ExpectBegin()
   126  	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
   127  	mock.ExpectRollback()
   128  	err := s.UpsertOrganization(context.Background(), &fftypes.Organization{Identity: "id1"}, true)
   129  	assert.Regexp(t, "FF10115", err)
   130  	assert.NoError(t, mock.ExpectationsWereMet())
   131  }
   132  
   133  func TestUpsertOrganizationFailInsert(t *testing.T) {
   134  	s, mock := newMockProvider().init()
   135  	mock.ExpectBegin()
   136  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{}))
   137  	mock.ExpectExec("INSERT .*").WillReturnError(fmt.Errorf("pop"))
   138  	mock.ExpectRollback()
   139  	err := s.UpsertOrganization(context.Background(), &fftypes.Organization{Identity: "id1"}, true)
   140  	assert.Regexp(t, "FF10116", err)
   141  	assert.NoError(t, mock.ExpectationsWereMet())
   142  }
   143  
   144  func TestUpsertOrganizationFailUpdate(t *testing.T) {
   145  	s, mock := newMockProvider().init()
   146  	mock.ExpectBegin()
   147  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"identity"}).
   148  		AddRow("id1"))
   149  	mock.ExpectExec("UPDATE .*").WillReturnError(fmt.Errorf("pop"))
   150  	mock.ExpectRollback()
   151  	err := s.UpsertOrganization(context.Background(), &fftypes.Organization{Identity: "id1"}, true)
   152  	assert.Regexp(t, "FF10117", err)
   153  	assert.NoError(t, mock.ExpectationsWereMet())
   154  }
   155  
   156  func TestUpsertOrganizationFailCommit(t *testing.T) {
   157  	s, mock := newMockProvider().init()
   158  	mock.ExpectBegin()
   159  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"identity"}))
   160  	mock.ExpectExec("INSERT .*").WillReturnResult(sqlmock.NewResult(1, 1))
   161  	mock.ExpectCommit().WillReturnError(fmt.Errorf("pop"))
   162  	err := s.UpsertOrganization(context.Background(), &fftypes.Organization{Identity: "id1"}, true)
   163  	assert.Regexp(t, "FF10119", err)
   164  	assert.NoError(t, mock.ExpectationsWereMet())
   165  }
   166  
   167  func TestGetOrganizationByIDSelectFail(t *testing.T) {
   168  	s, mock := newMockProvider().init()
   169  	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
   170  	_, err := s.GetOrganizationByID(context.Background(), fftypes.NewUUID())
   171  	assert.Regexp(t, "FF10115", err)
   172  	assert.NoError(t, mock.ExpectationsWereMet())
   173  }
   174  
   175  func TestGetOrganizationByNameSelectFail(t *testing.T) {
   176  	s, mock := newMockProvider().init()
   177  	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
   178  	_, err := s.GetOrganizationByName(context.Background(), "org1")
   179  	assert.Regexp(t, "FF10115", err)
   180  	assert.NoError(t, mock.ExpectationsWereMet())
   181  }
   182  
   183  func TestGetOrganizationByIdentitySelectFail(t *testing.T) {
   184  	s, mock := newMockProvider().init()
   185  	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
   186  	_, err := s.GetOrganizationByIdentity(context.Background(), "id1")
   187  	assert.Regexp(t, "FF10115", err)
   188  	assert.NoError(t, mock.ExpectationsWereMet())
   189  }
   190  
   191  func TestGetOrganizationByIDNotFound(t *testing.T) {
   192  	s, mock := newMockProvider().init()
   193  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"identity", "organization", "identity"}))
   194  	msg, err := s.GetOrganizationByID(context.Background(), fftypes.NewUUID())
   195  	assert.NoError(t, err)
   196  	assert.Nil(t, msg)
   197  	assert.NoError(t, mock.ExpectationsWereMet())
   198  }
   199  
   200  func TestGetOrganizationByIDScanFail(t *testing.T) {
   201  	s, mock := newMockProvider().init()
   202  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"identity"}).AddRow("only one"))
   203  	_, err := s.GetOrganizationByID(context.Background(), fftypes.NewUUID())
   204  	assert.Regexp(t, "FF10121", err)
   205  	assert.NoError(t, mock.ExpectationsWereMet())
   206  }
   207  
   208  func TestGetOrganizationQueryFail(t *testing.T) {
   209  	s, mock := newMockProvider().init()
   210  	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
   211  	f := database.OrganizationQueryFactory.NewFilter(context.Background()).Eq("identity", "")
   212  	_, err := s.GetOrganizations(context.Background(), f)
   213  	assert.Regexp(t, "FF10115", err)
   214  	assert.NoError(t, mock.ExpectationsWereMet())
   215  }
   216  
   217  func TestGetOrganizationBuildQueryFail(t *testing.T) {
   218  	s, _ := newMockProvider().init()
   219  	f := database.OrganizationQueryFactory.NewFilter(context.Background()).Eq("identity", map[bool]bool{true: false})
   220  	_, err := s.GetOrganizations(context.Background(), f)
   221  	assert.Regexp(t, "FF10149.*type", err)
   222  }
   223  
   224  func TestGetOrganizationReadMessageFail(t *testing.T) {
   225  	s, mock := newMockProvider().init()
   226  	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows([]string{"identity"}).AddRow("only one"))
   227  	f := database.OrganizationQueryFactory.NewFilter(context.Background()).Eq("identity", "")
   228  	_, err := s.GetOrganizations(context.Background(), f)
   229  	assert.Regexp(t, "FF10121", err)
   230  	assert.NoError(t, mock.ExpectationsWereMet())
   231  }
   232  
   233  func TestOrganizationUpdateBeginFail(t *testing.T) {
   234  	s, mock := newMockProvider().init()
   235  	mock.ExpectBegin().WillReturnError(fmt.Errorf("pop"))
   236  	u := database.OrganizationQueryFactory.NewUpdate(context.Background()).Set("identity", "anything")
   237  	err := s.UpdateOrganization(context.Background(), fftypes.NewUUID(), u)
   238  	assert.Regexp(t, "FF10114", err)
   239  }
   240  
   241  func TestOrganizationUpdateBuildQueryFail(t *testing.T) {
   242  	s, mock := newMockProvider().init()
   243  	mock.ExpectBegin()
   244  	u := database.OrganizationQueryFactory.NewUpdate(context.Background()).Set("identity", map[bool]bool{true: false})
   245  	err := s.UpdateOrganization(context.Background(), fftypes.NewUUID(), u)
   246  	assert.Regexp(t, "FF10149.*identity", err)
   247  }
   248  
   249  func TestOrganizationUpdateFail(t *testing.T) {
   250  	s, mock := newMockProvider().init()
   251  	mock.ExpectBegin()
   252  	mock.ExpectExec("UPDATE .*").WillReturnError(fmt.Errorf("pop"))
   253  	mock.ExpectRollback()
   254  	u := database.OrganizationQueryFactory.NewUpdate(context.Background()).Set("identity", fftypes.NewUUID())
   255  	err := s.UpdateOrganization(context.Background(), fftypes.NewUUID(), u)
   256  	assert.Regexp(t, "FF10117", err)
   257  }