示例#1
0
        public async Task Given_Values_When_UpsertUrlItemEntityAsync_Invoked_Then_It_Should_Return_Result(string shortUrl, string owner, HttpStatusCode statusCode)
        {
            var record = new UrlItemEntity()
            {
                ShortUrl = shortUrl, Owner = owner
            };

            var item = new Mock <ItemResponse <UrlItemEntity> >();

            item.SetupGet(p => p.Resource).Returns(record);
            item.SetupGet(p => p.StatusCode).Returns(statusCode);

            var container = new Mock <Container>();

            container.Setup(p => p.UpsertItemAsync <UrlItemEntity>(It.IsAny <UrlItemEntity>(), It.IsAny <PartitionKey?>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(item.Object);

            var helper = new Mock <ICosmosDbContainerHelper>();

            helper.Setup(p => p.GetContainerAsync()).ReturnsAsync(container.Object);

            var command = new CosmosDbCommand(helper.Object);

            var result = await command.UpsertItemEntityAsync <UrlItemEntity>(record).ConfigureAwait(false);

            result.Should().Be((int)statusCode);
        }
示例#2
0
        public async Task <UrlItem> ShortenAsync(string originalUrl)
        {
            // Get shortened URL.
            var sb = new StringBuilder();

            for (var i = 0; i < LengthOfShortUrl; i++)
            {
                var index = random.Next(LengthOfShortUrl);
                sb.Append(CharacterPool[index]);
            }
            var shortUrl = sb.ToString();

            // Store shortened URL to Table Storage.
            await this._client.CreateTableIfNotExistsAsync(TableName);

            var table  = this._client.GetTableClient(TableName);
            var entity = new UrlItemEntity()
            {
                PartitionKey = PartitionKey,
                RowKey       = shortUrl,
                Timestamp    = DateTimeOffset.UtcNow,
                OriginalUrl  = originalUrl,
                ShortUrl     = shortUrl,
            };
            await table.UpsertEntityAsync(entity);

            return(entity);
        }
示例#3
0
        public void Given_Values_When_Serialised_Then_It_Should_Return_Result(string original, string shortUrl, string owner)
        {
            var entityId   = Guid.NewGuid();
            var collection = PartitionType.Url;
            var uri        = new Uri(original);
            var now        = DateTimeOffset.UtcNow;

            var entity = new UrlItemEntity()
            {
                EntityId      = entityId,
                OriginalUrl   = new Uri(original),
                ShortUrl      = shortUrl,
                Owner         = owner,
                DateGenerated = now,
                DateUpdated   = now
            };

            var dateGenerated = JsonConvert.SerializeObject(now);
            var dateUpdated   = JsonConvert.SerializeObject(now);

            var serialised = JsonConvert.SerializeObject(entity);

            serialised.Should().Contain($"\"id\":\"{entityId.ToString()}\"");
            serialised.Should().Contain($"\"collection\":\"{collection.ToString()}\"");
            serialised.Should().Contain($"\"originalUrl\":\"{uri.ToString()}\"");
            serialised.Should().Contain($"\"shortUrl\":\"{shortUrl}\"");
            serialised.Should().Contain($"\"owner\":\"{owner}\"");
            serialised.Should().Contain($"\"dateGenerated\":{dateGenerated}");
            serialised.Should().Contain($"\"dateUpdated\":{dateUpdated}");
        }
示例#4
0
        public void Given_Type_When_Instantiated_Then_It_Should_Return_Result()
        {
            var entity = new UrlItemEntity();

            entity.CoOwners.Should().NotBeNull()
            .And.HaveCount(0);
        }
示例#5
0
        public void Given_PartitionType_Then_It_Should_Return_Result(PartitionType collection)
        {
            var entity = new UrlItemEntity();

            entity.PartitionKey.Should().Be(collection.ToString());
            entity.PartitionKeyPath.Should().Be("/collection");
        }
示例#6
0
        public async Task Given_ShortUrl_When_ExpandAsync_Invoked_Then_It_Should_Return_Result(string hostname, string shortUrl, string original)
        {
            var shorten = new Mock <ShortenUrlSettings>();

            shorten.SetupGet(p => p.Hostname).Returns(hostname);

            var settings = this._mocker.CreateAppSettingsInstance();

            settings.SetupGet(p => p.ShortenUrl).Returns(shorten.Object);

            var item = new UrlItemEntity()
            {
                ShortUrl    = shortUrl,
                OriginalUrl = new Uri(original)
            };

            var query = new Mock <IQuery>();

            query.Setup(p => p.GetUrlItemEntityAsync(It.IsAny <string>())).ReturnsAsync(item);

            var command = new Mock <ICommand>();

            var service = new ExpanderService(settings.Object, query.Object, command.Object);

            var payload = new ExpanderRequest()
            {
                ShortUrl = shortUrl
            };

            var result = await service.ExpandAsync(payload).ConfigureAwait(false);

            result.ShortUrl.Should().Be(shortUrl);
            result.Original.ToString().TrimEnd('/').Should().Be(original.TrimEnd('/'));
            result.Shortened.ToString().TrimEnd('/').Should().Be($"https://{hostname}/{shortUrl}");
        }
示例#7
0
        public void Given_DateUpdated_When_Decorator_Captured_Then_It_Should_Have_PropertyOrderOf_MaxValue()
        {
            var entity    = new UrlItemEntity();
            var pi        = typeof(UrlItemEntity).GetProperty("DateUpdated", BindingFlags.Public | BindingFlags.Instance);
            var attribute = pi.GetCustomAttribute <JsonPropertyAttribute>(inherit: false);

            attribute.Order.Should().Be(int.MaxValue);
        }
示例#8
0
        public void Given_InvalidDateUpdated_When_Assigned_Then_It_Should_Throw_Exception()
        {
            var entity = new UrlItemEntity();

            Action action = () => entity.DateUpdated = DateTimeOffset.MinValue;

            action.Should().Throw <InvalidOperationException>();
        }
示例#9
0
        /// <inheritdoc/>
        public async Task <int> UpsertAsync(ShortenerResponse payload)
        {
            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            var item = new UrlItemEntity(payload);

            var result = await this._command.UpsertItemEntityAsync <UrlItemEntity>(item).ConfigureAwait(false);

            return(result);
        }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ExpanderResponse"/> class.
 /// </summary>
 /// <param name="item"><see cref="UrlItemEntity"/> object.</param>
 public ExpanderResponse(UrlItemEntity item)
     : base()
 {
     this.EntityId      = item.EntityId;
     this.UrlId         = item.EntityId;
     this.Original      = item.OriginalUrl;
     this.ShortUrl      = item.ShortUrl;
     this.Title         = item.Title;
     this.Description   = item.Description;
     this.Owner         = item.Owner;
     this.CoOwners      = item.CoOwners;
     this.DateGenerated = item.DateGenerated;
     this.DateUpdated   = item.DateUpdated;
     this.HitCount      = item.HitCount;
 }
示例#11
0
        public void Given_Null_When_Serialised_Then_It_Should_Throw_Exception(string original, string shortUrl, string owner)
        {
            var entity = new UrlItemEntity()
            {
                OriginalUrl   = string.IsNullOrWhiteSpace(original) ? null : new Uri(original),
                ShortUrl      = shortUrl,
                Owner         = owner,
                DateGenerated = DateTimeOffset.UtcNow,
                DateUpdated   = DateTimeOffset.UtcNow
            };

            Action action = () => JsonConvert.SerializeObject(entity);

            action.Should().Throw <JsonSerializationException>();
        }
示例#12
0
        public async Task Given_ShortUrl_When_ExistsAsync_Invoked_Then_It_Should_Return_True(string shortUrl)
        {
            var settings = this._mocker.CreateAppSettingsInstance();

            var item = new UrlItemEntity();

            var query = new Mock <IQuery>();

            query.Setup(p => p.GetUrlItemEntityAsync(It.IsAny <string>())).ReturnsAsync(item);

            var command = new Mock <ICommand>();

            var service = new ShortenerService(settings.Object, query.Object, command.Object);

            var result = await service.ExistsAsync(shortUrl).ConfigureAwait(false);

            result.Should().BeTrue();
        }
示例#13
0
        public async Task <UrlItem> ExpandAsync(string shortUrl)
        {
            await this._client.CreateTableIfNotExistsAsync(TableName);

            var table  = this._client.GetTableClient(TableName);
            var entity = default(UrlItemEntity);

            try
            {
                var response = await table.GetEntityAsync <UrlItemEntity>(PartitionKey, shortUrl);

                entity = response.Value;
            }
            catch
            {
                entity = new UrlItemEntity();
            }

            return(entity);
        }
示例#14
0
        public async Task Given_Values_When_GetUrlItemEntityAsync_Invoked_Then_It_Should_Return_Result(string shortUrl)
        {
            var record = new UrlItemEntity()
            {
                ShortUrl = shortUrl
            };
            var records = new List <UrlItemEntity>()
            {
                record
            };

            var feed = new Mock <FeedResponse <UrlItemEntity> >();

            feed.SetupGet(p => p.Resource).Returns(records);
            feed.Setup(p => p.GetEnumerator()).Returns(records.GetEnumerator());

            var iterator = new Mock <FeedIterator <UrlItemEntity> >();

            iterator.SetupSequence(p => p.HasMoreResults)
            .Returns(true)
            .Returns(false);
            iterator.Setup(p => p.ReadNextAsync(It.IsAny <CancellationToken>())).ReturnsAsync(feed.Object);

            var container = new Mock <Container>();

            container.Setup(p => p.GetItemQueryIterator <UrlItemEntity>(It.IsAny <QueryDefinition>(), It.IsAny <string>(), It.IsAny <QueryRequestOptions>()))
            .Returns(iterator.Object);

            var helper = new Mock <ICosmosDbContainerHelper>();

            helper.Setup(p => p.GetContainerAsync()).ReturnsAsync(container.Object);

            var query = new CosmosDbQuery(helper.Object);

            var result = await query.GetUrlItemEntityAsync(shortUrl).ConfigureAwait(false);

            result.Should().NotBeNull();
            result.ShortUrl.Should().Be(shortUrl);
        }
示例#15
0
        public async Task Given_ShortUrl_When_UpsertAsync_Invoked_Then_It_Should_Return_Result(HttpStatusCode statusCode)
        {
            var settings = this._mocker.CreateAppSettingsInstance();

            var item  = new UrlItemEntity();
            var query = new Mock <IQuery>();

            var command = new Mock <ICommand>();

            command.Setup(p => p.UpsertItemEntityAsync <UrlItemEntity>(It.IsAny <UrlItemEntity>())).ReturnsAsync((int)statusCode);

            var service = new ShortenerService(settings.Object, query.Object, command.Object);

            var payload = new ShortenerResponse()
            {
                EntityId      = Guid.NewGuid(),
                DateGenerated = DateTimeOffset.UtcNow,
                DateUpdated   = DateTimeOffset.UtcNow
            };

            var result = await service.UpsertAsync(payload).ConfigureAwait(false);

            result.Should().Be((int)statusCode);
        }