public void FileProcess_InvalidFileWithMissingColumns_ShouldReturnInvalidFormat() { const string fileName = "AtrendProductTemplate_MissingColumns.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", fileName); var productUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = fileName, InputStream = stream }; FileUploadResult uploadResult = productUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = productUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); ValidationError validationError = processResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(true, processResult.ValidationResult.HasViolations, validationError.Message); Assert.AreEqual("Invalid file structure. Please use approved template!", validationError.Message); }
/// <summary> /// Ensures the process chain of uploading Product info: file upload,process, validation, mapping, address validation, /// warehouse creation, output file generation /// Updates upload status after each step completes /// </summary> /// <param name="input"></param> public void Upload(FileUploadInput input) { if (input == null) throw new ArgumentNullException("input"); var uploadStatus = new UploadStatus(input.UploadTraceToken); _logger.Information(string.Format("Upload initiated for file: {0}, by {1}", input.FileName, input.UserContext)); try { //Initiate upload UpdateStatus(uploadStatus, UploadStageEnum.UploadInitiated, "Initiating upload process..."); //Upload file to temp directory UpdateStatus(uploadStatus, UploadStageEnum.FileUploadStart, "File upload to temp directory started..."); FileUploadResult fileUploadResult = FileUpload(input); UpdateStatus(uploadStatus, UploadStageEnum.FileUploadEnd, "File upload to temp directory completed."); if (fileUploadResult.ValidationResult.HasViolations) { UpdateStatus(uploadStatus, UploadStageEnum.UploadCompleted, "Unable to complete upload process. " + fileUploadResult.ValidationResult.ValidationErrors.First().Message); return; } // Load File Data into memory UpdateStatus(uploadStatus, UploadStageEnum.FileProcessStart, "Load file data into memory started..."); FileProcessResult<ProductInputRow> fileProcessResult = FileProcess(new FileProcessInput(input.UserContext) { FileName = fileUploadResult.TempFileName, FilePath = fileUploadResult.TempFilePath }); UpdateStatus(uploadStatus, UploadStageEnum.FileProcessEnd, "Load file data into memory completed."); if (fileProcessResult.ValidationResult.HasViolations) { UpdateStatus(uploadStatus, UploadStageEnum.UploadCompleted, "Unable to complete upload process. " + fileProcessResult.ValidationResult.ValidationErrors.First().Message); return; } // Validate data UpdateStatus(uploadStatus, UploadStageEnum.FileDataValidateStart, "File data validation started..."); FileDataValidateResult<ProductInputRow> fileDataValidateResult = FileDataValidate(new FileDataValidateInput<ProductInputRow>(input.UserContext) { FileData = fileProcessResult.FileData }); FileDataProcessResult<ProductInputRow> fileDataProcessResult = null; if (fileDataValidateResult.ValidationResult.HasViolations) { UpdateStatus(uploadStatus, UploadStageEnum.FileDataValidateEnd, "File data validation completed. " + fileDataValidateResult.ValidationResult.ValidationErrors.First().Message); } else { UpdateStatus(uploadStatus, UploadStageEnum.FileDataValidateEnd, "File data validation completed."); } //process data if ready if (fileDataValidateResult.ReadyForUpload) { UpdateStatus(uploadStatus, UploadStageEnum.FileDataProcessStart, "File data processing started..."); fileDataProcessResult = FileDataProcess(new FileDataProcessInput<ProductInputRow>(input.UserContext) { FileData = fileDataValidateResult.FileData }); if (fileDataProcessResult.ValidationResult.HasViolations) { UpdateStatus(uploadStatus, UploadStageEnum.FileDataProcessEnd, "File data processing completed. " + fileDataProcessResult.ValidationResult.ValidationErrors.First().Message); } else { UpdateStatus(uploadStatus, UploadStageEnum.FileDataProcessEnd, "File data processing completed."); } } UpdateStatus(uploadStatus, UploadStageEnum.OutputFileProcessStart, "Output file generation started..."); OutputFileProcessResult outputFileProcessResult = OutputFileProcess(new OutputFileProcessInput<ProductInputRow>(input.UserContext) { TempFileName = fileUploadResult.TempFileName, TempFilePath = fileUploadResult.TempFilePath, ProcessedFileData = fileDataProcessResult == null ? fileDataValidateResult.FileData : fileDataProcessResult.FileData, HeadersCount = fileProcessResult.HeadersCount }); UpdateStatus(uploadStatus, UploadStageEnum.OutputFileProcessEnd, "Output file generation completed."); UpdateStatus(uploadStatus, UploadStageEnum.UploadCompleted, "Upload process completed.", outputFileProcessResult.OutputFileInfo); } catch (Exception e) { UpdateStatus(uploadStatus, UploadStageEnum.UploadCompleted, "Unable to complete upload process. An unexpected error has occurred."); _logger.Fatal("Unable to complete upload process. User context: " + input.UserContext, e); } }
/// <summary> /// Upload Excel File to temp directory on the server for further processing /// Validates format and structure of the file. Saves temp file to tem directory. /// </summary> /// <param name="input">FileUploadInput</param> /// <returns>FileUploadResult</returns> public FileUploadResult FileUpload(FileUploadInput input) { if (input == null) throw new ArgumentNullException("input"); _logger.Information(string.Format("Uploading to temp directory. File name: {0}", input.FileName)); using (input.InputStream) { var result = new FileUploadResult(input.UserContext); //validate input format ValidationResult formatValidationResult = _validator.FileFormatValidate(input.ContentType); if (formatValidationResult.HasViolations) { result.ValidationResult.ValidationErrors = formatValidationResult.ValidationErrors; return result; } var uploadedExcel = new XSSFWorkbook(input.InputStream); //validate excel file ValidationResult excelFileValidationResult = _validator.ExcelFileValidate(uploadedExcel); if (excelFileValidationResult.HasViolations) { result.ValidationResult.ValidationErrors = excelFileValidationResult.ValidationErrors; return result; } string tempFileName = Utility.ToUniqueFileName(input.FileName); string tempDirectoryPath = FileShareTempFilesPath; string tempFilePath = Utility.GetFilePath(tempDirectoryPath, tempFileName); using (var fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write)) { uploadedExcel.Write(fs); result.TempFileName = tempFileName; result.TempFilePath = tempFilePath; } return result; } }
public void OutputFileProcess_ValidTempFileProcessInputRecords_GeneratesOutputFile() { const string FileName = "AtrendProductTemplate_Small.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; var dummyProcessedData = new List<ProductInputRow> { new ProductInputRow { RowIndex = 1, UploadedProductId = Guid.NewGuid().ToString(), UploadStatus = "Success", UploadMessage = "Success Message" } }; var productUploader = EngineContext.Current.Resolve<IProductUploader>(); FileUploadResult uploadResult = productUploader.FileUpload(input); OutputFileProcessResult outputResult = productUploader.OutputFileProcess(new OutputFileProcessInput<ProductInputRow>(_userContext) { TempFileName = uploadResult.TempFileName, TempFilePath = uploadResult.TempFilePath, ProcessedFileData = dummyProcessedData }); Assert.AreEqual(false, outputResult.ValidationResult.HasViolations); Assert.IsTrue(File.Exists(outputResult.OutputFileInfo.FilePath)); }
public void Upload_ValidFileUploadInputFromExcelFile_UploadsProductDataFromTheFileUpdatesStatus() { const string FileName = "Web Map-Reikken (Autosaved) (1) - Copy.xlsx"; var traceToken = Guid.NewGuid().ToString(); var testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var productUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); memoryStream.Position = 0; var input = new FileUploadInput(_userContext) { UploadTraceToken = traceToken, ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = memoryStream }; productUploader.Upload(input); var uploadStatus = productUploader.GetUploadStatus(traceToken); var uploadHistory = productUploader.GetHistory(5, 0); Assert.IsNotNull(uploadStatus); Assert.IsNotNull(uploadHistory); foreach (var uploadStage in uploadStatus.UploadStageTrace) { Console.WriteLine("{0} : {1}", uploadStage.Stage, uploadStage.Message); } foreach (var fileInfo in uploadHistory) { Console.WriteLine("{0} : {1}", fileInfo.UploadDate, fileInfo.FilePath); } }
public void FileUpload_ValidFileUploadInputFromExcelFile_UploadsFileToTempLocation() { const string fileName = "AtrendProductTemplate.xlsx"; string tempFileDirectoryPath = Path.Combine(_fileSharePath, "Temp"); string testfilePath = Path.Combine(_fileSharePath, "Test Files", fileName); var fileUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = fileName, InputStream = stream }; FileUploadResult uploadResult = fileUploader.FileUpload(input); Assert.AreEqual(false, uploadResult.ValidationResult.HasViolations); Assert.IsTrue(uploadResult.TempFileName.Contains(fileName)); Assert.IsTrue(uploadResult.TempFilePath.Contains(tempFileDirectoryPath)); }
public void FileUpload_ValidFileUploadInputFromNotExcelFile_ReturnsErrorResultFormatNotSupported() { var fileUploader = EngineContext.Current.Resolve<IProductUploader>(); var input = new FileUploadInput(_userContext) { ContentType = "JPG" }; FileUploadResult uploadResult = fileUploader.FileUpload(input); ValidationError validationError = uploadResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(true, uploadResult.ValidationResult.HasViolations); Assert.AreEqual("JPG format is not supported!", validationError.Message); }
public void FileProcess_ValidFileUploadInputFromExcelFileWithMoreThen10000Rows_ReturnsViolationsDeletesTempFile() { const string FileName = "AtrendProductTemplate.xlsx"; const int MaxProductRowsInFile = 10000; // move to config const int ActualProductRowsInFile = 10002; // move to config string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var fileUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = fileUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = fileUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); ValidationError validationError = processResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(true, processResult.ValidationResult.HasViolations); Assert.AreEqual( string.Format( "Batch size has been exceeded. Maximum allowed size is {0} rows, file provided has: {1} rows", MaxProductRowsInFile, ActualProductRowsInFile), validationError.Message); Assert.AreEqual(false, File.Exists(uploadResult.TempFilePath), "File must be deleted!"); }
public void FileUpload_InValidFileUploadInputExcelWithoutSchema_ReturnsErrorResultInvalidFileFormat() { const string FileName = "RandomExcelFile.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var fileUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = fileUploader.FileUpload(input); ValidationError validationError = uploadResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(true, uploadResult.ValidationResult.HasViolations); Assert.AreEqual("Invalid file structure. Please use approved template!", validationError.Message); }
public void FileProcess_ValidFileProcessInputWithValidRecords_UploadsFileToTempLocation() { const string FileName = "AtrendProductTemplate_Small.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var ProductUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = ProductUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = ProductUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); Assert.AreEqual(false, processResult.ValidationResult.HasViolations); Assert.IsTrue(processResult.FileData.Any()); }
public void FileProcess_ValidFileProcessInputWithSomeColumnsInNumericAndSpecialFormat_ShouldProcessAllAsIfTextFormat() { const string FileName = "AtrendProductTemplate_Small.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var productUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = productUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = productUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); ValidationError validationError = processResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(false, processResult.ValidationResult.HasViolations, validationError.Message); }
public void FileProcess_ValidFileProcessInputWithNoRecords_ReturnsErrorResultFileHasNoRecods() { const string FileName = "AtrendProductTemplate_Empty.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var ProductUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = ProductUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = ProductUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); ValidationError validationError = processResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(true, processResult.ValidationResult.HasViolations); Assert.AreEqual("No records provided. At least one Product required to initiate upload!", validationError.Message); }
public void FileProcess_ValidFileProcessInputWithFullAndEmptyRows_ShouldProcessFullRowsAndIngnoreEmpty() { const string FileName = "AtrendProductTemplate_FullAndSomeEmptyRows.xlsx"; string testfilePath = Path.Combine(_fileSharePath, "Test Files", FileName); var ProductUploader = EngineContext.Current.Resolve<IProductUploader>(); var stream = new FileStream(testfilePath, FileMode.Open, FileAccess.Read); var input = new FileUploadInput(_userContext) { ContentLength = stream.Length, ContentType = "vnd.openxmlformats-officedocument.spreadsheetml.sheet", FileName = FileName, InputStream = stream }; FileUploadResult uploadResult = ProductUploader.FileUpload(input); FileProcessResult<ProductInputRow> processResult = ProductUploader.FileProcess(new FileProcessInput(_userContext) { FileName = uploadResult.TempFileName, FilePath = uploadResult.TempFilePath }); ValidationError validationError = processResult.ValidationResult.ValidationErrors.FirstOrDefault() ?? new ValidationError(); Assert.AreEqual(false, processResult.ValidationResult.HasViolations, validationError.Message); Assert.IsTrue(processResult.FileData.TrueForAll(x => !x.AllStringPropertiesNullOrEmpty()), "Should not process empty rows!"); }
public ActionResult UploadFile(HttpPostedFileBase inputFile) { if (!_permissionService.Authorize(StandardPermissionProvider.ManageProducts)) return AccessDeniedView(); //a vendor cannot import products if (_workContext.CurrentVendor != null) return AccessDeniedView(); if (inputFile == null) throw new ArgumentNullException("inputFile"); _logger.Debug("Upload file"); using (inputFile.InputStream) { // doing it because IE8 sends in full path instead of name var fileName = Path.GetFileName(inputFile.FileName); var userContext = _workContext.GetUserContext(); var uploadTraceToken = Guid.NewGuid().ToString(); // copy to memory and pass it along var memoryStream = new MemoryStream(); inputFile.InputStream.CopyTo(memoryStream); memoryStream.Position = 0; var fileUploadInput = new FileUploadInput(userContext) { UploadTraceToken = uploadTraceToken, ContentLength = inputFile.ContentLength, FileName = fileName, InputStream = memoryStream, ContentType = inputFile.ContentType }; Task.Factory.StartNew(() => EngineContext.Current.Resolve<IProductUploader>().Upload(fileUploadInput)); return View("~/Plugins/Anko.Plugin.Admin.Uploader/Views/Upload/UploadIframe.cshtml", new UploadFileViewModel { UploadTraceToken = uploadTraceToken }); } }