From c00632585021a9c30ac9173432569f1ab1e62b95 Mon Sep 17 00:00:00 2001
From: Tomasz Jarosik <tomek.jarosik@gmail.com>
Date: Sun, 10 Feb 2019 03:01:45 +0000
Subject: [PATCH] Add few unit tests for CollectionService (#437)

---
 .../Services/CollectionServiceTests.cs        | 183 ++++++++++++++++++
 1 file changed, 183 insertions(+)
 create mode 100644 test/Core.Test/Services/CollectionServiceTests.cs

diff --git a/test/Core.Test/Services/CollectionServiceTests.cs b/test/Core.Test/Services/CollectionServiceTests.cs
new file mode 100644
index 0000000000..ccf042823c
--- /dev/null
+++ b/test/Core.Test/Services/CollectionServiceTests.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+using Bit.Core.Repositories;
+using Bit.Core.Services;
+using NSubstitute;
+using Bit.Core.Exceptions;
+
+namespace Bit.Core.Test.Services
+{
+    public class CollectionServiceTest
+    {
+        readonly IEventService _eventService;
+        readonly IOrganizationRepository _organizationRepository;
+        readonly IOrganizationUserRepository _organizationUserRepository;
+        readonly ICollectionRepository _collectionRepository;
+        readonly IUserRepository _userRepository;
+        readonly IMailService _mailService;
+
+        public CollectionServiceTest()
+        {
+            _eventService = Substitute.For<IEventService>();
+            _organizationRepository = Substitute.For<IOrganizationRepository>();
+            _organizationUserRepository = Substitute.For<IOrganizationUserRepository>();
+            _collectionRepository = Substitute.For<ICollectionRepository>();
+            _userRepository = Substitute.For<IUserRepository>();
+            _mailService = Substitute.For<IMailService>();
+        }
+
+        [Fact]
+        public async Task SaveAsync_CollectionNotFound()
+        {
+            var collectionService = new CollectionService(_eventService,
+                _organizationRepository,
+                _organizationUserRepository,
+                _collectionRepository,
+                _userRepository,
+                _mailService);
+
+            var id = Guid.NewGuid();
+
+            var collection = new Models.Table.Collection
+            {
+                Id = id,
+            };
+
+            var ex = await Assert.ThrowsAsync<BadRequestException>(() => collectionService.SaveAsync(collection));
+
+            Assert.Equal("The model state is invalid.", ex.Message);
+            Assert.Equal(1, ex.ModelState.ErrorCount);
+            Assert.Equal("Organization not found", ex.ModelState.Root.Errors[0].ErrorMessage);
+        }
+
+        [Fact]
+        public async Task SaveAsync_DefaultCollectionId_createsCollectionInTheRepository()
+        {
+            // prepare the organization
+            var testOrganizationId = Guid.NewGuid();
+            var testOrganization = new Models.Table.Organization()
+            {
+                Id = testOrganizationId,
+            };
+            _organizationRepository.GetByIdAsync(testOrganizationId).Returns<Models.Table.Organization>(testOrganization);
+
+            var collectionService = new CollectionService(_eventService,
+                _organizationRepository,
+                _organizationUserRepository,
+                _collectionRepository,
+                _userRepository,
+                _mailService);
+
+            // execute
+            var testCollection = new Models.Table.Collection
+            {
+                OrganizationId = testOrganizationId,
+            };
+            await collectionService.SaveAsync(testCollection);
+
+            // verify
+            await _collectionRepository.Received().CreateAsync(testCollection);
+        }
+
+        [Fact]
+        public async Task SaveAsync_respectsMaxNumberOfCollectionsPerOrganization()
+        {
+            // prepare the organization
+            var testOrganizationId = Guid.NewGuid();
+            var testOrganization = new Models.Table.Organization()
+            {
+                Id = testOrganizationId,
+                MaxCollections = 2,
+            };
+            _organizationRepository.GetByIdAsync(testOrganizationId).Returns(testOrganization);
+            _collectionRepository.GetCountByOrganizationIdAsync(testOrganizationId).Returns(2);
+
+            // execute
+            var collectionService = new CollectionService(_eventService,
+                _organizationRepository,
+                _organizationUserRepository,
+                _collectionRepository,
+                _userRepository,
+                _mailService);
+
+            var testCollection = new Models.Table.Collection { OrganizationId = testOrganizationId };
+
+            // verify & expect exception to be thrown
+            var ex = await Assert.ThrowsAsync<BadRequestException>(() => collectionService.SaveAsync(testCollection));
+
+            Assert.Equal("The model state is invalid.", ex.Message);
+            Assert.Equal(1, ex.ModelState.ErrorCount);
+            Assert.Equal("You have reached the maximum number of collections (2) for this organization.",
+                ex.ModelState.Root.Errors[0].ErrorMessage);
+        }
+
+        [Fact]
+        public async Task DeleteUserAsync_deletesValidUserWhoBelongsToCollection()
+        {
+            // prepare the organization
+            var testOrganizationId = Guid.NewGuid();
+            var testOrganization = new Models.Table.Organization()
+            {
+                Id = testOrganizationId,
+            };
+            var testUserId = Guid.NewGuid();
+            var organizationUser = new Models.Table.OrganizationUser
+            {
+                Id = testUserId,
+                OrganizationId = testOrganizationId,
+            };
+            _organizationUserRepository.GetByIdAsync(testUserId).Returns(organizationUser);
+
+            // execute
+            var collectionService = new CollectionService(_eventService,
+                _organizationRepository,
+                _organizationUserRepository,
+                _collectionRepository,
+                _userRepository,
+                _mailService);
+
+            var testCollection = new Models.Table.Collection { OrganizationId = testOrganizationId };
+            await collectionService.DeleteUserAsync(testCollection, organizationUser.Id);
+
+            // verify
+            await _collectionRepository.Received().DeleteUserAsync(testCollection.Id, organizationUser.Id);
+        }
+
+        [Fact]
+        public async Task DeleteUserAsync_throwsIfUserIsInvalid()
+        {
+            // prepare the organization
+            var testOrganizationId = Guid.NewGuid();
+            var testOrganization = new Models.Table.Organization()
+            {
+                Id = testOrganizationId,
+            };
+            var testUserId = Guid.NewGuid();
+            var nonOrganizationUser = new Models.Table.OrganizationUser
+            {
+                Id = testUserId,
+                OrganizationId = Guid.NewGuid(),
+            };
+            _organizationUserRepository.GetByIdAsync(testUserId).Returns(nonOrganizationUser);
+
+            // execute
+            var collectionService = new CollectionService(_eventService,
+                _organizationRepository,
+                _organizationUserRepository,
+                _collectionRepository,
+                _userRepository,
+                _mailService);
+
+            var testCollection = new Models.Table.Collection { OrganizationId = testOrganizationId };
+
+            // verify
+            // invalid user
+            await Assert.ThrowsAsync<NotFoundException>(() => collectionService.DeleteUserAsync(testCollection, Guid.NewGuid()));
+            // user from other organization
+            await Assert.ThrowsAsync<NotFoundException>(() => collectionService.DeleteUserAsync(testCollection, testUserId));
+        }
+    }
+}