public async Task FileController_ImportFile_Failue_ForUnsupportedContentType()
        {
            // setup

            var mockFileInfo = new StoredFileInfo()
            {
                FileId = "id", ContentType = "application/text", FileName = "name", Length = 2048
            };

            Mock <IFileStorage> mockStorage = new Mock <IFileStorage>();

            mockStorage.Setup(s => s.StoreAsync(It.IsAny <IFormFile>(), default))
            .ReturnsAsync(mockFileInfo);

            Mock <ILogger <FileController> > mockLogger = new Mock <ILogger <FileController> >();

            Mock <IFormFile> mockFile = new Mock <IFormFile>();

            mockFile.Setup(s => s.ContentType).Returns(mockFileInfo.ContentType);

            // act
            var controller = new FileController(mockStorage.Object, mockLogger.Object);
            var res        = await controller.ImportFile(mockFile.Object, default) as ObjectResult;

            // assert
            Assert.AreEqual((int)HttpStatusCode.BadRequest, res.StatusCode);

            mockStorage.Verify(m => m.StoreAsync(It.IsAny <IFormFile>(), default), Times.Never);
        }
        public async Task FileController_ImportFile_Failure_StorageException()
        {
            // setup

            var mockFileInfo = new StoredFileInfo()
            {
                FileId = "id", ContentType = "application/x-tar", FileName = "name", Length = 2048
            };

            Mock <IFileStorage> mockStorage = new Mock <IFileStorage>();

            mockStorage.Setup(s => s.StoreAsync(It.IsAny <IFormFile>(), default))
            .Throws <Exception>();

            Mock <ILogger <FileController> > mockLogger = new Mock <ILogger <FileController> >();

            Mock <IFormFile> mockFile = new Mock <IFormFile>();

            mockFile.Setup(s => s.ContentType).Returns(mockFileInfo.ContentType);

            // act
            var controller = new FileController(mockStorage.Object, mockLogger.Object);
            var res        = await controller.ImportFile(mockFile.Object, default) as ObjectResult;

            // assert
            Assert.AreEqual((int)HttpStatusCode.InternalServerError, res.StatusCode);

            mockStorage.Verify(m => m.StoreAsync(It.IsAny <IFormFile>(), default), Times.Once);
        }
        public async Task FileController_PullFile_Success_ForValidFileId()
        {
            // setup

            var mockStream   = new Mock <Stream>();
            var mockFileInfo = new StoredFileInfo()
            {
                FileId = "id", ContentType = "application/x-tar", FileName = "name", Length = 2048
            };

            Mock <IFileStorage> mockStorage = new Mock <IFileStorage>();

            mockStorage.Setup(s => s.GetAsync(It.IsAny <string>(), default)).ReturnsAsync((mockStream.Object, mockFileInfo));

            Mock <ILogger <FileController> > mockLogger = new Mock <ILogger <FileController> >();

            // act
            var controller = new FileController(mockStorage.Object, mockLogger.Object);
            var res        = await controller.PullFile("id", default) as FileStreamResult;

            // assert
            Assert.AreEqual("application/x-tar", res.ContentType);
            Assert.AreEqual(mockStream.Object, res.FileStream);
            Assert.AreEqual(res.FileDownloadName, mockFileInfo.FileName);

            mockStorage.Verify(m => m.GetAsync("id", default), Times.Once);
        }
        public async Task FileController_ImportFile_Success()
        {
            // setup

            var mockFileInfo = new StoredFileInfo()
            {
                FileId = "id", ContentType = "application/x-tar", FileName = "name", Length = 2048
            };

            Mock <IFileStorage> mockStorage = new Mock <IFileStorage>();

            mockStorage.Setup(s => s.StoreAsync(It.IsAny <IFormFile>(), default))
            .ReturnsAsync(mockFileInfo);

            Mock <ILogger <FileController> > mockLogger = new Mock <ILogger <FileController> >();

            Mock <IFormFile> mockFile = new Mock <IFormFile>();

            mockFile.Setup(s => s.ContentType).Returns(mockFileInfo.ContentType);

            // act
            var controller = new FileController(mockStorage.Object, mockLogger.Object);
            var res        = await controller.ImportFile(mockFile.Object, default) as ObjectResult;

            var returnedFileInfo = res.Value as StoredFileInfo;

            // assert
            Assert.AreEqual((int)HttpStatusCode.Created, res.StatusCode);

            mockStorage.Verify(m => m.StoreAsync(It.IsAny <IFormFile>(), default), Times.Once());

            Assert.AreEqual(mockFileInfo.FileName, returnedFileInfo.FileName);
        }
