forked from grassrootseconomics/visedriver
		
	Added tests for CreateAccount and SavePin
This commit is contained in:
		
							parent
							
								
									b344720fdc
								
							
						
					
					
						commit
						802c3f92df
					
				| @ -29,9 +29,21 @@ type FSData struct { | ||||
| 	St   *state.State | ||||
| } | ||||
| 
 | ||||
| type AccountCreator interface { | ||||
| 	CreateAccount() (*models.AccountResponse, error) | ||||
| } | ||||
| 
 | ||||
| // ServerAccountCreator implements AccountCreator using the server package
 | ||||
| type ServerAccountCreator struct{} | ||||
| 
 | ||||
| func (s *ServerAccountCreator) CreateAccount() (*models.AccountResponse, error) { | ||||
| 	return server.CreateAccount() | ||||
| } | ||||
| 
 | ||||
| type Handlers struct { | ||||
| 	fs                 *FSData | ||||
| 	accountFileHandler *utils.AccountFileHandler | ||||
| 	accountCreator     AccountCreator | ||||
| } | ||||
| 
 | ||||
| func NewHandlers(path string, st *state.State) *Handlers { | ||||
| @ -41,6 +53,7 @@ func NewHandlers(path string, st *state.State) *Handlers { | ||||
| 			St:   st, | ||||
| 		}, | ||||
| 		accountFileHandler: utils.NewAccountFileHandler(path + "_data"), | ||||
| 		accountCreator:     &ServerAccountCreator{}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -81,7 +94,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) | ||||
| 		return res, err | ||||
| 	} | ||||
| 
 | ||||
| 	accountResp, err := server.CreateAccount() | ||||
| 	accountResp, err := h.accountCreator.CreateAccount() | ||||
| 	if err != nil { | ||||
| 		res.FlagSet = append(res.FlagSet, models.USERFLAG_ACCOUNT_CREATION_FAILED) | ||||
| 		return res, err | ||||
|  | ||||
| @ -1,11 +1,281 @@ | ||||
| package ussd | ||||
| 
 | ||||
| import "testing" | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"git.defalsify.org/vise.git/resource" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/models" | ||||
| 	"git.grassecon.net/urdt/ussd/internal/utils" | ||||
| ) | ||||
| 
 | ||||
| // MockAccountCreator implements AccountCreator for testing
 | ||||
| type MockAccountCreator struct { | ||||
| 	mockResponse *models.AccountResponse | ||||
| 	mockError    error | ||||
| } | ||||
| 
 | ||||
| func (m *MockAccountCreator) CreateAccount() (*models.AccountResponse, error) { | ||||
| 	return m.mockResponse, m.mockError | ||||
| } | ||||
| 
 | ||||
| func TestCreateAccount(t *testing.T) { | ||||
| 	// Setup
 | ||||
| 	tempDir, err := os.MkdirTemp("", "test_create_account") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Failed to create temp directory: %v", err) | ||||
| 	} | ||||
| 	defer os.RemoveAll(tempDir) // Clean up after the test run
 | ||||
| 
 | ||||
| func CreateAccountTest(t *testing.T){ | ||||
| 	 | ||||
| } | ||||
| 	sessionID := "07xxxxxxxx" | ||||
| 
 | ||||
| 	// Set up the data file path using the session ID
 | ||||
| 	accountFilePath := filepath.Join(tempDir, sessionID+"_data") | ||||
| 
 | ||||
| 	// Initialize account file handler
 | ||||
| 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath) | ||||
| 
 | ||||
| 	// Create a mock account creator
 | ||||
