Skip to content

Commit 9edd18b

Browse files
authored
[FullTextPolicy]: Adds tests for full text policy multi-language support. (#5515)
# Pull Request Template ## Description This PR contains end to end test and unit test supporting different language usage for defining FullTextPolicy during container creation. ## Type of change Please delete options that are not relevant. - [X] New feature (non-breaking change which adds functionality) ## Closing issues To automatically close an issue: closes #IssueNumber
1 parent 2c73160 commit 9edd18b

3 files changed

Lines changed: 245 additions & 4 deletions

File tree

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//------------------------------------------------------------
44

55
namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests
6-
{
6+
{
77
using Microsoft.VisualStudio.TestTools.UnitTesting;
88
using Newtonsoft.Json.Linq;
99
using System;
@@ -1304,8 +1304,104 @@ public async Task WithClientEncryptionPolicyFailureTest()
13041304
{
13051305
Assert.IsTrue(ex.Message.Contains("Only Deterministic encryption type is supported for path: /id."), ex.Message);
13061306
}
1307-
}
1308-
1307+
}
1308+
1309+
[Ignore("Marking as ignore until emulator is updated")]
1310+
[TestMethod]
1311+
[DataRow("en-US")]
1312+
[DataRow("fr-FR")]
1313+
[DataRow("de-DE")]
1314+
[DataRow("it-IT")]
1315+
[DataRow("pt-BR")]
1316+
[DataRow("pt-PT")]
1317+
[DataRow("es-ES")]
1318+
public async Task TestFullTextSearchPolicyWithAllSupportedDefaultLanguages(string defaultLanguage)
1319+
{
1320+
string fullTextPath1 = "/fts1", fullTextPath2 = "/fts2";
1321+
string endpoint = "";
1322+
string key = "";
1323+
1324+
string databaseName = "TestDatabaseFullTextPolicy";
1325+
string containerName = "TestContainerFullTextPolicy_"+ defaultLanguage;
1326+
1327+
CosmosClientOptions clientOptions = new CosmosClientOptions
1328+
{
1329+
ConnectionMode = ConnectionMode.Direct,
1330+
};
1331+
CosmosClient client = new(endpoint, key, clientOptions);
1332+
1333+
Database databaseForFullTextSearch = await client.CreateDatabaseIfNotExistsAsync(databaseName);
1334+
try
1335+
{
1336+
string partitionKeyPath = "/pk";
1337+
1338+
Collection<FullTextPath> fullTextPaths = new Collection<FullTextPath>()
1339+
{
1340+
new FullTextPath()
1341+
{
1342+
Path = fullTextPath1,
1343+
Language = defaultLanguage,
1344+
},
1345+
new FullTextPath()
1346+
{
1347+
Path = fullTextPath2,
1348+
Language = defaultLanguage,
1349+
}
1350+
};
1351+
1352+
ContainerResponse containerResponse =
1353+
await databaseForFullTextSearch.DefineContainer(containerName, partitionKeyPath)
1354+
.WithFullTextPolicy(
1355+
defaultLanguage: defaultLanguage,
1356+
fullTextPaths: fullTextPaths)
1357+
.Attach()
1358+
.WithIndexingPolicy()
1359+
.WithFullTextIndex()
1360+
.Path(fullTextPath1)
1361+
.Attach()
1362+
.WithFullTextIndex()
1363+
.Path(fullTextPath2)
1364+
.Attach()
1365+
.Attach()
1366+
.CreateAsync();
1367+
1368+
Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode,
1369+
$"Failed to create container with default language: {defaultLanguage}");
1370+
Assert.AreEqual(containerName, containerResponse.Resource.Id);
1371+
Assert.AreEqual(partitionKeyPath, containerResponse.Resource.PartitionKey.Paths.First());
1372+
1373+
ContainerProperties containerSettings = containerResponse.Resource;
1374+
1375+
// Validate FullText Policy
1376+
Assert.IsNotNull(containerSettings.FullTextPolicy,
1377+
$"FullTextPolicy is null for language: {defaultLanguage}");
1378+
Assert.AreEqual(defaultLanguage, containerSettings.FullTextPolicy.DefaultLanguage,
1379+
$"DefaultLanguage mismatch for: {defaultLanguage}");
1380+
Assert.IsNotNull(containerSettings.FullTextPolicy.FullTextPaths);
1381+
Assert.AreEqual(fullTextPaths.Count, containerSettings.FullTextPolicy.FullTextPaths.Count());
1382+
1383+
// Validate each path has the correct language
1384+
foreach (FullTextPath path in containerSettings.FullTextPolicy.FullTextPaths)
1385+
{
1386+
Assert.AreEqual(defaultLanguage, path.Language,
1387+
$"Path language mismatch for default language: {defaultLanguage}");
1388+
}
1389+
1390+
// Validate Full Text Indexes
1391+
Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes);
1392+
Assert.AreEqual(fullTextPaths.Count, containerSettings.IndexingPolicy.FullTextIndexes.Count());
1393+
Assert.AreEqual(fullTextPath1, containerSettings.IndexingPolicy.FullTextIndexes[0].Path);
1394+
Assert.AreEqual(fullTextPath2, containerSettings.IndexingPolicy.FullTextIndexes[1].Path);
1395+
1396+
// Clean up container after test
1397+
await containerResponse.Container.DeleteContainerAsync();
1398+
}
1399+
finally
1400+
{
1401+
await databaseForFullTextSearch.DeleteAsync();
1402+
}
1403+
}
1404+
13091405
private bool VerifyClientEncryptionIncludedPath(ClientEncryptionIncludedPath expected, ClientEncryptionIncludedPath actual)
13101406
{
13111407
return expected.Path == actual.Path &&

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Fluent/ContainerDefinitionForCreateTests.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,85 @@ public async Task ValidateVectorEmbeddingsAndIndexingPolicyUsingContainerBuilder
574574
It.IsAny<RequestOptions>(),
575575
It.IsAny<CancellationToken>()), Times.Once);
576576
}
577+
578+
[TestMethod]
579+
[DataRow("en-US")]
580+
[DataRow("fr-FR")]
581+
[DataRow("de-DE")]
582+
[DataRow("it-IT")]
583+
[DataRow("pt-BR")]
584+
[DataRow("pt-PT")]
585+
[DataRow("es-ES")]
586+
public async Task ValidateFullTextPolicyWithAllSupportedLanguages(string language)
587+
{
588+
string fullTextPath1 = "/fts1", fullTextPath2 = "/fts2";
589+
590+
Collection<FullTextPath> fullTextPaths = new Collection<FullTextPath>()
591+
{
592+
new Cosmos.FullTextPath()
593+
{
594+
Path = fullTextPath1,
595+
Language = language,
596+
},
597+
new Cosmos.FullTextPath()
598+
{
599+
Path = fullTextPath2,
600+
Language = language,
601+
}
602+
};
603+
604+
Mock<ContainerResponse> mockContainerResponse = new Mock<ContainerResponse>();
605+
mockContainerResponse
606+
.Setup(x => x.StatusCode)
607+
.Returns(HttpStatusCode.Created);
608+
609+
Mock<Database> mockDatabase = new Mock<Database>();
610+
Mock<CosmosClient> mockClient = new Mock<CosmosClient>();
611+
mockDatabase.Setup(m => m.Client).Returns(mockClient.Object);
612+
mockDatabase
613+
.Setup(c => c.CreateContainerAsync(
614+
It.IsAny<ContainerProperties>(),
615+
It.IsAny<int?>(),
616+
It.IsAny<RequestOptions>(),
617+
It.IsAny<CancellationToken>()))
618+
.ReturnsAsync(mockContainerResponse.Object);
619+
mockDatabase
620+
.Setup(c => c.Id)
621+
.Returns(Guid.NewGuid().ToString());
622+
623+
ContainerBuilder containerFluentDefinition = new ContainerBuilder(
624+
mockDatabase.Object,
625+
containerName,
626+
partitionKey);
627+
628+
ContainerResponse response = await containerFluentDefinition
629+
.WithFullTextPolicy(
630+
defaultLanguage: language,
631+
fullTextPaths: fullTextPaths)
632+
.Attach()
633+
.WithIndexingPolicy()
634+
.WithFullTextIndex()
635+
.Path(fullTextPath1)
636+
.Attach()
637+
.WithFullTextIndex()
638+
.Path(fullTextPath2)
639+
.Attach()
640+
.Attach()
641+
.CreateAsync();
642+
643+
Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
644+
645+
// Verify the correct language was passed
646+
mockDatabase.Verify(c => c.CreateContainerAsync(
647+
It.Is<ContainerProperties>((settings) =>
648+
settings.FullTextPolicy.DefaultLanguage == language &&
649+
settings.FullTextPolicy.FullTextPaths.Count == 2 &&
650+
settings.FullTextPolicy.FullTextPaths.All(p => p.Language == language)),
651+
It.IsAny<int?>(),
652+
It.IsAny<RequestOptions>(),
653+
It.IsAny<CancellationToken>()), Times.Once,
654+
$"Failed to verify container creation with language: {language}");
655+
}
577656