Exemple #5
0
        public async Task <ViewResult> Index(string id = null, bool raw = false, bool renew = false)
        {
            // fresh page
            if (string.IsNullOrWhiteSpace(id))
            {
                return(this.View("Index", this.GetModel(id)));
            }

            // log page
            StoredFileInfo file = await this.Storage.GetAsync(id, renew);

            ParsedLog log = file.Success
                ? new LogParser().Parse(file.Content)
                : new ParsedLog {
                IsValid = false, Error = file.Error
            };

            return(this.View("Index", this.GetModel(id, uploadWarning: file.Warning, expiry: file.Expiry).SetResult(log, raw)));
        }
Exemple #6
0
        public async Task <ActionResult> Index(string id = null, LogViewFormat format = LogViewFormat.Default, bool renew = false)
        {
            // fresh page
            if (string.IsNullOrWhiteSpace(id))
            {
                return(this.View("Index", this.GetModel(id)));
            }

            // fetch log
            StoredFileInfo file = await this.Storage.GetAsync(id, renew);

            // render view
            switch (format)
            {
            case LogViewFormat.Default:
            case LogViewFormat.RawView:
            {
                ParsedLog log = file.Success
                            ? new LogParser().Parse(file.Content)
                            : new ParsedLog {
                    IsValid = false, Error = file.Error
                };

                return(this.View("Index", this.GetModel(id, uploadWarning: file.Warning, expiry: file.Expiry).SetResult(log, showRaw: format == LogViewFormat.RawView)));
            }

            case LogViewFormat.RawDownload:
            {
                string content = file.Error ?? file.Content;
                return(this.File(Encoding.UTF8.GetBytes(content), "plain/text", $"SMAPI log ({id}).txt"));
            }

            default:
                throw new InvalidOperationException($"Unknown log view format '{format}'.");
            }
        }
Exemple #7
0
 public UpsertBillsCommand(StoredFileInfo bills)
 {
     Bills = bills != null ? new[] { bills } : new StoredFileInfo[0];
 }