| 	mockAccountCreator := &MockAccountCreator{ | ||||
| 		mockResponse: &models.AccountResponse{ | ||||
| 			Ok: true, | ||||
| 			Result: struct { | ||||
| 				CustodialId json.Number `json:"custodialId"` | ||||
| 				PublicKey   string      `json:"publicKey"` | ||||
| 				TrackingId  string      `json:"trackingId"` | ||||
| 			}{ | ||||
| 				CustodialId: "test-custodial-id", | ||||
| 				PublicKey:   "test-public-key", | ||||
| 				TrackingId:  "test-tracking-id", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	// Initialize Handlers with mock account creator
 | ||||
| 	h := &Handlers{ | ||||
| 		accountFileHandler: accountFileHandler, | ||||
| 		accountCreator:     mockAccountCreator, | ||||
| 	} | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name           string | ||||
| 		existingData   map[string]string | ||||
| 		expectedResult resource.Result | ||||
| 		expectedData   map[string]string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:         "New account creation", | ||||
| 			existingData: nil, | ||||
| 			expectedResult: resource.Result{ | ||||
| 				FlagSet: []uint32{models.USERFLAG_ACCOUNT_CREATED}, | ||||
| 			}, | ||||
| 			expectedData: map[string]string{ | ||||
| 				"TrackingId":  "test-tracking-id", | ||||
| 				"PublicKey":   "test-public-key", | ||||
| 				"CustodialId": "test-custodial-id", | ||||
| 				"Status":      "PENDING", | ||||
| 				"Gender":      "Not provided", | ||||
| 				"YOB":         "Not provided", | ||||
| 				"Location":    "Not provided", | ||||
| 				"Offerings":   "Not provided", | ||||
| 				"FirstName":   "Not provided", | ||||
| 				"FamilyName":  "Not provided", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "Existing account", | ||||
| 			existingData: map[string]string{ | ||||
| 				"TrackingId":  "test-tracking-id", | ||||
| 				"PublicKey":   "test-public-key", | ||||
| 				"CustodialId": "test-custodial-id", | ||||
| 				"Status":      "PENDING", | ||||
| 				"Gender":      "Not provided", | ||||
| 				"YOB":         "Not provided", | ||||
| 				"Location":    "Not provided", | ||||
| 				"Offerings":   "Not provided", | ||||
| 				"FirstName":   "Not provided", | ||||
| 				"FamilyName":  "Not provided", | ||||
| 			}, | ||||
| 			expectedResult: resource.Result{ | ||||
| 				FlagSet: []uint32{models.USERFLAG_ACCOUNT_CREATED}, | ||||
| 			}, | ||||
| 			expectedData: map[string]string{ | ||||
| 				"TrackingId":  "test-tracking-id", | ||||
| 				"PublicKey":   "test-public-key", | ||||
| 				"CustodialId": "test-custodial-id", | ||||
| 				"Status":      "PENDING", | ||||
| 				"Gender":      "Not provided", | ||||
| 				"YOB":         "Not provided", | ||||
| 				"Location":    "Not provided", | ||||
| 				"Offerings":   "Not provided", | ||||
| 				"FirstName":   "Not provided", | ||||
| 				"FamilyName":  "Not provided", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			// Set up the data file path using the session ID
 | ||||
| 			accountFilePath := filepath.Join(tempDir, sessionID+"_data") | ||||
| 
 | ||||
| 			// Setup existing data if any
 | ||||
| 			if tt.existingData != nil { | ||||
| 				data, _ := json.Marshal(tt.existingData) | ||||
| 				err := os.WriteFile(accountFilePath, data, 0644) | ||||
| 				if err != nil { | ||||
| 					t.Fatalf("Failed to write existing data: %v", err) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// Call the function
 | ||||
| 			result, err := h.CreateAccount(context.Background(), "", nil) | ||||
| 
 | ||||
| 			// Check for errors
 | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("CreateAccount returned an error: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			// Check the result
 | ||||
| 			if len(result.FlagSet) != len(tt.expectedResult.FlagSet) { | ||||
| 				t.Errorf("Expected %d flags, got %d", len(tt.expectedResult.FlagSet), len(result.FlagSet)) | ||||
| 			} | ||||
| 			for i, flag := range tt.expectedResult.FlagSet { | ||||
| 				if result.FlagSet[i] != flag { | ||||
| 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i]) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			// Check the stored data
 | ||||
| 			data, err := os.ReadFile(accountFilePath) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("Failed to read account data file: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			var storedData map[string]string | ||||
| 			err = json.Unmarshal(data, &storedData) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("Failed to unmarshal stored data: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			for key, expectedValue := range tt.expectedData { | ||||
| 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue { | ||||
| 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue) | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestSavePin(t *testing.T) { | ||||
| 	// Setup
 | ||||
| 	tempDir, err := os.MkdirTemp("", "test_save_pin") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Failed to create temp directory: %v", err) | ||||
| 	} | ||||
| 	defer os.RemoveAll(tempDir) | ||||
| 
 | ||||
| 	sessionID := "07xxxxxxxx" | ||||
| 
 | ||||
| 	// Set up the data file path using the session ID
 | ||||
| 	accountFilePath := filepath.Join(tempDir, sessionID+"_data") | ||||
| 	initialAccountData := map[string]string{ | ||||
| 		"TrackingId": "test-tracking-id", | ||||
| 		"PublicKey":  "test-public-key", | ||||
| 	} | ||||
| 	data, _ := json.Marshal(initialAccountData) | ||||
| 	err = os.WriteFile(accountFilePath, data, 0644) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Failed to write initial account data: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// Create a new AccountFileHandler and set it in the Handlers struct
 | ||||
| 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath) | ||||
| 	h := &Handlers{ | ||||
| 		accountFileHandler: accountFileHandler, | ||||
| 	} | ||||
| 
 | ||||
| 	tests := []struct { | ||||
| 		name           string | ||||
| 		input          []byte | ||||
| 		expectedFlags  []uint32 | ||||
| 		expectedData   map[string]string | ||||
| 		expectedErrors bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:          "Valid PIN", | ||||
| 			input:         []byte("1234"), | ||||
| 			expectedFlags: []uint32{}, | ||||
| 			expectedData: map[string]string{ | ||||
| 				"TrackingId": "test-tracking-id", | ||||
| 				"PublicKey":  "test-public-key", | ||||
| 				"AccountPIN": "1234", | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:           "Invalid PIN - non-numeric", | ||||
| 			input:          []byte("12ab"), | ||||
| 			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN}, | ||||
| 			expectedData:   initialAccountData, // No changes expected
 | ||||
| 			expectedErrors: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:           "Invalid PIN - less than 4 digits", | ||||
| 			input:          []byte("123"), | ||||
| 			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN}, | ||||
| 			expectedData:   initialAccountData, // No changes expected
 | ||||
| 			expectedErrors: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:           "Invalid PIN - more than 4 digits", | ||||
| 			input:          []byte("12345"), | ||||
| 			expectedFlags:  []uint32{models.USERFLAG_INCORRECTPIN}, | ||||
| 			expectedData:   initialAccountData, // No changes expected
 | ||||
| 			expectedErrors: false, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			// Ensure the file exists before running the test
 | ||||
| 			err := accountFileHandler.EnsureFileExists() | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("Failed to ensure account file exists: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			result, err := h.SavePin(context.Background(), "", tt.input) | ||||
| 			if err != nil && !tt.expectedErrors { | ||||
| 				t.Fatalf("SavePin returned an unexpected error: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			if len(result.FlagSet) != len(tt.expectedFlags) { | ||||
| 				t.Errorf("Expected %d flags, got %d", len(tt.expectedFlags), len(result.FlagSet)) | ||||
| 			} | ||||
| 			for i, flag := range tt.expectedFlags { | ||||
| 				if result.FlagSet[i] != flag { | ||||
| 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i]) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			data, err := os.ReadFile(accountFilePath) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("Failed to read account data file: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			var storedData map[string]string | ||||
| 			err = json.Unmarshal(data, &storedData) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("Failed to unmarshal stored data: %v", err) | ||||
| 			} | ||||
| 
 | ||||
| 			for key, expectedValue := range tt.expectedData { | ||||
| 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue { | ||||
| 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue) | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user