This is an automated email from the ASF dual-hosted git repository. lahirujayathilake pushed a commit to branch access-integration-v3 in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
commit 25a841f571ea2305330357d4340e62ea96fe00e2 Author: lahiruj <[email protected]> AuthorDate: Wed May 20 17:41:42 2026 -0400 Drop AMIE handler tests that don't fit the new core architecture --- .../handler/data_account_create_test.go | 148 -------------- .../handler/data_project_create_test.go | 149 -------------- .../handler/inform_transaction_complete_test.go | 124 ----------- .../ACCESS/AMIE-Processor/handler/noop_test.go | 75 ------- .../handler/request_account_create_test.go | 189 ----------------- .../handler/request_account_inactivate_test.go | 146 ------------- .../handler/request_account_reactivate_test.go | 129 ------------ .../handler/request_person_merge_test.go | 149 -------------- .../handler/request_project_create_test.go | 226 --------------------- .../handler/request_project_inactivate_test.go | 152 -------------- .../handler/request_project_reactivate_test.go | 152 -------------- .../handler/request_user_modify_test.go | 167 --------------- .../ACCESS/AMIE-Processor/handler/router_test.go | 136 ------------- .../ACCESS/AMIE-Processor/handler/testutil_test.go | 49 ----- 14 files changed, 1991 deletions(-) diff --git a/connectors/ACCESS/AMIE-Processor/handler/data_account_create_test.go b/connectors/ACCESS/AMIE-Processor/handler/data_account_create_test.go deleted file mode 100644 index 04e04bc5c..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/data_account_create_test.go +++ /dev/null @@ -1,148 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockDACPersonService struct{ mock.Mock } - -func (m *mockDACPersonService) PersistDNsForPerson(ctx context.Context, tx *sql.Tx, personID string, dnList []string) error { - return m.Called(ctx, tx, personID, dnList).Error(0) -} - -type mockDACAmieClient struct{ mock.Mock } - -func (m *mockDACAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockDACAuditService struct{ mock.Mock } - -func (m *mockDACAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestDataAccountCreateHandler_SupportsType(t *testing.T) { - h := NewDataAccountCreateHandler( - &mockDACPersonService{}, &mockDACAmieClient{}, &mockDACAuditService{}, - ) - assert.Equal(t, "data_account_create", h.SupportsType()) -} - -func TestDataAccountCreateHandler(t *testing.T) { - validFixture := loadTestData(t, "data_account_create/incoming-data.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockDACPersonService, ac *mockDACAmieClient, aud *mockDACAuditService) - wantErr string - }{ - { - name: "valid packet with DNs processes successfully", - input: validFixture, - setupMocks: func(ps *mockDACPersonService, ac *mockDACAmieClient, aud *mockDACAuditService) { - ps.On("PersistDNsForPerson", mock.Anything, mock.Anything, "test-user-person-123", mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditPersistDNs, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497918), mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-user-person-123", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "missing PersonID returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - }}, - wantErr: "'PersonID' must not be empty", - }, - { - name: "packet without DnList still sends reply", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - "PersonID": "test-user-person-123", - }}, - setupMocks: func(ps *mockDACPersonService, ac *mockDACAmieClient, aud *mockDACAuditService) { - // PersistDNsForPerson should NOT be called when DnList absent - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockDACPersonService{} - ac := &mockDACAmieClient{} - aud := &mockDACAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ac, aud) - } - - h := NewDataAccountCreateHandler(ps, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497918, Type: "data_account_create"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - - if tt.name == "packet without DnList still sends reply" { - ps.AssertNotCalled(t, "PersistDNsForPerson", mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/data_project_create_test.go b/connectors/ACCESS/AMIE-Processor/handler/data_project_create_test.go deleted file mode 100644 index 8e9d92b7d..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/data_project_create_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockDPCPersonService struct{ mock.Mock } - -func (m *mockDPCPersonService) PersistDNsForPerson(ctx context.Context, tx *sql.Tx, personID string, dnList []string) error { - return m.Called(ctx, tx, personID, dnList).Error(0) -} - -type mockDPCAmieClient struct{ mock.Mock } - -func (m *mockDPCAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockDPCAuditService struct{ mock.Mock } - -func (m *mockDPCAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestDataProjectCreateHandler_SupportsType(t *testing.T) { - h := NewDataProjectCreateHandler( - &mockDPCPersonService{}, &mockDPCAmieClient{}, &mockDPCAuditService{}, - ) - assert.Equal(t, "data_project_create", h.SupportsType()) -} - -func TestDataProjectCreateHandler(t *testing.T) { - validFixture := loadTestData(t, "data_project_create/incoming-data.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockDPCPersonService, ac *mockDPCAmieClient, aud *mockDPCAuditService) - wantErr string - }{ - { - name: "valid packet with DNs processes successfully", - input: validFixture, - setupMocks: func(ps *mockDPCPersonService, ac *mockDPCAmieClient, aud *mockDPCAuditService) { - ps.On("PersistDNsForPerson", mock.Anything, mock.Anything, "test-person-456", mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditPersistDNs, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497909), mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-person-456", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "missing PersonID returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-123", - }}, - wantErr: "'PersonID' must not be empty", - }, - { - name: "packet without DnList still sends reply", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-123", - "PersonID": "test-person-456", - }}, - setupMocks: func(ps *mockDPCPersonService, ac *mockDPCAmieClient, aud *mockDPCAuditService) { - // PersistDNsForPerson should NOT be called when DnList is absent - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockDPCPersonService{} - ac := &mockDPCAmieClient{} - aud := &mockDPCAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ac, aud) - } - - h := NewDataProjectCreateHandler(ps, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497909, Type: "data_project_create"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - - // Verify PersistDNsForPerson was NOT called when DnList is absent - if tt.name == "packet without DnList still sends reply" { - ps.AssertNotCalled(t, "PersistDNsForPerson", mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/inform_transaction_complete_test.go b/connectors/ACCESS/AMIE-Processor/handler/inform_transaction_complete_test.go deleted file mode 100644 index 52534c81c..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/inform_transaction_complete_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockITCAuditService struct{ mock.Mock } - -func (m *mockITCAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestInformTransactionCompleteHandler_SupportsType(t *testing.T) { - h := NewInformTransactionCompleteHandler(&mockITCAuditService{}) - assert.Equal(t, "inform_transaction_complete", h.SupportsType()) -} - -func TestInformTransactionCompleteHandler(t *testing.T) { - validFixture := loadTestData(t, "inform_transaction_complete/incoming-inform.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(aud *mockITCAuditService) - wantErr string - }{ - { - name: "valid packet logs transaction complete", - input: validFixture, - setupMocks: func(aud *mockITCAuditService) { - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, - model.AuditTransactionComplete, "transaction", "", mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing StatusCode uses Unknown as default", - input: map[string]any{"body": map[string]any{ - "Message": "done", - }}, - setupMocks: func(aud *mockITCAuditService) { - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, - model.AuditTransactionComplete, "transaction", "", - mock.MatchedBy(func(summary string) bool { - return len(summary) > 0 - })).Return(nil) - }, - }, - { - name: "no reply is sent (terminal packet)", - input: map[string]any{"body": map[string]any{ - "StatusCode": "Success", - "Message": "All good", - }}, - setupMocks: func(aud *mockITCAuditService) { - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, - model.AuditTransactionComplete, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aud := &mockITCAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(aud) - } - - h := NewInformTransactionCompleteHandler(aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497913, Type: "inform_transaction_complete"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - - // Verify the audit log was called for terminal packet cases - if tt.setupMocks != nil { - aud.AssertExpectations(t) - } - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/noop_test.go b/connectors/ACCESS/AMIE-Processor/handler/noop_test.go deleted file mode 100644 index 67b3dbbbd..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/noop_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestNoOpHandler_SupportsType(t *testing.T) { - h := NewNoOpHandler() - assert.Equal(t, "*", h.SupportsType()) -} - -func TestNoOpHandler(t *testing.T) { - tests := []struct { - name string - packetType string - }{ - { - name: "unknown packet type returns nil", - packetType: "unknown_packet_type", - }, - { - name: "any packet type returns nil without error", - packetType: "some_other_type", - }, - { - name: "empty packet type returns nil", - packetType: "", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - h := NewNoOpHandler() - packet := &model.Packet{ - ID: "test-id", - AmieID: 12345, - Type: tt.packetType, - } - - err := h.Handle(context.Background(), nil, map[string]any{}, packet, "event-1") - require.NoError(t, err) - }) - } -} - -func TestNoOpHandler_DoesNotPanic_WithNilPacketJSON(t *testing.T) { - h := NewNoOpHandler() - packet := &model.Packet{ID: "test-id", Type: "unknown"} - // The NoOp handler ignores packetJSON entirely. - require.NotPanics(t, func() { - _ = h.Handle(context.Background(), nil, nil, packet, "event-1") - }) -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_account_create_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_account_create_test.go deleted file mode 100644 index 3d32510d7..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_account_create_test.go +++ /dev/null @@ -1,189 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRACPersonService struct{ mock.Mock } - -func (m *mockRACPersonService) FindOrCreateFromPacket(ctx context.Context, tx *sql.Tx, body map[string]any) (*model.Person, error) { - args := m.Called(ctx, tx, body) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.Person), args.Error(1) -} - -type mockRACAccountService struct{ mock.Mock } - -func (m *mockRACAccountService) ProvisionClusterAccount(ctx context.Context, tx *sql.Tx, person *model.Person) (*model.ClusterAccount, error) { - args := m.Called(ctx, tx, person) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.ClusterAccount), args.Error(1) -} - -type mockRACProjectService struct{ mock.Mock } - -func (m *mockRACProjectService) CreateOrFindProject(ctx context.Context, tx *sql.Tx, projectID, grantNumber string) (*model.Project, error) { - args := m.Called(ctx, tx, projectID, grantNumber) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.Project), args.Error(1) -} - -type mockRACMembershipService struct{ mock.Mock } - -func (m *mockRACMembershipService) CreateMembership(ctx context.Context, tx *sql.Tx, projectID, clusterAccountID, role string) (*model.ProjectMembership, error) { - args := m.Called(ctx, tx, projectID, clusterAccountID, role) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.ProjectMembership), args.Error(1) -} - -type mockRACAmieClient struct{ mock.Mock } - -func (m *mockRACAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRACAuditService struct{ mock.Mock } - -func (m *mockRACAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestAccountCreateHandler_SupportsType(t *testing.T) { - h := NewRequestAccountCreateHandler( - &mockRACPersonService{}, &mockRACAccountService{}, - &mockRACProjectService{}, &mockRACMembershipService{}, - &mockRACAmieClient{}, &mockRACAuditService{}, - ) - assert.Equal(t, "request_account_create", h.SupportsType()) -} - -func TestRequestAccountCreateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_account_create/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockRACPersonService, as *mockRACAccountService, prj *mockRACProjectService, ms *mockRACMembershipService, ac *mockRACAmieClient, aud *mockRACAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ps *mockRACPersonService, as *mockRACAccountService, prj *mockRACProjectService, ms *mockRACMembershipService, ac *mockRACAmieClient, aud *mockRACAuditService) { - person := &model.Person{ID: "person-123"} - account := &model.ClusterAccount{ID: "account-123", Username: "testuser"} - project := &model.Project{ID: "test-project-456", GrantNumber: "TEST123"} - - ps.On("FindOrCreateFromPacket", mock.Anything, mock.Anything, mock.Anything).Return(person, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreatePerson, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - as.On("ProvisionClusterAccount", mock.Anything, mock.Anything, person).Return(account, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreateAccount, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - prj.On("CreateOrFindProject", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(project, nil) - - ms.On("CreateMembership", mock.Anything, mock.Anything, "test-project-456", account.ID, "USER").Return(&model.ProjectMembership{}, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497917), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "GrantNumber": "TEST123", - "UserGlobalID": "12345", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "missing GrantNumber returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - "UserGlobalID": "12345", - }}, - wantErr: "'GrantNumber' must not be empty", - }, - { - name: "missing UserGlobalID returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - "GrantNumber": "TEST123", - }}, - wantErr: "'UserGlobalID' must not be empty", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRACPersonService{} - as := &mockRACAccountService{} - prj := &mockRACProjectService{} - ms := &mockRACMembershipService{} - ac := &mockRACAmieClient{} - aud := &mockRACAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, as, prj, ms, ac, aud) - } - - h := NewRequestAccountCreateHandler(ps, as, prj, ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497917, Type: "request_account_create"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_account_inactivate_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_account_inactivate_test.go deleted file mode 100644 index a0639ace2..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_account_inactivate_test.go +++ /dev/null @@ -1,146 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRAIMembershipService struct{ mock.Mock } - -func (m *mockRAIMembershipService) InactivateMembershipsByPersonAndProject(ctx context.Context, tx *sql.Tx, projectID, personID string) (int, error) { - args := m.Called(ctx, tx, projectID, personID) - return args.Int(0), args.Error(1) -} - -type mockRAIAmieClient struct{ mock.Mock } - -func (m *mockRAIAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRAIAuditService struct{ mock.Mock } - -func (m *mockRAIAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestAccountInactivateHandler_SupportsType(t *testing.T) { - h := NewRequestAccountInactivateHandler( - &mockRAIMembershipService{}, &mockRAIAmieClient{}, &mockRAIAuditService{}, - ) - assert.Equal(t, "request_account_inactivate", h.SupportsType()) -} - -func TestRequestAccountInactivateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_account_inactivate/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ms *mockRAIMembershipService, ac *mockRAIAmieClient, aud *mockRAIAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ms *mockRAIMembershipService, ac *mockRAIAmieClient, aud *mockRAIAuditService) { - ms.On("InactivateMembershipsByPersonAndProject", mock.Anything, mock.Anything, "test-project-456", "test-user-person-123").Return(1, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497919), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-user-person-123", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "missing PersonID returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - }}, - wantErr: "'PersonID' must not be empty", - }, - { - name: "reply contains correct ProjectID and PersonID", - input: map[string]any{"body": map[string]any{ - "ProjectID": "prj-abc", - "PersonID": "per-xyz", - }}, - setupMocks: func(ms *mockRAIMembershipService, ac *mockRAIAmieClient, aud *mockRAIAuditService) { - ms.On("InactivateMembershipsByPersonAndProject", mock.Anything, mock.Anything, "prj-abc", "per-xyz").Return(2, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - body, ok := reply["body"].(map[string]any) - return ok && body["ProjectID"] == "prj-abc" && body["PersonID"] == "per-xyz" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ms := &mockRAIMembershipService{} - ac := &mockRAIAmieClient{} - aud := &mockRAIAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ms, ac, aud) - } - - h := NewRequestAccountInactivateHandler(ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497919, Type: "request_account_inactivate"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_account_reactivate_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_account_reactivate_test.go deleted file mode 100644 index 7104f533e..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_account_reactivate_test.go +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRARMembershipService struct{ mock.Mock } - -func (m *mockRARMembershipService) ReactivateMembershipsByPersonAndProject(ctx context.Context, tx *sql.Tx, projectID, personID string) (int, error) { - args := m.Called(ctx, tx, projectID, personID) - return args.Int(0), args.Error(1) -} - -type mockRARAmieClient struct{ mock.Mock } - -func (m *mockRARAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRARAuditService struct{ mock.Mock } - -func (m *mockRARAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestAccountReactivateHandler_SupportsType(t *testing.T) { - h := NewRequestAccountReactivateHandler( - &mockRARMembershipService{}, &mockRARAmieClient{}, &mockRARAuditService{}, - ) - assert.Equal(t, "request_account_reactivate", h.SupportsType()) -} - -func TestRequestAccountReactivateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_account_reactivate/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ms *mockRARMembershipService, ac *mockRARAmieClient, aud *mockRARAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ms *mockRARMembershipService, ac *mockRARAmieClient, aud *mockRARAuditService) { - ms.On("ReactivateMembershipsByPersonAndProject", mock.Anything, mock.Anything, "test-project-456", "test-user-person-123").Return(1, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497923), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-user-person-123", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "missing PersonID returns error", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-456", - }}, - wantErr: "'PersonID' must not be empty", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ms := &mockRARMembershipService{} - ac := &mockRARAmieClient{} - aud := &mockRARAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ms, ac, aud) - } - - h := NewRequestAccountReactivateHandler(ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497923, Type: "request_account_reactivate"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_person_merge_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_person_merge_test.go deleted file mode 100644 index d87bd9053..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_person_merge_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRPMPersonService struct{ mock.Mock } - -func (m *mockRPMPersonService) MergePersons(ctx context.Context, tx *sql.Tx, survivingID, retiringID string) error { - return m.Called(ctx, tx, survivingID, retiringID).Error(0) -} - -type mockRPMAmieClient struct{ mock.Mock } - -func (m *mockRPMAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRPMAuditService struct{ mock.Mock } - -func (m *mockRPMAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestPersonMergeHandler_SupportsType(t *testing.T) { - h := NewRequestPersonMergeHandler( - &mockRPMPersonService{}, &mockRPMAmieClient{}, &mockRPMAuditService{}, - ) - assert.Equal(t, "request_person_merge", h.SupportsType()) -} - -func TestRequestPersonMergeHandler(t *testing.T) { - validFixture := loadTestData(t, "request_person_merge/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockRPMPersonService, ac *mockRPMAmieClient, aud *mockRPMAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ps *mockRPMPersonService, ac *mockRPMAmieClient, aud *mockRPMAuditService) { - ps.On("MergePersons", mock.Anything, mock.Anything, "test-person-primary-123", "test-person-secondary-456").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditMergePersons, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497920), mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing KeepPersonID returns error", - input: map[string]any{"body": map[string]any{ - "DeletePersonID": "test-person-secondary-456", - }}, - wantErr: "'KeepPersonID' must not be empty", - }, - { - name: "missing DeletePersonID returns error", - input: map[string]any{"body": map[string]any{ - "KeepPersonID": "test-person-primary-123", - }}, - wantErr: "'DeletePersonID' must not be empty", - }, - { - name: "reply type is inform_transaction_complete", - input: map[string]any{"body": map[string]any{ - "KeepPersonID": "keep-person-1", - "DeletePersonID": "delete-person-2", - }}, - setupMocks: func(ps *mockRPMPersonService, ac *mockRPMAmieClient, aud *mockRPMAuditService) { - ps.On("MergePersons", mock.Anything, mock.Anything, "keep-person-1", "delete-person-2").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditMergePersons, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - body, ok := reply["body"].(map[string]any) - return ok && - reply["type"] == "inform_transaction_complete" && - body["StatusCode"] == "Success" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRPMPersonService{} - ac := &mockRPMAmieClient{} - aud := &mockRPMAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ac, aud) - } - - h := NewRequestPersonMergeHandler(ps, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497920, Type: "request_person_merge"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_project_create_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_project_create_test.go deleted file mode 100644 index e5782e974..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_project_create_test.go +++ /dev/null @@ -1,226 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRPCPersonService struct{ mock.Mock } - -func (m *mockRPCPersonService) FindOrCreateFromPacket(ctx context.Context, tx *sql.Tx, body map[string]any) (*model.Person, error) { - args := m.Called(ctx, tx, body) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.Person), args.Error(1) -} - -type mockRPCAccountService struct{ mock.Mock } - -func (m *mockRPCAccountService) ProvisionClusterAccount(ctx context.Context, tx *sql.Tx, person *model.Person) (*model.ClusterAccount, error) { - args := m.Called(ctx, tx, person) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.ClusterAccount), args.Error(1) -} - -type mockRPCProjectService struct{ mock.Mock } - -func (m *mockRPCProjectService) CreateOrFindProject(ctx context.Context, tx *sql.Tx, projectID, grantNumber string) (*model.Project, error) { - args := m.Called(ctx, tx, projectID, grantNumber) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.Project), args.Error(1) -} - -type mockRPCMembershipService struct{ mock.Mock } - -func (m *mockRPCMembershipService) CreateMembership(ctx context.Context, tx *sql.Tx, projectID, clusterAccountID, role string) (*model.ProjectMembership, error) { - args := m.Called(ctx, tx, projectID, clusterAccountID, role) - if args.Get(0) == nil { - return nil, args.Error(1) - } - return args.Get(0).(*model.ProjectMembership), args.Error(1) -} - -type mockRPCAmieClient struct{ mock.Mock } - -func (m *mockRPCAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRPCAuditService struct{ mock.Mock } - -func (m *mockRPCAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - -func newRPCHandler( - ps *mockRPCPersonService, - as *mockRPCAccountService, - prj *mockRPCProjectService, - ms *mockRPCMembershipService, - ac *mockRPCAmieClient, - aud *mockRPCAuditService, -) *RequestProjectCreateHandler { - return NewRequestProjectCreateHandler(ps, as, prj, ms, ac, aud) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestProjectCreateHandler_SupportsType(t *testing.T) { - h := newRPCHandler( - &mockRPCPersonService{}, &mockRPCAccountService{}, - &mockRPCProjectService{}, &mockRPCMembershipService{}, - &mockRPCAmieClient{}, &mockRPCAuditService{}, - ) - assert.Equal(t, "request_project_create", h.SupportsType()) -} - -func TestRequestProjectCreateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_project_create/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockRPCPersonService, as *mockRPCAccountService, prj *mockRPCProjectService, ms *mockRPCMembershipService, ac *mockRPCAmieClient, aud *mockRPCAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ps *mockRPCPersonService, as *mockRPCAccountService, prj *mockRPCProjectService, ms *mockRPCMembershipService, ac *mockRPCAmieClient, aud *mockRPCAuditService) { - person := &model.Person{ID: "person-123"} - account := &model.ClusterAccount{ID: "account-123", Username: "hwan"} - project := &model.Project{ID: "project-123", GrantNumber: "NNT259276"} - - ps.On("FindOrCreateFromPacket", mock.Anything, mock.Anything, mock.Anything).Return(person, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreatePerson, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - as.On("ProvisionClusterAccount", mock.Anything, mock.Anything, person).Return(account, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreateAccount, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - prj.On("CreateOrFindProject", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(project, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreateProject, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ms.On("CreateMembership", mock.Anything, mock.Anything, project.ID, account.ID, "PI").Return(&model.ProjectMembership{}, nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditCreateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497907), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing GrantNumber returns error", - input: map[string]any{"body": map[string]any{ - "PiGlobalID": "PI123", - "PiFirstName": "John", - "PiLastName": "Doe", - }}, - wantErr: "'GrantNumber' must not be empty", - }, - { - name: "missing PiGlobalID returns error", - input: map[string]any{"body": map[string]any{ - "GrantNumber": "NNT259276", - "PiFirstName": "John", - "PiLastName": "Doe", - }}, - wantErr: "'PiGlobalID' must not be empty", - }, - { - name: "missing PiFirstName returns error", - input: map[string]any{"body": map[string]any{ - "GrantNumber": "NNT259276", - "PiGlobalID": "PI123", - "PiLastName": "Doe", - }}, - wantErr: "'PiFirstName' must not be empty", - }, - { - name: "missing PiLastName returns error", - input: map[string]any{"body": map[string]any{ - "GrantNumber": "NNT259276", - "PiGlobalID": "PI123", - "PiFirstName": "John", - }}, - wantErr: "'PiLastName' must not be empty", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRPCPersonService{} - as := &mockRPCAccountService{} - prj := &mockRPCProjectService{} - ms := &mockRPCMembershipService{} - ac := &mockRPCAmieClient{} - aud := &mockRPCAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, as, prj, ms, ac, aud) - } - - h := newRPCHandler(ps, as, prj, ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497907, Type: "request_project_create"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - - // Verify key reply assertions for the happy path - if tt.name == "valid packet processes successfully" { - ac.AssertCalled(t, "ReplyToPacket", mock.Anything, int64(233497907), mock.Anything) - ps.AssertCalled(t, "FindOrCreateFromPacket", mock.Anything, mock.Anything, mock.Anything) - as.AssertCalled(t, "ProvisionClusterAccount", mock.Anything, mock.Anything, mock.Anything) - prj.AssertCalled(t, "CreateOrFindProject", mock.Anything, mock.Anything, mock.Anything, mock.Anything) - ms.AssertCalled(t, "CreateMembership", mock.Anything, mock.Anything, mock.Anything, mock.Anything, "PI") - } - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_project_inactivate_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_project_inactivate_test.go deleted file mode 100644 index 46d6bddd5..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_project_inactivate_test.go +++ /dev/null @@ -1,152 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRPIProjectService struct{ mock.Mock } - -func (m *mockRPIProjectService) InactivateProject(ctx context.Context, tx *sql.Tx, projectID string) error { - return m.Called(ctx, tx, projectID).Error(0) -} - -type mockRPIMembershipService struct{ mock.Mock } - -func (m *mockRPIMembershipService) InactivateAllForProject(ctx context.Context, tx *sql.Tx, projectID string) error { - return m.Called(ctx, tx, projectID).Error(0) -} - -type mockRPIAmieClient struct{ mock.Mock } - -func (m *mockRPIAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRPIAuditService struct{ mock.Mock } - -func (m *mockRPIAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestProjectInactivateHandler_SupportsType(t *testing.T) { - h := NewRequestProjectInactivateHandler( - &mockRPIProjectService{}, &mockRPIMembershipService{}, - &mockRPIAmieClient{}, &mockRPIAuditService{}, - ) - assert.Equal(t, "request_project_inactivate", h.SupportsType()) -} - -func TestRequestProjectInactivateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_project_inactivate/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockRPIProjectService, ms *mockRPIMembershipService, ac *mockRPIAmieClient, aud *mockRPIAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ps *mockRPIProjectService, ms *mockRPIMembershipService, ac *mockRPIAmieClient, aud *mockRPIAuditService) { - ps.On("InactivateProject", mock.Anything, mock.Anything, "test-project-123").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateProject, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ms.On("InactivateAllForProject", mock.Anything, mock.Anything, "test-project-123").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497911), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-person-456", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "optional PersonID is included in reply when present", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-999", - "PersonID": "opt-person-001", - }}, - setupMocks: func(ps *mockRPIProjectService, ms *mockRPIMembershipService, ac *mockRPIAmieClient, aud *mockRPIAuditService) { - ps.On("InactivateProject", mock.Anything, mock.Anything, "test-project-999").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateProject, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ms.On("InactivateAllForProject", mock.Anything, mock.Anything, "test-project-999").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditInactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - body, ok := reply["body"].(map[string]any) - return ok && body["PersonID"] == "opt-person-001" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRPIProjectService{} - ms := &mockRPIMembershipService{} - ac := &mockRPIAmieClient{} - aud := &mockRPIAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ms, ac, aud) - } - - h := NewRequestProjectInactivateHandler(ps, ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497911, Type: "request_project_inactivate"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_project_reactivate_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_project_reactivate_test.go deleted file mode 100644 index 16611ff4b..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_project_reactivate_test.go +++ /dev/null @@ -1,152 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRPRProjectService struct{ mock.Mock } - -func (m *mockRPRProjectService) ReactivateProject(ctx context.Context, tx *sql.Tx, projectID string) error { - return m.Called(ctx, tx, projectID).Error(0) -} - -type mockRPRMembershipService struct{ mock.Mock } - -func (m *mockRPRMembershipService) ReactivatePiMembership(ctx context.Context, tx *sql.Tx, projectID string) error { - return m.Called(ctx, tx, projectID).Error(0) -} - -type mockRPRAmieClient struct{ mock.Mock } - -func (m *mockRPRAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRPRAuditService struct{ mock.Mock } - -func (m *mockRPRAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestProjectReactivateHandler_SupportsType(t *testing.T) { - h := NewRequestProjectReactivateHandler( - &mockRPRProjectService{}, &mockRPRMembershipService{}, - &mockRPRAmieClient{}, &mockRPRAuditService{}, - ) - assert.Equal(t, "request_project_reactivate", h.SupportsType()) -} - -func TestRequestProjectReactivateHandler(t *testing.T) { - validFixture := loadTestData(t, "request_project_reactivate/incoming-request.json") - - tests := []struct { - name string - input map[string]any - setupMocks func(ps *mockRPRProjectService, ms *mockRPRMembershipService, ac *mockRPRAmieClient, aud *mockRPRAuditService) - wantErr string - }{ - { - name: "valid packet processes successfully", - input: validFixture, - setupMocks: func(ps *mockRPRProjectService, ms *mockRPRMembershipService, ac *mockRPRAmieClient, aud *mockRPRAuditService) { - ps.On("ReactivateProject", mock.Anything, mock.Anything, "test-project-123").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReactivateProject, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ms.On("ReactivatePiMembership", mock.Anything, mock.Anything, "test-project-123").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497914), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ProjectID returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-person-456", - }}, - wantErr: "'ProjectID' must not be empty", - }, - { - name: "optional PersonID is forwarded in reply", - input: map[string]any{"body": map[string]any{ - "ProjectID": "test-project-777", - "PersonID": "opt-person-002", - }}, - setupMocks: func(ps *mockRPRProjectService, ms *mockRPRMembershipService, ac *mockRPRAmieClient, aud *mockRPRAuditService) { - ps.On("ReactivateProject", mock.Anything, mock.Anything, "test-project-777").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReactivateProject, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ms.On("ReactivatePiMembership", mock.Anything, mock.Anything, "test-project-777").Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReactivateMembership, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.MatchedBy(func(reply map[string]any) bool { - body, ok := reply["body"].(map[string]any) - return ok && body["PersonID"] == "opt-person-002" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRPRProjectService{} - ms := &mockRPRMembershipService{} - ac := &mockRPRAmieClient{} - aud := &mockRPRAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ms, ac, aud) - } - - h := NewRequestProjectReactivateHandler(ps, ms, ac, aud) - packet := &model.Packet{ID: "test-id", AmieID: 233497914, Type: "request_project_reactivate"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/request_user_modify_test.go b/connectors/ACCESS/AMIE-Processor/handler/request_user_modify_test.go deleted file mode 100644 index c55293d08..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/request_user_modify_test.go +++ /dev/null @@ -1,167 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mocks -// --------------------------------------------------------------------------- - -type mockRUMPersonService struct{ mock.Mock } - -func (m *mockRUMPersonService) ReplaceFromModifyPacket(ctx context.Context, tx *sql.Tx, body map[string]any) error { - return m.Called(ctx, tx, body).Error(0) -} - -func (m *mockRUMPersonService) DeleteFromModifyPacket(ctx context.Context, tx *sql.Tx, body map[string]any) error { - return m.Called(ctx, tx, body).Error(0) -} - -type mockRUMAmieClient struct{ mock.Mock } - -func (m *mockRUMAmieClient) ReplyToPacket(ctx context.Context, packetRecID int64, reply map[string]any) error { - return m.Called(ctx, packetRecID, reply).Error(0) -} - -type mockRUMAuditService struct{ mock.Mock } - -func (m *mockRUMAuditService) Log(ctx context.Context, tx *sql.Tx, packetID, eventID string, action model.AuditAction, entityType, entityID, summary string) error { - return m.Called(ctx, tx, packetID, eventID, action, entityType, entityID, summary).Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRequestUserModifyHandler_SupportsType(t *testing.T) { - h := NewRequestUserModifyHandler( - &mockRUMPersonService{}, &mockRUMAmieClient{}, &mockRUMAuditService{}, - ) - assert.Equal(t, "request_user_modify", h.SupportsType()) -} - -func TestRequestUserModifyHandler(t *testing.T) { - replaceFixture := loadTestData(t, "request_user_modify_replace/incoming-request.json") - deleteFixture := loadTestData(t, "request_user_modify_delete/incoming-request.json") - - tests := []struct { - name string - input map[string]any - amieID int64 - setupMocks func(ps *mockRUMPersonService, ac *mockRUMAmieClient, aud *mockRUMAuditService) - wantErr string - }{ - { - name: "replace action processes successfully", - input: replaceFixture, - amieID: 233497921, - setupMocks: func(ps *mockRUMPersonService, ac *mockRUMAmieClient, aud *mockRUMAuditService) { - ps.On("ReplaceFromModifyPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditUpdatePerson, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497921), mock.MatchedBy(func(reply map[string]any) bool { - return reply["type"] == "inform_transaction_complete" - })).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "delete action processes successfully", - input: deleteFixture, - amieID: 233497922, - setupMocks: func(ps *mockRUMPersonService, ac *mockRUMAmieClient, aud *mockRUMAuditService) { - ps.On("DeleteFromModifyPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditDeletePerson, mock.Anything, mock.Anything, mock.Anything).Return(nil) - - ac.On("ReplyToPacket", mock.Anything, int64(233497922), mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - { - name: "missing body returns error", - input: map[string]any{}, - wantErr: "packet missing 'body'", - }, - { - name: "missing ActionType returns error", - input: map[string]any{"body": map[string]any{ - "PersonID": "test-person", - }}, - wantErr: "'ActionType' must not be empty", - }, - { - name: "unsupported ActionType returns error", - input: map[string]any{"body": map[string]any{ - "ActionType": "update", - "PersonID": "test-person", - }}, - wantErr: "unsupported ActionType: update", - }, - { - name: "ActionType is case-insensitive for replace", - input: map[string]any{"body": map[string]any{ - "ActionType": "REPLACE", - "PersonID": "test-person", - }}, - setupMocks: func(ps *mockRUMPersonService, ac *mockRUMAmieClient, aud *mockRUMAuditService) { - ps.On("ReplaceFromModifyPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditUpdatePerson, mock.Anything, mock.Anything, mock.Anything).Return(nil) - ac.On("ReplyToPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - aud.On("Log", mock.Anything, mock.Anything, mock.Anything, mock.Anything, model.AuditReplySent, mock.Anything, mock.Anything, mock.Anything).Return(nil) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - ps := &mockRUMPersonService{} - ac := &mockRUMAmieClient{} - aud := &mockRUMAuditService{} - - if tt.setupMocks != nil { - tt.setupMocks(ps, ac, aud) - } - - h := NewRequestUserModifyHandler(ps, ac, aud) - amieID := tt.amieID - if amieID == 0 { - amieID = 12345 - } - packet := &model.Packet{ID: "test-id", AmieID: amieID, Type: "request_user_modify"} - - err := h.Handle(context.Background(), nil, tt.input, packet, "event-1") - - if tt.wantErr != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tt.wantErr) - return - } - require.NoError(t, err) - }) - } -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/router_test.go b/connectors/ACCESS/AMIE-Processor/handler/router_test.go deleted file mode 100644 index 350036c13..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/router_test.go +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "context" - "database/sql" - "testing" - - "github.com/apache/airavata-custos/connectors/ACCESS/AMIE-Processor/model" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -// --------------------------------------------------------------------------- -// Mock handler used only by router tests -// --------------------------------------------------------------------------- - -type mockPacketHandler struct { - mock.Mock -} - -func (m *mockPacketHandler) SupportsType() string { - return m.Called().String(0) -} - -func (m *mockPacketHandler) Handle(ctx context.Context, tx *sql.Tx, packetJSON map[string]any, packet *model.Packet, eventID string) error { - args := m.Called(ctx, tx, packetJSON, packet, eventID) - return args.Error(0) -} - -// --------------------------------------------------------------------------- -// Tests -// --------------------------------------------------------------------------- - -func TestRouter(t *testing.T) { - tests := []struct { - name string - packetType string - wantHandler1 bool - wantHandler2 bool - wantNoOpInvoked bool - wantErr bool - }{ - { - name: "routes to matching handler (handler1)", - packetType: "request_project_create", - wantHandler1: true, - wantHandler2: false, - }, - { - name: "routes to different matching handler (handler2)", - packetType: "request_account_create", - wantHandler1: false, - wantHandler2: true, - }, - { - name: "unknown type falls back to NoOp", - packetType: "unknown_packet_type", - wantHandler1: false, - wantHandler2: false, - wantNoOpInvoked: true, - }, - { - name: "case-insensitive matching routes correctly", - packetType: "REQUEST_PROJECT_CREATE", - wantHandler1: true, - wantHandler2: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - h1 := &mockPacketHandler{} - h2 := &mockPacketHandler{} - noOp := NewNoOpHandler() - - h1.On("SupportsType").Return("request_project_create") - h2.On("SupportsType").Return("request_account_create") - - if tt.wantHandler1 { - h1.On("Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - } - if tt.wantHandler2 { - h2.On("Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) - } - - router := NewRouter(h1, h2, noOp) - packet := &model.Packet{ID: "test-id", AmieID: 12345, Type: tt.packetType} - - err := router.Route(context.Background(), nil, map[string]any{}, packet, "event-1") - - if tt.wantErr { - require.Error(t, err) - return - } - require.NoError(t, err) - - if tt.wantHandler1 { - h1.AssertCalled(t, "Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } else { - h1.AssertNotCalled(t, "Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } - - if tt.wantHandler2 { - h2.AssertCalled(t, "Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } else { - h2.AssertNotCalled(t, "Handle", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything) - } - }) - } -} - -func TestRouter_NoHandlerAndNoNoOp_ReturnsError(t *testing.T) { - router := NewRouter() // no handlers at all, no noop - packet := &model.Packet{ID: "test-id", Type: "unknown_type"} - err := router.Route(context.Background(), nil, map[string]any{}, packet, "e1") - assert.Error(t, err) - assert.Contains(t, err.Error(), "no handler for packet type") -} diff --git a/connectors/ACCESS/AMIE-Processor/handler/testutil_test.go b/connectors/ACCESS/AMIE-Processor/handler/testutil_test.go deleted file mode 100644 index d5eba865b..000000000 --- a/connectors/ACCESS/AMIE-Processor/handler/testutil_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package handler - -import ( - "encoding/json" - "os" - "path/filepath" - "runtime" - "testing" - - "github.com/stretchr/testify/require" -) - -// testdataDir returns the absolute path to the module-level testdata directory. -// It uses runtime.Caller so the path is correct regardless of where tests run. -func testdataDir() string { - // handler/ is one level below the module root; go up one directory. - _, filename, _, _ := runtime.Caller(0) - return filepath.Join(filepath.Dir(filename), "..", "testdata") -} - -// loadTestData reads a JSON fixture file from testdata/<subpath> and unmarshals -// it into a map[string]any. The test fails immediately if the file cannot be -// read or parsed. -func loadTestData(t *testing.T, subpath string) map[string]any { - t.Helper() - path := filepath.Join(testdataDir(), subpath) - data, err := os.ReadFile(path) - require.NoError(t, err, "reading fixture %s", path) - var m map[string]any - require.NoError(t, json.Unmarshal(data, &m), "parsing fixture %s", path) - return m -}
