package mongo import ( "context" "testing" "time" "github.com/shopspring/decimal" "github.com/zeromicro/go-zero/core/stores/cache" "go.mongodb.org/mongo-driver/v2/bson" ) func TestDocumentDBWithCache_MustDocumentDBWithCache(t *testing.T) { // Test with valid config conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} // This will panic if MongoDB is not available, so we need to handle it defer func() { if r := recover(); r != nil { t.Logf("Expected panic in test environment: %v", r) } }() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Logf("MongoDB connection failed (expected in test environment): %v", err) return } if db == nil { t.Error("Expected DocumentDBWithCache to be non-nil") } } func TestDocumentDBWithCache_CacheOperations(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} ctx := context.Background() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Skip("Skipping test - MongoDB not available") return } // Test cache operations key := "test-key" value := "test-value" // Test SetCache err = db.SetCache(key, value) if err != nil { t.Errorf("Failed to set cache: %v", err) } // Test GetCache var cachedValue string err = db.GetCache(key, &cachedValue) if err != nil { t.Errorf("Failed to get cache: %v", err) } if cachedValue != value { t.Errorf("Expected cached value %s, got %s", value, cachedValue) } // Test DelCache err = db.DelCache(ctx, key) if err != nil { t.Errorf("Failed to delete cache: %v", err) } } func TestDocumentDBWithCache_CRUDOperations(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} ctx := context.Background() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Skip("Skipping test - MongoDB not available") return } // Test data testDoc := bson.M{ "name": "test", "value": 123, "price": decimal.NewFromFloat(99.99), } // Test InsertOne result, err := db.InsertOne(ctx, collection, testDoc) if err != nil { t.Errorf("Failed to insert document: %v", err) } insertedID := result.InsertedID if insertedID == nil { t.Error("Expected inserted ID to be non-nil") } // Test FindOne var foundDoc bson.M err = db.FindOne(ctx, collection, bson.M{"_id": insertedID}, &foundDoc) if err != nil { t.Errorf("Failed to find document: %v", err) } if foundDoc["name"] != "test" { t.Errorf("Expected name 'test', got %v", foundDoc["name"]) } // Test UpdateOne update := bson.M{"$set": bson.M{"value": 456}} updateResult, err := db.UpdateOne(ctx, collection, bson.M{"_id": insertedID}, update) if err != nil { t.Errorf("Failed to update document: %v", err) } if updateResult.ModifiedCount != 1 { t.Errorf("Expected 1 modified document, got %d", updateResult.ModifiedCount) } // Test UpdateByID updateByID := bson.M{"$set": bson.M{"value": 789}} updateByIDResult, err := db.UpdateByID(ctx, collection, insertedID, updateByID) if err != nil { t.Errorf("Failed to update document by ID: %v", err) } if updateByIDResult.ModifiedCount != 1 { t.Errorf("Expected 1 modified document, got %d", updateByIDResult.ModifiedCount) } // Test UpdateMany updateMany := bson.M{"$set": bson.M{"updated": true}} updateManyResult, err := db.UpdateMany(ctx, []string{collection}, bson.M{"_id": insertedID}, updateMany) if err != nil { t.Errorf("Failed to update many documents: %v", err) } if updateManyResult.ModifiedCount != 1 { t.Errorf("Expected 1 modified document, got %d", updateManyResult.ModifiedCount) } // Test FindOneAndReplace replacement := bson.M{ "name": "replaced", "value": 999, "price": decimal.NewFromFloat(199.99), } var replacedDoc bson.M err = db.FindOneAndReplace(ctx, collection, bson.M{"_id": insertedID}, replacement, &replacedDoc) if err != nil { t.Errorf("Failed to find and replace document: %v", err) } // Test FindOneAndDelete var deletedDoc bson.M err = db.FindOneAndDelete(ctx, collection, bson.M{"_id": insertedID}, &deletedDoc) if err != nil { t.Errorf("Failed to find and delete document: %v", err) } // Test DeleteOne deleteResult, err := db.DeleteOne(ctx, collection, bson.M{"_id": insertedID}) if err != nil { t.Errorf("Failed to delete document: %v", err) } if deleteResult != 0 { // Should be 0 since we already deleted it t.Errorf("Expected 0 deleted documents, got %d", deleteResult) } } func TestDocumentDBWithCache_MustModelCache(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Skip("Skipping test - MongoDB not available") return } // Test that we got a valid DocumentDBWithCache if db == nil { t.Error("Expected DocumentDBWithCache to be non-nil") } } func TestDocumentDBWithCache_ErrorHandling(t *testing.T) { // Test with invalid config invalidConf := &Conf{ Host: "invalid-host:99999", } collection := "testcollection" cacheConf := cache.CacheConf{} _, err := MustDocumentDBWithCache(invalidConf, collection, cacheConf, nil, nil) // This should fail if err == nil { t.Error("Expected error with invalid host, got nil") } } func TestDocumentDBWithCache_ContextHandling(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} // Test with timeout context ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) // Use ctx to avoid unused variable warning _ = ctx if err != nil { t.Logf("MongoDB connection failed (expected in test environment): %v", err) return } if db == nil { t.Error("Expected DocumentDBWithCache to be non-nil") } } func TestDocumentDBWithCache_WithDecimalValues(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} ctx := context.Background() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Skip("Skipping test - MongoDB not available") return } // Test with decimal values testDoc := bson.M{ "name": "decimal-test", "price": decimal.NewFromFloat(123.45), "amount": decimal.NewFromFloat(999.99), } // Insert document with decimal values result, err := db.InsertOne(ctx, collection, testDoc) if err != nil { t.Errorf("Failed to insert document with decimal values: %v", err) } insertedID := result.InsertedID // Find document with decimal values var foundDoc bson.M err = db.FindOne(ctx, collection, bson.M{"_id": insertedID}, &foundDoc) if err != nil { t.Errorf("Failed to find document with decimal values: %v", err) } // Verify decimal values if foundDoc["name"] != "decimal-test" { t.Errorf("Expected name 'decimal-test', got %v", foundDoc["name"]) } // Clean up _, err = db.DeleteOne(ctx, collection, bson.M{"_id": insertedID}) if err != nil { t.Errorf("Failed to clean up document: %v", err) } } func TestDocumentDBWithCache_WithObjectID(t *testing.T) { conf := &Conf{ Host: "localhost:27017", Database: "testdb", } collection := "testcollection" cacheConf := cache.CacheConf{} ctx := context.Background() db, err := MustDocumentDBWithCache(conf, collection, cacheConf, nil, nil) if err != nil { t.Skip("Skipping test - MongoDB not available") return } // Test with ObjectID objectID := bson.NewObjectID() testDoc := bson.M{ "_id": objectID, "name": "objectid-test", "value": 123, } // Insert document with ObjectID result, err := db.InsertOne(ctx, collection, testDoc) if err != nil { t.Errorf("Failed to insert document with ObjectID: %v", err) } insertedID := result.InsertedID // Verify ObjectID if insertedID != objectID { t.Errorf("Expected ObjectID %v, got %v", objectID, insertedID) } // Find document by ObjectID var foundDoc bson.M err = db.FindOne(ctx, collection, bson.M{"_id": objectID}, &foundDoc) if err != nil { t.Errorf("Failed to find document by ObjectID: %v", err) } // Clean up _, err = db.DeleteOne(ctx, collection, bson.M{"_id": objectID}) if err != nil { t.Errorf("Failed to clean up document: %v", err) } }