public async Task TestGetPartitionKeyValueFromStreamAsync() { ContainerInternal mockContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); ContainerInternal container = containerMock.Object; containerMock.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "pk" } })); containerMock .Setup( x => x.GetPartitionKeyValueFromStreamAsync( It.IsAny <Stream>(), It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns <Stream, ITrace, CancellationToken>( (stream, trace, cancellationToken) => mockContainer.GetPartitionKeyValueFromStreamAsync( stream, trace, cancellationToken)); DateTime dateTime = new DateTime(2019, 05, 15, 12, 1, 2, 3, DateTimeKind.Utc); Guid guid = Guid.NewGuid(); //Test supported types List <dynamic> supportedTypesToTest = new List <dynamic> { new { pk = true }, new { pk = false }, new { pk = byte.MaxValue }, new { pk = sbyte.MaxValue }, new { pk = short.MaxValue }, new { pk = ushort.MaxValue }, new { pk = int.MaxValue }, new { pk = uint.MaxValue }, new { pk = long.MaxValue }, new { pk = ulong.MaxValue }, new { pk = float.MaxValue }, new { pk = double.MaxValue }, new { pk = decimal.MaxValue }, new { pk = char.MaxValue }, new { pk = "test" }, new { pk = dateTime }, new { pk = guid }, }; foreach (dynamic poco in supportedTypesToTest) { object pk = await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken)); if (pk is bool boolValue) { Assert.AreEqual(poco.pk, boolValue); } else if (pk is double doubleValue) { if (poco.pk is float) { Assert.AreEqual(poco.pk, Convert.ToSingle(pk)); } else if (poco.pk is double) { Assert.AreEqual(poco.pk, Convert.ToDouble(pk)); } else if (poco.pk is decimal) { Assert.AreEqual(Convert.ToDouble(poco.pk), (double)pk); } } else if (pk is string stringValue) { if (poco.pk is DateTime) { Assert.AreEqual(poco.pk.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), stringValue); } else { Assert.AreEqual(poco.pk.ToString(), (string)pk); } } } //Unsupported types should throw List <dynamic> unsupportedTypesToTest = new List <dynamic> { new { pk = new { test = "test" } }, new { pk = new int[] { 1, 2, 3 } }, new { pk = new ArraySegment <byte>(new byte[] { 0 }) }, }; foreach (dynamic poco in unsupportedTypesToTest) { await Assert.ThrowsExceptionAsync <ArgumentException>(async() => await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken))); } //null should return null object pkValue = await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(new { pk = (object)null }), NoOpTrace.Singleton, default); Assert.AreEqual(Cosmos.PartitionKey.Null, pkValue); }
public async Task TestNestedPartitionKeyValueFromStreamAsync() { ContainerInternal originalContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerCore> mockedContainer = new Mock <ContainerCore>( originalContainer.ClientContext, (DatabaseInternal)originalContainer.Database, originalContainer.Id, null) { CallBase = true }; mockedContainer.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "a", "b", "c" } })); ContainerInternal containerWithMockPartitionKeyPath = mockedContainer.Object; List <dynamic> invalidNestedItems = new List <dynamic> { new // a/b/d (leaf invalid) { id = Guid.NewGuid().ToString(), a = new { b = new { d = "pk1", } } }, new // a/d/c (middle invalid) { id = Guid.NewGuid().ToString(), a = new { d = new { c = "pk1", } } }, new // nested/a/b/c (root invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = "pk1", } } } }, new // nested/a/b/c/d (root & tail invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = new { d = "pk1" } } } } } }; foreach (dynamic poco in invalidNestedItems) { object pk = await containerWithMockPartitionKeyPath.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), NoOpTrace.Singleton, default(CancellationToken)); Assert.IsTrue(object.Equals(Cosmos.PartitionKey.None, pk)); } }
public async Task TestMultipleNestedPartitionKeyValueFromStreamAsync() { ContainerInternal originalContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerCore> mockedContainer = new Mock <ContainerCore>( originalContainer.ClientContext, (DatabaseInternal)originalContainer.Database, originalContainer.Id, null) { CallBase = true }; mockedContainer.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <ITrace>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult((IReadOnlyList <IReadOnlyList <string> >) new List <IReadOnlyList <string> > { new List <string> { "a", "b", "c" }, new List <string> { "a", "e", "f" } })); ContainerInternal containerWithMockPartitionKeyPath = mockedContainer.Object; List <dynamic> validNestedItems = new List <dynamic> { ( new // a/b/c (Specify only one partition key) { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, } } }, "[10.0,{}]" ), ( new // { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, }, e = new { f = 15, } } }, "[10.0,15.0]" ), ( new { id = Guid.NewGuid().ToString(), a = new { b = new { c = 10, }, e = new { f = default(string), //null } } }, "[10.0,null]" ), ( new { id = Guid.NewGuid().ToString(), a = new { e = new { f = 10, } } }, "[{},10.0]" ), ( new { id = Guid.NewGuid().ToString(), a = new { e = 10, b = new { k = 10, } } }, "[{},{}]" ) }; foreach (dynamic poco in validNestedItems) { Cosmos.PartitionKey pk = await containerWithMockPartitionKeyPath.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco.Item1), NoOpTrace.Singleton, default(CancellationToken)); string partitionKeyString = pk.InternalKey.ToJsonString(); Assert.AreEqual(poco.Item2, partitionKeyString); } }
public async Task TestNestedPartitionKeyValueFromStreamAsync() { ContainerInternal mockContainer = (ContainerInternal)MockCosmosUtil.CreateMockCosmosClient().GetContainer("TestDb", "Test"); Mock <ContainerInternal> containerMock = new Mock <ContainerInternal>(); ContainerInternal container = containerMock.Object; containerMock.Setup(e => e.GetPartitionKeyPathTokensAsync(It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new string[] { "a", "b", "c" })); containerMock.Setup(x => x.GetPartitionKeyValueFromStreamAsync(It.IsAny <Stream>(), It.IsAny <CancellationToken>())) .Returns <Stream, CancellationToken>((stream, cancellationToken) => mockContainer.GetPartitionKeyValueFromStreamAsync(stream, cancellationToken)); List <dynamic> invalidNestedItems = new List <dynamic> { new // a/b/d (leaf invalid) { id = Guid.NewGuid().ToString(), a = new { b = new { d = "pk1", } } }, new // a/d/c (middle invalid) { id = Guid.NewGuid().ToString(), a = new { d = new { c = "pk1", } } }, new // nested/a/b/c (root invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = "pk1", } } } }, new // nested/a/b/c/d (root & tail invalid) { id = Guid.NewGuid().ToString(), nested = new { a = new { b = new { c = new { d = "pk1" } } } } } }; foreach (dynamic poco in invalidNestedItems) { object pk = await container.GetPartitionKeyValueFromStreamAsync( MockCosmosUtil.Serializer.ToStream(poco), default(CancellationToken)); Assert.IsTrue(object.ReferenceEquals(Cosmos.PartitionKey.None, pk) || object.Equals(Cosmos.PartitionKey.None, pk)); } }