solidarity-transport/storage/mock.go

279 lines
7.0 KiB
Go

package storage
import (
"fmt"
"strings"
"sync"
"git.coopgo.io/coopgo-platform/solidarity-transport/types"
"github.com/google/uuid"
"github.com/spf13/viper"
)
// MockStorage implements the Storage interface for testing purposes
type MockStorage struct {
config *viper.Viper
mu sync.RWMutex
availabilities map[string]*types.DriverRegularAvailability
journeys map[string]*types.DriverJourney
bookings map[string]*types.Booking
availabilitiesByDriver map[string][]*types.DriverRegularAvailability
}
// NewMockStorage creates a new mock storage instance
func NewMockStorage(cfg *viper.Viper) Storage {
return &MockStorage{
config: cfg,
availabilities: make(map[string]*types.DriverRegularAvailability),
journeys: make(map[string]*types.DriverJourney),
bookings: make(map[string]*types.Booking),
availabilitiesByDriver: make(map[string][]*types.DriverRegularAvailability),
}
}
// Driver Regular Availability methods
func (m *MockStorage) CreateDriverRegularAvailability(availability types.DriverRegularAvailability) error {
m.mu.Lock()
defer m.mu.Unlock()
if availability.ID == "" {
availability.ID = uuid.New().String()
}
m.availabilities[availability.ID] = &availability
// Update driver index
m.availabilitiesByDriver[availability.DriverId] = append(
m.availabilitiesByDriver[availability.DriverId],
&availability,
)
return nil
}
func (m *MockStorage) CreateDriverRegularAvailabilities(availabilities []*types.DriverRegularAvailability) error {
for _, availability := range availabilities {
if err := m.CreateDriverRegularAvailability(*availability); err != nil {
return err
}
}
return nil
}
func (m *MockStorage) DeleteDriverRegularAvailability(driverid string, availabilityid string) error {
m.mu.Lock()
defer m.mu.Unlock()
availability, exists := m.availabilities[availabilityid]
if !exists {
return fmt.Errorf("availability %s not found", availabilityid)
}
if availability.DriverId != driverid {
return fmt.Errorf("availability %s does not belong to driver %s", availabilityid, driverid)
}
delete(m.availabilities, availabilityid)
// Update driver index
driverAvailabilities := m.availabilitiesByDriver[driverid]
for i, a := range driverAvailabilities {
if a.ID == availabilityid {
m.availabilitiesByDriver[driverid] = append(driverAvailabilities[:i], driverAvailabilities[i+1:]...)
break
}
}
return nil
}
func (m *MockStorage) GetDriverRegularAvailability(driverid string, availabilityid string) (*types.DriverRegularAvailability, error) {
m.mu.RLock()
defer m.mu.RUnlock()
availability, exists := m.availabilities[availabilityid]
if !exists {
return nil, fmt.Errorf("availability %s not found", availabilityid)
}
if availability.DriverId != driverid {
return nil, fmt.Errorf("availability %s does not belong to driver %s", availabilityid, driverid)
}
return availability, nil
}
func (m *MockStorage) GetDriverRegularAvailabilities(driverid string) ([]*types.DriverRegularAvailability, error) {
m.mu.RLock()
defer m.mu.RUnlock()
return m.availabilitiesByDriver[driverid], nil
}
func (m *MockStorage) GetRegularAvailabilities(day int, timeInDay string) ([]*types.DriverRegularAvailability, error) {
m.mu.RLock()
defer m.mu.RUnlock()
var result []*types.DriverRegularAvailability
for _, availability := range m.availabilities {
// Match day
if availability.Day != day {
continue
}
// For testing, just return all availabilities for the day
// Let the handler do the time filtering logic
result = append(result, availability)
}
return result, nil
}
// timeMatches is a simple time matching function for testing
func (m *MockStorage) timeMatches(availabilityTime, requestedTime string) bool {
// Simple string matching for testing - real implementation would parse times
return strings.HasPrefix(availabilityTime, requestedTime[:2]) // Match hour
}
// Driver Journey methods
func (m *MockStorage) PushDriverJourneys(journeys []*types.DriverJourney) error {
m.mu.Lock()
defer m.mu.Unlock()
for _, journey := range journeys {
if journey.Id == "" {
journey.Id = uuid.New().String()
}
m.journeys[journey.Id] = journey
}
return nil
}
func (m *MockStorage) GetDriverJourney(id string) (*types.DriverJourney, error) {
m.mu.RLock()
defer m.mu.RUnlock()
journey, exists := m.journeys[id]
if !exists {
return nil, fmt.Errorf("journey %s not found", id)
}
return journey, nil
}
func (m *MockStorage) UpdateDriverJourney(journey types.DriverJourney) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.journeys[journey.Id]; !exists {
return fmt.Errorf("journey %s not found", journey.Id)
}
m.journeys[journey.Id] = &journey
return nil
}
// Booking methods
func (m *MockStorage) CreateBooking(booking types.Booking) error {
m.mu.Lock()
defer m.mu.Unlock()
if booking.Id == "" {
booking.Id = uuid.New().String()
}
m.bookings[booking.Id] = &booking
return nil
}
func (m *MockStorage) GetAllBookings() ([]*types.Booking, error) {
m.mu.RLock()
defer m.mu.RUnlock()
var result []*types.Booking
for _, booking := range m.bookings {
result = append(result, booking)
}
return result, nil
}
func (m *MockStorage) GetBooking(id string) (*types.Booking, error) {
m.mu.RLock()
defer m.mu.RUnlock()
booking, exists := m.bookings[id]
if !exists {
return nil, fmt.Errorf("booking %s not found", id)
}
return booking, nil
}
func (m *MockStorage) UpdateBooking(booking types.Booking) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.bookings[booking.Id]; !exists {
return fmt.Errorf("booking %s not found", booking.Id)
}
m.bookings[booking.Id] = &booking
return nil
}
func (m *MockStorage) UpdateBookingStatus(bookingid string, newStatus string, reason string) error {
m.mu.Lock()
defer m.mu.Unlock()
booking, exists := m.bookings[bookingid]
if !exists {
return fmt.Errorf("booking %s not found", bookingid)
}
booking.Status = newStatus
// In a real implementation, we might store the reason in a separate field
return nil
}
// Helper methods for testing
// Reset clears all data - useful for test setup
func (m *MockStorage) Reset() {
m.mu.Lock()
defer m.mu.Unlock()
m.availabilities = make(map[string]*types.DriverRegularAvailability)
m.journeys = make(map[string]*types.DriverJourney)
m.bookings = make(map[string]*types.Booking)
m.availabilitiesByDriver = make(map[string][]*types.DriverRegularAvailability)
}
// GetAllJourneys returns all stored journeys - useful for testing
func (m *MockStorage) GetAllJourneys() []*types.DriverJourney {
m.mu.RLock()
defer m.mu.RUnlock()
var result []*types.DriverJourney
for _, journey := range m.journeys {
result = append(result, journey)
}
return result
}
// GetAllAvailabilities returns all stored availabilities - useful for testing
func (m *MockStorage) GetAllAvailabilities() []*types.DriverRegularAvailability {
m.mu.RLock()
defer m.mu.RUnlock()
var result []*types.DriverRegularAvailability
for _, availability := range m.availabilities {
result = append(result, availability)
}
return result
}