Add ready question production promotion
This commit is contained in:
@@ -31,4 +31,129 @@ public sealed class ContentPromotionTests
|
||||
ContentPromotionCommand.HashDocuments([first, second]),
|
||||
ContentPromotionCommand.HashDocuments([second, first]));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadyQuestionEligibilityRequiresPublishedAndUnflagged()
|
||||
{
|
||||
Assert.True(QuestionPromotionCommand.IsEligible(new BsonDocument
|
||||
{
|
||||
["IsPublished"] = true,
|
||||
["FlaggedForReviewUtc"] = BsonNull.Value
|
||||
}));
|
||||
Assert.True(QuestionPromotionCommand.IsEligible(new BsonDocument("IsPublished", true)));
|
||||
Assert.False(QuestionPromotionCommand.IsEligible(new BsonDocument
|
||||
{
|
||||
["IsPublished"] = true,
|
||||
["FlaggedForReviewUtc"] = DateTime.UtcNow
|
||||
}));
|
||||
Assert.False(QuestionPromotionCommand.IsEligible(new BsonDocument("IsPublished", false)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QuestionMediaIdsSupportStoredApiUrlsAndRawIds()
|
||||
{
|
||||
var first = ObjectId.GenerateNewId();
|
||||
var second = ObjectId.GenerateNewId();
|
||||
var questions = new[]
|
||||
{
|
||||
new BsonDocument
|
||||
{
|
||||
["ExternalId"] = "one",
|
||||
["Media"] = new BsonArray { $"/api/questions/media/{first}", second.ToString() }
|
||||
},
|
||||
new BsonDocument
|
||||
{
|
||||
["ExternalId"] = "two",
|
||||
["Media"] = new BsonArray { $"https://example.test/api/questions/media/{first}" }
|
||||
}
|
||||
};
|
||||
|
||||
var result = QuestionPromotionCommand.CollectMediaIds(questions);
|
||||
|
||||
Assert.Equal(new HashSet<ObjectId> { first, second }, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidLocalQuestionMediaReferenceFailsValidation()
|
||||
{
|
||||
var question = new BsonDocument
|
||||
{
|
||||
["ExternalId"] = "bad-media",
|
||||
["Media"] = new BsonArray { "/api/questions/media/not-an-id" }
|
||||
};
|
||||
|
||||
var exception = Assert.Throws<InvalidOperationException>(
|
||||
() => QuestionPromotionCommand.CollectMediaIds([question]));
|
||||
|
||||
Assert.Contains("bad-media", exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QuestionComparisonClassifiesInsertUpdateAndUnchanged()
|
||||
{
|
||||
var source = new[]
|
||||
{
|
||||
Question("insert", "new"),
|
||||
Question("update", "new"),
|
||||
Question("same", "same")
|
||||
};
|
||||
var target = new[]
|
||||
{
|
||||
Question("update", "old"),
|
||||
new BsonDocument
|
||||
{
|
||||
["Stem"] = "same",
|
||||
["ExternalId"] = "same",
|
||||
["_id"] = ObjectId.GenerateNewId()
|
||||
}
|
||||
};
|
||||
|
||||
var result = QuestionPromotionCommand.ClassifyQuestions(source, target);
|
||||
|
||||
Assert.Equal(1, result.Inserted);
|
||||
Assert.Equal(1, result.Updated);
|
||||
Assert.Equal(1, result.Unchanged);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QuestionHashIgnoresMongoIdsFieldOrderAndInputOrder()
|
||||
{
|
||||
var first = Question("a", "one");
|
||||
first["_id"] = ObjectId.GenerateNewId();
|
||||
var second = Question("b", "two");
|
||||
var equivalentFirst = new BsonDocument
|
||||
{
|
||||
["Stem"] = "one",
|
||||
["_id"] = ObjectId.GenerateNewId(),
|
||||
["ExternalId"] = "a"
|
||||
};
|
||||
|
||||
Assert.Equal(
|
||||
QuestionPromotionCommand.HashQuestions([first, second]),
|
||||
QuestionPromotionCommand.HashQuestions([second, equivalentFirst]));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadyQuestionApplyRequiresExplicitProductionConfirmation()
|
||||
{
|
||||
using var output = new StringWriter();
|
||||
|
||||
var result = await QuestionPromotionCommand.RunAsync(
|
||||
[
|
||||
"--source-connection", "mongodb://source.invalid",
|
||||
"--source-database", "uat",
|
||||
"--target-connection", "mongodb://target.invalid",
|
||||
"--target-database", "prd",
|
||||
"--apply"
|
||||
], output);
|
||||
|
||||
Assert.Equal(1, result);
|
||||
Assert.Contains("--confirm PROMOTE_TO_PRD is required", output.ToString());
|
||||
}
|
||||
|
||||
private static BsonDocument Question(string externalId, string stem) => new()
|
||||
{
|
||||
["ExternalId"] = externalId,
|
||||
["Stem"] = stem
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user