578657
private static CosmosClientContext GetContext()
579658
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ namespace Microsoft.Azure.Cosmos.Tests
1818
using Microsoft.VisualStudio.TestTools.UnitTesting;
1919
using Newtonsoft.Json;
2020
using Newtonsoft.Json.Linq;
21-
using FullTextPath = Microsoft.Azure.Cosmos.FullTextPath;
21+
using FullTextPath = Microsoft.Azure.Cosmos.FullTextPath;
22+
using FullTextPolicy = Microsoft.Azure.Cosmos.FullTextPolicy;
2223

2324
[TestClass]
2425
public class SettingsContractTests
@@ -1203,6 +1204,71 @@ public void FullTextPolicySerialization()
12031204
Assert.AreEqual(JTokenType.String, fullTextLanguageDeSerialized.Type, "Full Text Policy serialized language should be a string.");
12041205
Assert.IsTrue(fullTextPath1.Equals(fullTextPathsDeSerialized.Value<JArray>()[0].ToObject<Cosmos.FullTextPath>()));
12051206
Assert.IsTrue(fullTextPath2.Equals(fullTextPathsDeSerialized.Value<JArray>()[1].ToObject<Cosmos.FullTextPath>()));
1207+
}
1208+
1209+
[TestMethod]
1210+
[DataRow("en-US")]
1211+
[DataRow("fr-FR")]
1212+
[DataRow("de-DE")]
1213+
[DataRow("it-IT")]
1214+
[DataRow("pt-BR")]
1215+
[DataRow("pt-PT")]
1216+
[DataRow("es-ES")]
1217+
public void FullTextPolicySerializationWithAllSupportedLanguages(string language)
1218+
{
1219+
FullTextPolicy fullTextPolicy = new FullTextPolicy
1220+
{
1221+
DefaultLanguage = language,
1222+
FullTextPaths = new Collection<FullTextPath>
1223+
{
1224+
new FullTextPath { Path = "/text1", Language = language },
1225+
new FullTextPath { Path = "/text2", Language = "en-US" },
1226+
new FullTextPath { Path = "/text3" } // No language specified, should use default
1227+
}
1228+
};
1229+
1230+
string serialized = CosmosSerialize(fullTextPolicy);
1231+
Assert.IsNotNull(serialized);
1232+
Assert.IsTrue(serialized.Contains($"\"defaultLanguage\":\"{language}\""),
1233+
$"Serialized JSON should contain defaultLanguage: {language}");
1234+
1235+
FullTextPolicy deserialized = CosmosDeserialize<FullTextPolicy>(serialized);
1236+
Assert.IsNotNull(deserialized);
1237+
Assert.AreEqual(language, deserialized.DefaultLanguage,
1238+
$"DefaultLanguage mismatch after deserialization for: {language}");
1239+
Assert.AreEqual(3, deserialized.FullTextPaths.Count);
1240+
Assert.AreEqual(language, deserialized.FullTextPaths[0].Language);
1241+
Assert.AreEqual("en-US", deserialized.FullTextPaths[1].Language);
1242+
Assert.IsNull(deserialized.FullTextPaths[2].Language);
1243+
}
1244+
1245+
[TestMethod]
1246+
[DataRow("en-US")]
1247+
[DataRow("fr-FR")]
1248+
[DataRow("de-DE")]
1249+
[DataRow("it-IT")]
1250+
[DataRow("ja-JP")]
1251+
[DataRow("pt-BR")]
1252+
[DataRow("pt-PT")]
1253+
[DataRow("es-ES")]
1254+
public void FullTextPathSerializationWithAllLanguages(string language)
1255+
{
1256+
FullTextPath fullTextPath = new FullTextPath
1257+
{
1258+
Path = "/testPath",
1259+
Language = language
1260+
};
1261+
1262+
string serialized = CosmosSerialize(fullTextPath);
1263+
Assert.IsNotNull(serialized);
1264+
Assert.IsTrue(serialized.Contains($"\"language\":\"{language}\""),
1265+
$"Serialized JSON should contain language: {language}");
1266+
1267+
FullTextPath deserialized = CosmosDeserialize<FullTextPath>(serialized);
1268+
Assert.IsNotNull(deserialized);
1269+
Assert.AreEqual("/testPath", deserialized.Path);
1270+
Assert.AreEqual(language, deserialized.Language,
1271+
$"Language mismatch after deserialization for: {language}");
12061272
}
12071273

12081274
private static T CosmosDeserialize<T>(string payload)

0 commit comments

Comments
 (0)