Exemple #8
0
        public async Task <ViewResult> Index(string schemaName = null, string id = null, string operation = null)
        {
            // parse arguments
            schemaName = this.NormalizeSchemaName(schemaName);
            bool hasId      = !string.IsNullOrWhiteSpace(id);
            bool isEditView = !hasId || operation?.Trim().ToLower() == "edit";

            // build result model
            var result = this.GetModel(id, schemaName, isEditView);

            if (!hasId)
            {
                return(this.View("Index", result));
            }

            // fetch raw JSON
            StoredFileInfo file = await this.Storage.GetAsync(id);

            if (string.IsNullOrWhiteSpace(file.Content))
            {
                return(this.View("Index", result.SetUploadError("The JSON file seems to be empty.")));
            }
            result.SetContent(file.Content, expiry: file.Expiry, uploadWarning: file.Warning);

            // skip parsing if we're going to the edit screen
            if (isEditView)
            {
                return(this.View("Index", result));
            }

            // parse JSON
            JToken parsed;

            try
            {
                parsed = JToken.Parse(file.Content, new JsonLoadSettings
                {
                    DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error,
                    CommentHandling = CommentHandling.Load
                });
            }
            catch (JsonReaderException ex)
            {
                return(this.View("Index", result.AddErrors(new JsonValidatorErrorModel(ex.LineNumber, ex.Path, ex.Message, ErrorType.None))));
            }

            // format JSON
            result.SetContent(parsed.ToString(Formatting.Indented), expiry: file.Expiry, uploadWarning: file.Warning);

            // skip if no schema selected
            if (schemaName == "none")
            {
                return(this.View("Index", result));
            }

            // load schema
            JSchema schema;

            {
                FileInfo schemaFile = this.FindSchemaFile(schemaName);
                if (schemaFile == null)
                {
                    return(this.View("Index", result.SetParseError($"Invalid schema '{schemaName}'.")));
                }
                schema = JSchema.Parse(System.IO.File.ReadAllText(schemaFile.FullName));
            }

            // get format doc URL
            result.FormatUrl = this.GetExtensionField <string>(schema, "@documentationUrl");

            // validate JSON
            parsed.IsValid(schema, out IList <ValidationError> rawErrors);
            var errors = rawErrors
                         .SelectMany(this.GetErrorModels)
                         .ToArray();

            return(this.View("Index", result.AddErrors(errors)));
        }
        public async Task <IActionResult> UploadFile()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest());
            }

            var file     = new StoredFileInfo();
            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), new FormOptions().MultipartBoundaryLengthLimit);
            var reader   = new MultipartReader(boundary, HttpContext.Request.Body);
            var section  = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (contentDisposition.IsFileDisposition())
                    {
                        // Don't trust the file name sent by the client. To display the file name, HTML-encode the value.
                        var trustedFileNameForDisplay     = WebUtility.HtmlEncode(contentDisposition.FileName.Value);
                        var trustedFileNameForFileStorage = Path.GetRandomFileName();

                        var streamedFileContent = await FileHelper.ProcessStreamedFile(section, contentDisposition, ModelState, _permittedExtensions, _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }

                        var trustedFilePath = trustedFileNameForFileStorage;
                        using (var targetStream = System.IO.File.Create(trustedFilePath))
                        {
                            await targetStream.WriteAsync(streamedFileContent);

                            file.FilePath = trustedFilePath;
                            file.FileName = trustedFileNameForDisplay;
                        }
                    }
                    else if (contentDisposition.IsFormDisposition())
                    {
                        var content = new StreamReader(section.Body).ReadToEnd();
                        if (contentDisposition.Name == "userId" && int.TryParse(content, out var userId))
                        {
                            file.UserId = userId.ToString();
                        }

                        if (contentDisposition.Name == "comment")
                        {
                            file.Comment = content;
                        }

                        if (contentDisposition.Name == "isPrimary" && bool.TryParse(content, out var isPrimary))
                        {
                            file.IsPrimary = isPrimary;
                        }
                    }
                }
                section = await reader.ReadNextSectionAsync();
            }

            Files.Add(file);
            return(Created(nameof(MainController), file));
        }
        public void Copy_NotNull_SameTransactionDifferentId()
        {
            //given
            var user = new Stock {
                Name = "User1", IsUserStock = true
            };
            var external = new Stock {
                Name = "Ex"
            };
            var type = new TransactionType {
                Income = true, IsDefault = true
            };
            var tag = new Tag {
                Name = "tag"
            };
            var category = new Model.Category {
                Name = "cat"
            };
            var parent = new Transaction
            {
                Title = "Title",
                Notes = new TrulyObservableCollection <Note> {
                    new Note("Note")
                },
                BookDate      = DateTime.Today,
                UserStock     = user,
                ExternalStock = external,
                Type          = type
            };
            var storedFileInfo = new StoredFileInfo("file", parent.Id);

            parent.StoredFiles.Add(storedFileInfo);
            var source = new Position
            {
                Value    = new PaymentValue(10, 10, 0),
                Category = category,
                Title    = "pos",
                Tags     = new[] { tag },
                Parent   = parent
            };

            parent.Positions = new TrulyObservableCollection <Position>(new[] { source });
            MapperConfiguration.Configure();

            //when
            var result = Position.Copy(source);

            //then
            Assert.NotNull(result);
            Assert.NotEqual(source.Id, result.Id);
            Assert.Equal(source.Value.NetValue, result.Value.NetValue);
            Assert.Equal(source.Value.GrossValue, result.Value.GrossValue);
            Assert.Equal(source.Value.TaxPercentValue, result.Value.TaxPercentValue);
            Assert.Equal(source.Parent, result.Parent);
            Assert.Equal(source.BookDate, result.BookDate);
            Assert.Equal(source.Category, result.Category);
            Assert.Equal(source.Tags, result.Tags);
            Assert.Equal(source.Title, result.Title);

            //parent
            Assert.Equal(parent.Id, result.Parent.Id);
            Assert.Equal(parent.Title, result.Parent.Title);
            Assert.Equal(parent.Notes, result.Parent.Notes);
            Assert.Equal(parent.BookDate, result.Parent.BookDate);
            Assert.Equal(parent.UserStock, result.Parent.UserStock);
            Assert.Equal(parent.ExternalStock, result.Parent.ExternalStock);
            Assert.Equal(parent.IsPropertyChangedEnabled, result.Parent.IsPropertyChangedEnabled);
            Assert.Equal(parent.Type, result.Parent.Type);
            Assert.Equal(parent.Positions.Count, result.Parent.Positions.Count);
            Assert.True(result.Parent.IsValid);
        }
        public void Copy_NotNull_SameTransactionDifferentId()
        {
            //given
            var user = new Stock {
                Name = "User1", IsUserStock = true
            };
            var external = new Stock {
                Name = "Ex"
            };
            var type = new TransactionType {
                Income = true, IsDefault = true
            };
            var position = new Position
            {
                Value    = new PaymentValue(10, 10, 0),
                Category = new Model.Category {
                    Name = "cat"
                },
                Title = "pos",
                Tags  = new [] { new Tag {
                                     Name = "tag"
                                 } }
            };
            var source = new Transaction
            {
                Title = "Title",
                Notes = new TrulyObservableCollection <Note> {
                    new Note("Note")
                },
                BookDate      = DateTime.Today,
                UserStock     = user,
                ExternalStock = external,
                Type          = type,
                Positions     = new TrulyObservableCollection <Position>(new[] { position })
            };
            var storedFileInfo = new StoredFileInfo("file", source.Id);

            source.StoredFiles.Add(storedFileInfo);

            var expected = new Transaction($"{source.Id}{DateTime.Now}".GenerateGuid())
            {
                Title = "Title",
                Notes = new TrulyObservableCollection <Note> {
                    new Note("Note")
                },
                BookDate      = DateTime.Today,
                UserStock     = user,
                ExternalStock = external,
                Type          = type,
                Positions     = new TrulyObservableCollection <Position>(new[] { position })
            };

            expected.StoredFiles.Add(storedFileInfo);
            MapperConfiguration.Configure();

            //when
            var result = Transaction.Copy(source);

            //then
            Assert.NotNull(result);
            Assert.NotEqual(source.Id, result.Id);
            Assert.Equal(expected.Title, result.Title);
            Assert.Equal(expected.Notes.Select(x => x.Value), result.Notes.Select(x => x.Value));
            Assert.Equal(expected.BookDate, result.BookDate);
            Assert.Equal(expected.UserStock, result.UserStock);
            Assert.Equal(expected.ExternalStock, result.ExternalStock);
            Assert.Equal(expected.IsPropertyChangedEnabled, result.IsPropertyChangedEnabled);
            Assert.Equal(expected.Type, result.Type);
            Assert.Equal(expected.Positions.Count, result.Positions.Count);
            Assert.True(result.IsValid);
        }