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 }