PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/framework/Composable.CQRS.Tests/Persistence/DocumentDb/DocumentDbTests.cs

https://github.com/mlidbom/Composable.Monolithic
C# | 785 lines | 634 code | 149 blank | 2 comment | 0 complexity | 7703f0d648c80c190754bcc771560552 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using Composable.DDD;
  6. using Composable.DependencyInjection;
  7. using Composable.DependencyInjection.Testing;
  8. using Composable.Persistence.DocumentDb;
  9. using Composable.SystemCE.CollectionsCE.GenericCE;
  10. using Composable.SystemCE.LinqCE;
  11. using Composable.SystemCE.ThreadingCE;
  12. using FluentAssertions;
  13. using JetBrains.Annotations;
  14. using NUnit.Framework;
  15. // ReSharper disable AccessToDisposedClosure
  16. namespace Composable.Tests.Persistence.DocumentDb
  17. {
  18. class DocumentDbTests : DocumentDbTestsBase
  19. {
  20. [Test]
  21. public void CanSaveAndLoadDocument()
  22. {
  23. var user = new User
  24. {
  25. Id = Guid.NewGuid(),
  26. Email = "email@email.se",
  27. Password = "password",
  28. Address = new Address
  29. {
  30. City = "MyTown",
  31. Street = "MyStreet",
  32. Streetnumber = 234
  33. }
  34. };
  35. UseInTransactionalScope((reader,updater) => updater.Save(user.Id, user));
  36. UseInScope(reader =>
  37. {
  38. var loadedUser = reader.Get<User>(user.Id);
  39. Assert.That(loadedUser.Id, Is.EqualTo(user.Id));
  40. Assert.That(loadedUser.Email, Is.EqualTo(user.Email));
  41. Assert.That(loadedUser.Password, Is.EqualTo(user.Password));
  42. Assert.That(loadedUser.Address, Is.EqualTo(user.Address));
  43. });
  44. }
  45. [Test]
  46. public void GetAllWithIdsReturnsAsManyResultsAsPassedIds()
  47. {
  48. var ids = 1.Through(9).Select(index => Guid.Parse($"00000000-0000-0000-0000-00000000000{index}")).ToArray();
  49. var users = ids.Select(id => new User { Id = id }).ToArray();
  50. UseInTransactionalScope((reader, updater) => users.ForEach(user => updater.Save(user)));
  51. UseInScope(reader => reader.GetAll<User>(ids.Take(5))
  52. .Select(fetched => fetched.Id)
  53. .Should()
  54. .Equal(ids.Take(5)));
  55. }
  56. [Test] public void GetAllWithIdsThrowsNoSuchDocumentExceptionExceptionIfAnyIdIsMissing()
  57. {
  58. var ids = 1.Through(9)
  59. .Select(index => Guid.Parse($"00000000-0000-0000-0000-00000000000{index}"))
  60. .ToArray();
  61. var users = ids.Select(id => new User {Id = id})
  62. .ToArray();
  63. UseInTransactionalScope((reader,updater) => users.ForEach(user => updater.Save(user)));
  64. UseInScope(reader => Assert.Throws<NoSuchDocumentException>(
  65. () => reader.GetAll<User>(ids.Take(5)
  66. .Append(Guid.Parse("00000000-0000-0000-0000-000000000099"))
  67. .ToArray())
  68. // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
  69. .ToArray()));
  70. }
  71. [Test]
  72. public void GetAllWithIdsReturnsTheSameInstanceForAnyPreviouslyFetchedDocuments()
  73. {
  74. var ids = 1.Through(9).Select(index => Guid.Parse($"00000000-0000-0000-0000-00000000000{index}")).ToArray();
  75. var users = ids.Select(id => new User { Id = id }).ToArray();
  76. UseInTransactionalScope((reader,updater) => users.ForEach(user => updater.Save(user)));
  77. UseInScope(reader =>
  78. {
  79. var fetchedIndividually = ids.Select(id => reader.Get<User>(id))
  80. .ToArray();
  81. var fetchedWithGetAll = reader.GetAll<User>(ids)
  82. .ToArray();
  83. fetchedIndividually.ForEach((user, index) => Assert.That(user, Is.SameAs(fetchedWithGetAll[index])));
  84. });
  85. }
  86. [Test]
  87. public void CanSaveAndLoadAggregateForUpdate()
  88. {
  89. var user = new User
  90. {
  91. Id = Guid.NewGuid(),
  92. Email = "email@email.se",
  93. Password = "password",
  94. Address = new Address
  95. {
  96. City = "MyTown",
  97. Street = "MyStreet",
  98. Streetnumber = 234
  99. }
  100. };
  101. UseInTransactionalScope((reader,updater) => updater.Save(user.Id, user));
  102. UseInTransactionalScope((reader, updater) =>
  103. {
  104. var loadedUser = updater.GetForUpdate<User>(user.Id);
  105. Assert.That(loadedUser.Id, Is.EqualTo(user.Id));
  106. Assert.That(loadedUser.Email, Is.EqualTo(user.Email));
  107. Assert.That(loadedUser.Password, Is.EqualTo(user.Password));
  108. Assert.That(loadedUser.Address, Is.EqualTo(user.Address));
  109. });
  110. }
  111. [Test]
  112. public void CallingSaveWithAnInteraceAsTypeParameterDoesNotExplode()
  113. {
  114. IPersistentEntity<Guid> user1 = new User { Id = Guid.NewGuid(), Email = "user1" };
  115. IPersistentEntity<Guid> user2 = new User { Id = Guid.NewGuid(), Email = "user2" };
  116. UseInTransactionalScope((reader, updater) =>
  117. {
  118. updater.Save(user2);
  119. updater.Save(user1.Id, user1);
  120. reader.Get<User>(user1.Id)
  121. .Should()
  122. .Be(user1);
  123. reader.Get<User>(user2.Id)
  124. .Should()
  125. .Be(user2);
  126. });
  127. UseInScope(reader =>
  128. {
  129. reader.Get<User>(user1.Id)
  130. .Id.Should()
  131. .Be(user1.Id);
  132. reader.Get<User>(user2.Id)
  133. .Id.Should()
  134. .Be(user2.Id);
  135. });
  136. }
  137. [Test]
  138. public void AddingAndRemovingObjectResultsInNoObjectBeingSaved()
  139. {
  140. var user = new User { Id = Guid.NewGuid() };
  141. UseInTransactionalScope((reader,updater) =>
  142. {
  143. updater.Save(user.Id, user);
  144. updater.Delete(user);
  145. });
  146. UseInScope(reader =>
  147. reader.TryGet(user.Id, out user)
  148. .Should()
  149. .BeFalse());
  150. }
  151. [Test]
  152. public void AddingRemovingAndAddingObjectInTransactionResultsInNoObjectBeingSaved()
  153. {
  154. var user = new User { Id = Guid.NewGuid() };
  155. UseInTransactionalScope((reader,updater) =>
  156. {
  157. updater.Save(user.Id, user);
  158. updater.Delete(user);
  159. updater.Save(user.Id, user);
  160. });
  161. UseInScope(reader => reader.TryGet(user.Id, out user).Should().BeTrue());
  162. }
  163. [Test]
  164. public void ObjectsWhoseKeysDifferOnlyByCaseAreConsideredTheSameObjectForCompatibilityWithMsSql()
  165. {
  166. var lowerCase = new Email("theemail");
  167. var upperCase = new Email(lowerCase.TheEmail.ToUpperInvariant());
  168. UseInTransactionalScope((reader, updater) =>
  169. {
  170. updater.Save(lowerCase.TheEmail, lowerCase);
  171. Assert.Throws<AttemptToSaveAlreadyPersistedValueException>(() => updater.Save(upperCase.TheEmail, upperCase));
  172. reader.Get<Email>(lowerCase.TheEmail)
  173. .Should()
  174. .Be(reader.Get<Email>(upperCase.TheEmail));
  175. });
  176. UseInTransactionalScope((reader, updater) =>
  177. {
  178. Assert.Throws<AttemptToSaveAlreadyPersistedValueException>(() => updater.Save(upperCase.TheEmail, upperCase));
  179. reader.Get<Email>(upperCase.TheEmail)
  180. .TheEmail.Should()
  181. .Be(lowerCase.TheEmail);
  182. reader.Get<Email>(lowerCase.TheEmail)
  183. .Should()
  184. .Be(reader.Get<Email>(upperCase.TheEmail));
  185. updater.Delete<Email>(upperCase.TheEmail);
  186. Assert.Throws<NoSuchDocumentException>(() => updater.Delete<Email>(upperCase.TheEmail));
  187. Assert.Throws<NoSuchDocumentException>(() => updater.Delete<Email>(lowerCase.TheEmail));
  188. });
  189. }
  190. [Test]
  191. public void ObjectsWhoseKeysDifferOnlyByTrailingSpacesTrailingWhiteSpaceCaseAreConsideredTheSameObjectForCompatibilityWithMsSql()
  192. {
  193. var noWhitespace = new Email("theemail");
  194. var withWhitespace = new Email(noWhitespace.TheEmail + " ");
  195. UseInTransactionalScope((reader, updater) =>
  196. {
  197. updater.Save(noWhitespace.TheEmail, noWhitespace);
  198. Assert.Throws<AttemptToSaveAlreadyPersistedValueException>(() => updater.Save(withWhitespace.TheEmail, withWhitespace));
  199. reader.Get<Email>(noWhitespace.TheEmail)
  200. .Should()
  201. .Be(reader.Get<Email>(withWhitespace.TheEmail));
  202. });
  203. UseInTransactionalScope((reader, updater) =>
  204. {
  205. Assert.Throws<AttemptToSaveAlreadyPersistedValueException>(() => updater.Save(withWhitespace.TheEmail, withWhitespace));
  206. reader.Get<Email>(withWhitespace.TheEmail)
  207. .TheEmail.Should()
  208. .Be(noWhitespace.TheEmail);
  209. reader.Get<Email>(noWhitespace.TheEmail)
  210. .Should()
  211. .Be(reader.Get<Email>(withWhitespace.TheEmail));
  212. updater.Delete<Email>(withWhitespace.TheEmail);
  213. Assert.Throws<NoSuchDocumentException>(() => updater.Delete<Email>(withWhitespace.TheEmail));
  214. Assert.Throws<NoSuchDocumentException>(() => updater.Delete<Email>(noWhitespace.TheEmail));
  215. });
  216. }
  217. [Test]
  218. public void TryingToFetchNonExistentItemDoesNotCauseSessionToTryAndAddItWithANullInstance()
  219. {
  220. var user = new User { Id = Guid.NewGuid() };
  221. UseInScope(reader => reader.TryGet(user.Id, out user)
  222. .Should()
  223. .Be(false));
  224. }
  225. [Test]
  226. public void RepeatedlyAddingAndRemovingObjectResultsInNoObjectBeingSaved()
  227. {
  228. var user = new User { Id = Guid.NewGuid() };
  229. UseInTransactionalScope((reader, updater) =>
  230. {
  231. updater.Save(user.Id, user);
  232. updater.Delete(user);
  233. updater.Save(user.Id, user);
  234. updater.Delete(user);
  235. updater.Save(user.Id, user);
  236. updater.Delete(user);
  237. });
  238. UseInScope(reader => reader.TryGet(user.Id, out user)
  239. .Should()
  240. .BeFalse());
  241. }
  242. [Test]
  243. public void LoadingRemovingAndAddingObjectInTransactionResultsInObjectBeingSaved()
  244. {
  245. var user = new User { Id = Guid.NewGuid() };
  246. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user));
  247. UseInTransactionalScope((reader, updater) =>
  248. {
  249. user = reader.Get<User>(user.Id);
  250. updater.Delete(user);
  251. reader.TryGet(user.Id, out User _)
  252. .Should()
  253. .Be(false);
  254. updater.Save(user);
  255. reader.TryGet(user.Id, out User _)
  256. .Should()
  257. .Be(true);
  258. updater.Delete(user);
  259. reader.TryGet(user.Id, out User _)
  260. .Should()
  261. .Be(false);
  262. updater.Save(user);
  263. reader.TryGet(user.Id, out User _)
  264. .Should()
  265. .Be(true);
  266. });
  267. UseInScope(reader => reader.TryGet(user.Id, out user)
  268. .Should()
  269. .Be(true));
  270. }
  271. [Test]
  272. public void ReturnsSameInstanceOnRepeatedLoads()
  273. {
  274. var user = new User { Id = Guid.NewGuid() };
  275. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user));
  276. UseInScope(reader =>
  277. {
  278. var loaded1 = reader.Get<User>(user.Id);
  279. var loaded2 = reader.Get<User>(user.Id);
  280. Assert.That(loaded1, Is.SameAs(loaded2));
  281. });
  282. }
  283. [Test]
  284. public void ReturnsSameInstanceOnLoadAfterSave()
  285. {
  286. var user = new User { Id = Guid.NewGuid() };
  287. UseInTransactionalScope((reader, updater) =>
  288. {
  289. updater.Save(user.Id, user);
  290. var loaded1 = reader.Get<User>(user.Id);
  291. var loaded2 = reader.Get<User>(user.Id);
  292. Assert.That(loaded1, Is.SameAs(loaded2));
  293. Assert.That(loaded1, Is.SameAs(user));
  294. });
  295. }
  296. [Test]
  297. public void HandlesHashSets()
  298. {
  299. var user = new User { Id = Guid.NewGuid() };
  300. var userSet = new HashSet<User> { user };
  301. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, userSet));
  302. UseInScope(reader =>
  303. {
  304. var loadedUser = reader.Get<HashSet<User>>(user.Id);
  305. Assert.That(loadedUser.Count, Is.EqualTo(1));
  306. });
  307. }
  308. [Test]
  309. public void HandlesHashSetsInObjects()
  310. {
  311. var userInSet = new User
  312. {
  313. Id = Guid.NewGuid(),
  314. Email = "Email"
  315. };
  316. var user = new User
  317. {
  318. Id = Guid.NewGuid(),
  319. People = new HashSet<User> { userInSet }
  320. };
  321. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user));
  322. UseInScope(reader =>
  323. {
  324. var loadedUser = reader.Get<User>(user.Id);
  325. Assert.That(loadedUser.People.Count, Is.EqualTo(1));
  326. var loadedUserInSet = loadedUser.People.Single();
  327. Assert.That(loadedUserInSet.Id, Is.EqualTo(userInSet.Id));
  328. });
  329. }
  330. [Test]
  331. public void ThrowsExceptionWhenAttemptingToDeleteNonExistingValue()
  332. {
  333. UseInTransactionalScope((reader, updater) =>
  334. {
  335. var lassie = new Dog {Id = Guid.NewGuid()};
  336. updater.Save(lassie);
  337. });
  338. var buster = new Dog { Id = Guid.NewGuid() };
  339. UseInTransactionalScope((reader, updater) => Assert.Throws<NoSuchDocumentException>(() => updater.Delete(buster)));
  340. }
  341. [Test]
  342. public void HandlesDeletesOfInstancesAlreadyLoaded()
  343. {
  344. var user = new User { Id = Guid.NewGuid() };
  345. UseInTransactionalScope((reader, updater) => updater.Save(user));
  346. UseInTransactionalScope((reader, updater) =>
  347. {
  348. var loadedUser = updater.GetForUpdate<User>(user.Id);
  349. loadedUser.Should()
  350. .NotBeNull();
  351. updater.Delete(user);
  352. Assert.Throws<NoSuchDocumentException>(() => reader.Get<User>(user.Id));
  353. });
  354. UseInScope(reader => Assert.Throws<NoSuchDocumentException>(() => reader.Get<User>(user.Id)));
  355. }
  356. [Test]
  357. public void HandlesDeletesOfInstancesNotYetLoaded()
  358. {
  359. var user = new User { Id = Guid.NewGuid() };
  360. UseInTransactionalScope((reader, updater) => updater.Save(user));
  361. UseInTransactionalScope((reader, updater) =>
  362. {
  363. updater.Delete(user);
  364. Assert.Throws<NoSuchDocumentException>(() => updater.GetForUpdate<User>(user.Id));
  365. });
  366. UseInScope(reader => Assert.Throws<NoSuchDocumentException>(() => reader.Get<User>(user.Id)));
  367. }
  368. [Test]
  369. public void HandlesAValueBeingAddedAndDeletedDuringTheSameSession()
  370. {
  371. var user = new User { Id = Guid.NewGuid() };
  372. UseInTransactionalScope((reader, updater) =>
  373. {
  374. updater.Save(user);
  375. updater.Delete(user);
  376. Assert.Throws<NoSuchDocumentException>(() => updater.GetForUpdate<User>(user.Id));
  377. });
  378. UseInScope(reader => Assert.Throws<NoSuchDocumentException>(() => reader.Get<User>(user.Id)));
  379. }
  380. [Test]
  381. public void TracksAndUpdatesLoadedAggregates()
  382. {
  383. var user = new User { Id = Guid.NewGuid() };
  384. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user));
  385. UseInTransactionalScope((reader, updater) =>
  386. {
  387. var loadedUser = updater.GetForUpdate<User>(user.Id);
  388. loadedUser.Password = "NewPassword";
  389. });
  390. UseInScope(reader =>
  391. {
  392. var loadedUser = reader.Get<User>(user.Id);
  393. Assert.That(loadedUser.Password, Is.EqualTo("NewPassword"));
  394. });
  395. }
  396. [Test]
  397. public void ThrowsWhenAttemptingToSaveExistingAggregate()
  398. {
  399. var user = new User { Id = Guid.NewGuid() };
  400. UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user));
  401. Assert.Throws<AttemptToSaveAlreadyPersistedValueException>(() => UseInTransactionalScope((reader, updater) => updater.Save(user.Id, user)));
  402. }
  403. [Test]
  404. public void HandlesInstancesOfDifferentTypesWithTheSameId()
  405. {
  406. var user = new User
  407. {
  408. Id = Guid.NewGuid(),
  409. Email = "email"
  410. };
  411. var dog = new Dog { Id = user.Id };
  412. UseInTransactionalScope((reader, updater) =>
  413. {
  414. updater.Save<IPersistentEntity<Guid>>(user);
  415. updater.Save<IPersistentEntity<Guid>>(dog);
  416. });
  417. UseInScope(reader =>
  418. {
  419. var loadedDog = reader.Get<Dog>(dog.Id);
  420. var loadedUser = reader.Get<User>(dog.Id);
  421. Assert.That(loadedDog.Name, Is.EqualTo(dog.Name));
  422. Assert.That(loadedUser.Email, Is.EqualTo(user.Email));
  423. Assert.That(loadedDog.Id, Is.EqualTo(user.Id));
  424. Assert.That(loadedUser.Id, Is.EqualTo(user.Id));
  425. });
  426. }
  427. [Test]
  428. public void FetchesAllinstancesPerType()
  429. {
  430. UseInTransactionalScope((reader, updater) =>
  431. {
  432. updater.Save(new User {Id = Guid.NewGuid()});
  433. updater.Save(new User {Id = Guid.NewGuid()});
  434. updater.Save(new Dog {Id = Guid.NewGuid()});
  435. updater.Save(new Dog {Id = Guid.NewGuid()});
  436. });
  437. using (ServiceLocator.BeginScope())
  438. {
  439. Assert.That(ServiceLocator.DocumentDbBulkReader().GetAll<Dog>().ToList(), Has.Count.EqualTo(2));
  440. Assert.That(ServiceLocator.DocumentDbBulkReader().GetAll<User>().ToList(), Has.Count.EqualTo(2));
  441. }
  442. }
  443. [Test]
  444. public void ThrowsIfUsedByMultipleThreads()
  445. {
  446. IDocumentDbSession session = null;
  447. using var wait = new ManualResetEventSlim();
  448. ThreadPool.QueueUserWorkItem(state =>
  449. {
  450. ServiceLocator.ExecuteInIsolatedScope(() => session = ServiceLocator.DocumentDbSession());
  451. wait.Set();
  452. });
  453. wait.Wait();
  454. var user = new User { Id = Guid.NewGuid() };
  455. Assert.Throws<MultiThreadedUseException>(() => session.Get<User>(Guid.NewGuid()));
  456. Assert.Throws<MultiThreadedUseException>(() => session.GetAll<User>());
  457. Assert.Throws<MultiThreadedUseException>(() => session.Save(user, user.Id));
  458. Assert.Throws<MultiThreadedUseException>(() => session.Delete(user));
  459. Assert.Throws<MultiThreadedUseException>(() => session.Dispose());
  460. Assert.Throws<MultiThreadedUseException>(() => session.Save(new User()));
  461. Assert.Throws<MultiThreadedUseException>(() => session.TryGet(Guid.NewGuid(), out user));
  462. Assert.Throws<MultiThreadedUseException>(() => session.Delete(user));
  463. }
  464. [Test]
  465. public void GetHandlesSubTyping()
  466. {
  467. var user1 = new User { Id = Guid.NewGuid() };
  468. var person1 = new Person { Id = Guid.NewGuid() };
  469. UseInTransactionalScope((reader, updater) =>
  470. {
  471. updater.Save(user1);
  472. updater.Save(person1);
  473. });
  474. UseInScope(reader =>
  475. {
  476. Assert.That(reader.Get<Person>(user1.Id), Is.EqualTo(user1));
  477. Assert.That(reader.Get<Person>(person1.Id), Is.EqualTo(person1));
  478. });
  479. }
  480. [Test]
  481. public void GetAllHandlesSubTyping()
  482. {
  483. var user1 = new User { Id = Guid.NewGuid() };
  484. var person1 = new Person { Id = Guid.NewGuid() };
  485. UseInTransactionalScope((reader, updater) =>
  486. {
  487. updater.Save(user1);
  488. updater.Save(person1);
  489. });
  490. using (ServiceLocator.BeginScope())
  491. {
  492. var people = ServiceLocator.DocumentDbBulkReader().GetAll<Person>().ToList();
  493. Assert.That(people, Has.Count.EqualTo(2));
  494. Assert.That(people, Contains.Item(user1));
  495. Assert.That(people, Contains.Item(person1));
  496. }
  497. }
  498. [Test]
  499. public void ThrowsExceptionIfYouTryToSaveAnIHasPersistentIdentityWithNoId()
  500. {
  501. var user1 = new User { Id = Guid.Empty };
  502. UseInTransactionalScope((reader, updater) => updater.Invoking(@this => @this.Save(user1))
  503. .Should().Throw<Exception>());
  504. }
  505. [Test]
  506. public void GetByIdsShouldReturnOnlyMatchingResultEvenWhenMoreResultsAreInTheCache()
  507. {
  508. var user1 = new User { Id = Guid.Parse("00000000-0000-0000-0000-000000000001") };
  509. var user2 = new User { Id = Guid.Parse("00000000-0000-0000-0000-000000000002") };
  510. UseInTransactionalScope((reader, updater) =>
  511. {
  512. updater.Save(user1);
  513. updater.Save(user2);
  514. var people = reader.GetAll<User>(new[] {user1.Id});
  515. Assert.That(people.ToList(), Has.Count.EqualTo(1));
  516. Assert.That(people, Contains.Item(user1));
  517. });
  518. }
  519. [Test]
  520. public void GetAllIdsShouldOnlyReturnResultsWithTheGivenType()
  521. {
  522. var userid1 = Guid.Parse("00000000-0000-0000-0000-000000000001");
  523. var userid2 = Guid.Parse("00000000-0000-0000-0000-000000000002");
  524. var user1 = new User {Id = userid1 };
  525. var user2 = new User { Id = userid2 };
  526. var dog = new Dog {Id = Guid.Parse("00000000-0000-0000-0000-000000000010") };
  527. UseInTransactionalScope((reader, updater) =>
  528. {
  529. updater.Save(user1);
  530. updater.Save(user2);
  531. updater.Save(dog);
  532. });
  533. ServiceLocator.ExecuteInIsolatedScope(() =>
  534. {
  535. var ids = ServiceLocator.DocumentDbBulkReader()
  536. .GetAllIds<User>()
  537. .ToSet();
  538. ids.Count.Should()
  539. .Be(2);
  540. ids.Should()
  541. .Contain(userid1);
  542. ids.Should()
  543. .Contain(userid2);
  544. });
  545. }
  546. [Test]
  547. public void GetAllIdsShouldOnlyReturnResultsWithTheGivenTypeWhenCalledWithinTheInsertingTransaction()
  548. {
  549. var userid1 = Guid.Parse("00000000-0000-0000-0000-000000000001");
  550. var userid2 = Guid.Parse("00000000-0000-0000-0000-000000000002");
  551. var user1 = new User { Id = userid1 };
  552. var user2 = new User { Id = userid2 };
  553. var dog = new Dog { Id = Guid.Parse("00000000-0000-0000-0000-000000000010") };
  554. UseInTransactionalScope((reader, updater) =>
  555. {
  556. updater.Save(user1);
  557. updater.Save(user2);
  558. updater.Save(dog);
  559. var ids = ServiceLocator.DocumentDbBulkReader()
  560. .GetAllIds<User>()
  561. .ToSet();
  562. ids.Count.Should()
  563. .Be(2);
  564. ids.Should()
  565. .Contain(userid1);
  566. ids.Should()
  567. .Contain(userid2);
  568. });
  569. }
  570. [Test]
  571. public void DeletingAllObjectsOfATypeLeavesNoSuchObjectsInTheDbButLeavesOtherObjectsInPlaceAndReturnsTheNumberOfDeletedObjects()
  572. {
  573. using(ServiceLocator.BeginScope())
  574. {
  575. var store = CreateStore();
  576. var dictionary = new Dictionary<Type, Dictionary<string, string>>();
  577. 1.Through(4).ForEach(num =>
  578. {
  579. var user = new User {Id = Guid.NewGuid()};
  580. store.Add(user.Id, user, dictionary);
  581. });
  582. 1.Through(4).ForEach(num =>
  583. {
  584. var person = new Person {Id = Guid.NewGuid()};
  585. store.Add(person.Id, person, dictionary);
  586. });
  587. }
  588. using(ServiceLocator.BeginScope())
  589. {
  590. var store = CreateStore();
  591. store.GetAll<User>().Should().HaveCount(4);
  592. store.GetAll<Person>().Should().HaveCount(8); //User inherits person
  593. store.GetAllIds<User>().ForEach(userId => store.Remove(userId, typeof(User)));
  594. store.GetAll<User>().Should().HaveCount(0);
  595. store.GetAll<Person>().Should().HaveCount(4);
  596. }
  597. }
  598. void InsertUsersInOtherDocumentDb(Guid userId)
  599. {
  600. using var cloneServiceLocator = ServiceLocator.Clone();
  601. cloneServiceLocator.ExecuteTransactionInIsolatedScope(() => cloneServiceLocator.DocumentDbUpdater()
  602. .Save(new User {Id = userId}));
  603. }
  604. [Test]
  605. public void Can_get_document_of_previously_unknown_class_added_by_onother_documentDb_instance()
  606. {
  607. var userId = Guid.Parse("00000000-0000-0000-0000-000000000001");
  608. InsertUsersInOtherDocumentDb(userId);
  609. using(ServiceLocator.BeginScope())
  610. {
  611. ServiceLocator.DocumentDbSession().Get<User>(userId);
  612. }
  613. }
  614. [Test]
  615. public void Can_get_all_documents_of_previously_unknown_class_added_by_onother_documentDb_instance()
  616. {
  617. var userId = Guid.Parse("00000000-0000-0000-0000-000000000001");
  618. InsertUsersInOtherDocumentDb(userId);
  619. using (ServiceLocator.BeginScope())
  620. {
  621. ServiceLocator.DocumentDbSession().GetAll<User>().Count().Should().Be(1);
  622. }
  623. }
  624. [Test]
  625. public void Can_get_all_documents_of_previously_unknown_class_added_by_onother_documentDb_instance_byId()
  626. {
  627. var userId = Guid.Parse("00000000-0000-0000-0000-000000000001");
  628. InsertUsersInOtherDocumentDb(userId);
  629. UseInScope(reader => reader.GetAll<User>(EnumerableCE.Create(userId))
  630. .Count()
  631. .Should()
  632. .Be(1));
  633. }
  634. public DocumentDbTests([NotNull] string _) : base(_) {}
  635. }
  636. }