public async Task Expiration_Is_Updated_After_File_Write_If_Sliding_Expiration_Is_Used()
        {
            var fileId             = Guid.NewGuid().ToString("n");
            var tusStore           = Substitute.For <ITusStore, ITusCreationStore, ITusExpirationStore>();
            var tusCreationStore   = (ITusCreationStore)tusStore;
            var tusExpirationStore = (ITusExpirationStore)tusStore;

            tusCreationStore.CreateFileAsync(1, null, CancellationToken.None).ReturnsForAnyArgs(fileId);
            tusStore.AppendDataAsync(fileId, Arg.Any <Stream>(), Arg.Any <CancellationToken>()).Returns(3);
            tusStore.FileExistAsync(fileId, Arg.Any <CancellationToken>()).Returns(true);
            tusStore.GetUploadLengthAsync(fileId, Arg.Any <CancellationToken>()).Returns(1);

            var expiration = new SlidingExpiration(TimeSpan.FromHours(24));

            DateTimeOffset?uploadExpiresAt = null;

            using (var server = TestServerFactory.Create(app =>
            {
                var config = new DefaultTusConfiguration
                {
                    Store = tusStore,
                    UrlPath = "/files",
                    Expiration = expiration,
                };

                config.Events = new Events
                {
                    OnAuthorizeAsync = ctx =>
                    {
                        if (ctx.Intent != IntentType.WriteFile)
                        {
                            return(Task.FromResult(0));
                        }

                        // Emulate that OnCreateComplete took 10 sec to complete.
                        var fakeSystemTime = DateTimeOffset.UtcNow.AddSeconds(10);
                        config.MockSystemTime(fakeSystemTime);
                        uploadExpiresAt = fakeSystemTime.Add(expiration.Timeout);
                        return(Task.FromResult(0));
                    }
                };

                app.UseTus(_ => config);
            }))
            {
                var response = await server
                               .CreateTusResumableRequest("/files")
                               .AddHeader("Upload-Length", "100")
                               .AddBody()
                               .SendAsync("POST");

                response.StatusCode.ShouldBe(HttpStatusCode.Created);
                // Once for file creation, once for writing the data.
                await tusExpirationStore.Received(2).SetExpirationAsync(fileId, Arg.Any <DateTimeOffset>(), Arg.Any <CancellationToken>());

                response.ShouldContainHeader("Upload-Expires", uploadExpiresAt.Value.ToString("R"));
            }
        }
        public async Task Post_Requests_Contain_Upload_Expires_Header_For_Partial_Uploads_If_Expiration_Is_Configured(
            string methodToUse)
        {
            var store = (ITusStore)Substitute.For(new[]
            {
                typeof(ITusStore),
                typeof(ITusCreationStore),
                typeof(ITusConcatenationStore),
                typeof(ITusExpirationStore)
            },
                                                  new object[0]
                                                  );
            var concatenationStore = (ITusConcatenationStore)store;

            concatenationStore.CreatePartialFileAsync(-1, null, CancellationToken.None).ReturnsForAnyArgs(Guid.NewGuid().ToString());

            var now = DateTimeOffset.Now;

            using (var server = TestServerFactory.Create(app =>
            {
                var config = new DefaultTusConfiguration
                {
                    Store = store,
                    UrlPath = "/files",
                    Expiration = new AbsoluteExpiration(TimeSpan.FromMinutes(10))
                };

                config.MockSystemTime(now);

                app.UseTus(_ => config);
            }))
            {
                var response = await server
                               .CreateRequest("/files")
                               .AddTusResumableHeader()
                               .AddHeader("Upload-Length", "1")
                               .AddHeader("Upload-Concat", "partial")
                               .OverrideHttpMethodIfNeeded("POST", methodToUse)
                               .SendAsync(methodToUse);

                response.StatusCode.ShouldBe(HttpStatusCode.Created);
                response.ShouldContainHeader("Upload-Expires", now.Add(TimeSpan.FromMinutes(10)).ToString("r"));
            }
        }