public async void IReport_Download_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");
            byte[] actualContent;
            byte[] expectedContent = { 0x01, 0x02, 0x03 };

            await using (MemoryStream ms = new MemoryStream())
            {
                await report.Download(ms);

                actualContent = ms.ToArray();
            }
            PdfApiMock.Verify(e => e.DownloadFileAsync("a/b/c/file.pdf", null, null), Times.Exactly(1));
            Assert.True(actualContent.SequenceEqual(expectedContent), "Download bytes do not match");

            PdfApiMock.Invocations.Clear();

            await using (MemoryStream ms = new MemoryStream())
            {
                await report.Download(PdfApiMock.Object, ms, "a/b/c/file.pdf", null);

                actualContent = ms.ToArray();
            }

            PdfApiMock.Verify(e => e.DownloadFileAsync("a/b/c/file.pdf", null, null), Times.Exactly(1));
            Assert.True(actualContent.SequenceEqual(expectedContent), "Download bytes do not match");
        }
        public async void IReport_RemoveFile_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            PdfApiMock.Invocations.Clear();

            await report.RemoveFile("a/b/c/file.mock");

            PdfApiMock.Verify(e => e.DeleteFileAsync("a/b/c/file.mock", null, null));
        }
        public async void IReport_RemoveFolder_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            PdfApiMock.Invocations.Clear();

            await report.RemoveFolder("mock_test");

            PdfApiMock.Verify(e => e.DeleteFolderAsync("a/b/c/mock_test", null, It.IsAny <bool?>()));
        }
        public async void IReport_CreateFolderPath_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            PdfApiMock.Invocations.Clear();

            await report.CreateFolderPath("1/2/3/mock_test");

            PdfApiMock.Verify(e => e.CreateFolderAsync("1/2/3/mock_test", null));
        }
        internal async Task <PdfReport.PdfReportPageProcessor> GetPageProcessor()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            report._defaultFont = new Font()
            {
                Name  = "Arial",
                Size  = 10,
                Style = "regular"
            };
            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            return(new PdfReport.PdfReportPageProcessor(report, "file_01.pdf", "a/b/c"));
        }
        public async void IReport_Configure_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            PdfApiMock.Verify(e => e.CreateFolderAsync("a", null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.CreateFolderAsync("a/b", null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.CreateFolderAsync("a/b/c", null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.CreateFolderAsync("a/b/c/tmp_file.pdf", null), Times.Once);

            PdfApiMock.Verify(e => e.ObjectExistsAsync("a", null, null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.ObjectExistsAsync("a/b", null, null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.ObjectExistsAsync("a/b/c", null, null), Times.Exactly(2));
            PdfApiMock.Verify(e => e.ObjectExistsAsync("a/b/c/tmp_file.pdf", null, null), Times.Once);
        }
        public async void IReport_ReportMultiple_Tests()
        {
            PdfReport report = new PdfReport("a/b/c/file.pdf");

            Assert.True(await report.Configure(PdfApiMock.Object, BarcodeMock.Object), "Configure should succeed");

            var result = await report.Report(new Report.Model.Document()
            {
                DefaultFont = new Font
                {
                    Name  = "name1",
                    Size  = 10,
                    Style = "italic"
                },
                Content = new List <ContentObject>()
                {
                    new ContentObject
                    {
                        Page = new List <PageContentItem>()
                        {
                            new PageContentItem()
                            {
                                Text     = "mock text",
                                Location = new Location()
                                {
                                    Left = 10, Top = 20, Right = 300, Bottom = 400
                                }
                            }, new PageContentItem()
                            {
                                Url      = "file://issue-link-qr?link=123",
                                Location = new Location()
                                {
                                    Left = 50, Top = 60, Right = 700, Bottom = 800
                                }
                            }, new PageContentItem()
                            {
                                Rows = new List <TableRow>()
                                {
                                    new TableRow()
                                    {
                                        Cells = new List <TableCell>()
                                        {
                                            new TableCell()
                                            {
                                                Text = "cell 11"
                                            },
                                            new TableCell()
                                            {
                                                Text = "cell 12"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }, new ContentObject
                    {
                        Page = new List <PageContentItem>()
                        {
                            new PageContentItem()
                            {
                                Text     = "mock text2",
                                Location = new Location()
                                {
                                    Left = 10, Top = 20, Right = 300, Bottom = 400
                                }
                            }, new PageContentItem()
                            {
                                Url      = "file://issue-link-qr?link=123",
                                Location = new Location()
                                {
                                    Left = 50, Top = 60, Right = 700, Bottom = 800
                                }
                            }, new PageContentItem()
                            {
                                Rows = new List <TableRow>()
                                {
                                    new TableRow()
                                    {
                                        Cells = new List <TableCell>()
                                        {
                                            new TableCell()
                                            {
                                                Text = "cell 11-1"
                                            },
                                            new TableCell()
                                            {
                                                Text = "cell 12-1"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });

            Assert.True(result, "Invalid Report result");
            Assert.Equal("name1", report._defaultFont.Name);
            Assert.Equal(10, report._defaultFont.Size);
            Assert.Equal("italic", report._defaultFont.Style);

            PdfApiMock.Verify(e => e.PutCreateDocumentAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), null, "a/b/c/tmp_file.pdf"), Times.Exactly(2));

            PdfApiMock.Verify(e => e.PostDocumentTextHeaderAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), It.Is <TextHeader>(h =>
                                                                                                                       Regex.IsMatch(h.Value, "Generated.*by Aspose.PDF Exporter"))
                                                                 , It.IsAny <int?>(), It.IsAny <int?>(), null, "a/b/c/tmp_file.pdf"), Times.Exactly(2));


            PdfApiMock.Verify(e => e.PostDocumentTextHeaderAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), It.Is <TextHeader>(h =>
                                                                                                                       Regex.IsMatch(h.Value, "Generated.*by Aspose.PDF Exporter"))
                                                                 , It.IsAny <int?>(), It.IsAny <int?>(), null, "a/b/c/tmp_file.pdf"), Times.Exactly(2));
            PdfApiMock.Verify(e => e.PostDocumentTextFooterAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), It.Is <TextFooter>(h =>
                                                                                                                       Regex.IsMatch(h.Value, "Powered by Aspose.PDF for Cloud, Aspose.Barcode for Cloud"))
                                                                 , It.IsAny <int?>(), It.IsAny <int?>(), null, "a/b/c/tmp_file.pdf"), Times.Exactly(2));

            PdfApiMock.Verify(e => e.PutAddTextAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), 1, It.Is <Paragraph>(p =>
                                                                                                             p.Lines.Exists(l => l.Segments.Exists(s => s.Value == "mock text")) &&
                                                                                                             IsEqual(p.Rectangle.LLX, 10) && IsEqual(p.Rectangle.LLY, 440) && IsEqual(p.Rectangle.URX, 300) && IsEqual(p.Rectangle.URY, 820)
                                                                                                             ), "a/b/c/tmp_file.pdf", null), Times.Once);
            PdfApiMock.Verify(e => e.PutAddTextAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), 1, It.Is <Paragraph>(p =>
                                                                                                             p.Lines.Exists(l => l.Segments.Exists(s => s.Value == "mock text2")) &&
                                                                                                             IsEqual(p.Rectangle.LLX, 10) && IsEqual(p.Rectangle.LLY, 440) && IsEqual(p.Rectangle.URX, 300) && IsEqual(p.Rectangle.URY, 820)
                                                                                                             ), "a/b/c/tmp_file.pdf", null), Times.Once);


            PdfApiMock.Verify(e => e.PostInsertImageAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), 1
                                                          , It.Is <double>(m => IsEqual(m, 50))
                                                          , It.Is <double>(m => IsEqual(m, 40))
                                                          , It.Is <double>(m => IsEqual(m, 700))
                                                          , It.Is <double>(m => IsEqual(m, 780))
                                                          , It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), null, "a/b/c/tmp_file.pdf", It.IsAny <Stream>()), Times.Exactly(2));

            PdfApiMock.Verify(e => e.PostPageTablesAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), 1, It.Is <List <Table> >(ts =>
                                                                                                                     ts.Count == 1 && ts[0].Rows.Count == 1 &&
                                                                                                                     ts[0].Rows[0].Cells[0].Paragraphs.Count == 1 && ts[0].Rows[0].Cells[0].Paragraphs[0].Text == "cell 11" &&
                                                                                                                     ts[0].Rows[0].Cells[1].Paragraphs.Count == 1 && ts[0].Rows[0].Cells[1].Paragraphs[0].Text == "cell 12"
                                                                                                                     ), null, "a/b/c/tmp_file.pdf"), Times.Once);
            PdfApiMock.Verify(e => e.PostPageTablesAsync(It.IsRegex("[-0-9A-Fa-f]*\\.pdf"), 1, It.Is <List <Table> >(ts =>
                                                                                                                     ts.Count == 1 && ts[0].Rows.Count == 1 &&
                                                                                                                     ts[0].Rows[0].Cells[0].Paragraphs.Count == 1 && ts[0].Rows[0].Cells[0].Paragraphs[0].Text == "cell 11-1" &&
                                                                                                                     ts[0].Rows[0].Cells[1].Paragraphs.Count == 1 && ts[0].Rows[0].Cells[1].Paragraphs[0].Text == "cell 12-1"
                                                                                                                     ), null, "a/b/c/tmp_file.pdf"), Times.Once);

            PdfApiMock.Verify(e => e.PutMergeDocumentsAsync("file.pdf", It.Is <MergeDocuments>(f =>
                                                                                               f.List.Count == 2), null, "a/b/c"), Times.Once);
        }
示例#8
0
        public async Task <IActionResult> ExportIssues([FromForm(Name = "issues")] List <string> issuesList, [FromForm(Name = "includeqr")] bool includeQRCode
                                                       , [FromHeader(Name = "Referer")] string referer, [FromHeader(Name = "x-real-ip")] string realIp, [FromHeader(Name = "User-Agent")] string userAgent
                                                       , [FromHeader(Name = "x-forwarded-for")] string forwardedFor)
        {
            IActionResult result          = null;
            DateTime      requestDateTime = DateTime.Now;
            TaskMeasurer  taskMeasurer    = new TaskMeasurer();
            string        extension       = "pdf";

            Model.ClientRegistration registrationData = _client.RegistrationData;
            string fileId         = Guid.NewGuid().ToString();
            string reportFileName = $"{_configuration.GetValue<string>("Settings:StorageRoot", "clients_jiracloud")}/{registrationData.ClientKey}/{fileId}.{extension}";

            JArray  fields = null;
            JObject issues = null;
            Dictionary <string, JArray> epicStories = new Dictionary <string, JArray>();

            Report.Model.Document      document             = null;
            Model.ReportFile           reportFile           = null;
            ReportJiraCloudModel       reportJiraCloudModel = null;
            List <StatisticalDocument> statItems            = new List <StatisticalDocument>();

            try
            {
                _logger.LogInformation($"{requestDateTime} New job ClientKey {registrationData.ClientKey}, issues {String.Join(", ", issuesList)}");
                HttpClient httpCli = _clientFactory.CreateClient("jira_client");
                httpCli.BaseAddress = new Uri(registrationData.BaseUrl);
                RestApiClient cli = new RestApiClient(registrationData.Key, registrationData.SharedSecret, registrationData.ClientKey, httpCli);

                fields = (JArray)JsonConvert.DeserializeObject(await taskMeasurer.Run(() => cli.Get($"/rest/api/3/field"), "000_FetchFields"));
                var EpicNameField = getField(fields, "com.pyxis.greenhopper.jira:gh-epic-label");


                string[] responses = await taskMeasurer.Run(() => Task.WhenAll(issuesList.Select(i => cli.Get($"/rest/api/3/issue/{i}"))), "111_FetchIssuesData");

                PdfReport pdfReport = new PdfReport(filePath: reportFileName, storageName: _configuration.GetValue <string>("Settings:StorageName"), debug: _hostEnvironment.IsDevelopment());
                await pdfReport.Configure(_client.PdfApi, _client.BarcodeApi);

                issues = JToken.FromObject(new
                {
                    issues = responses.Select(JsonConvert.DeserializeObject).ToList()
                }) as JObject;

                // get stories for epics
                epicStories = new Dictionary <string, JArray>();
                if (!string.IsNullOrEmpty(EpicNameField))
                {
                    var issuesArr = await Task.WhenAll(issues["issues"]
                                                       .Where(i => !string.IsNullOrEmpty(i.SelectToken($"$.fields.{EpicNameField}")?.ToString()))
                                                       .Select(async i => KeyValuePair.Create(i.SelectToken($"$.key")?.ToString(), await getSubtasksForEpic(cli, i.SelectToken($"$.key")?.ToString()))
                                                               ));

                    epicStories = issuesArr.ToDictionary(t => t.Key, t => t.Value);
                }

                document = taskMeasurer.RunSync(() =>
                {
                    reportJiraCloudModel = new ReportJiraCloudModel(System.IO.File.ReadAllText(
                                                                        _configuration.GetValue("Templates:ReportIssuesModel",
                                                                                                "template/Report-Issues.Mustache")))
                    {
                        EpicLinkField  = getField(fields, "com.pyxis.greenhopper.jira:gh-epic-link"),
                        EpicNameField  = EpicNameField,
                        GenerateQRCode = includeQRCode
                    };
                    return(reportJiraCloudModel.CreateReportModel(reportJiraCloudModel.issuesModel(issues, epicStories)));
                }, "112_PrepareReportModel");

                if (null == document.Options)
                {
                    document.Options = new Report.Model.DocumentOptions();
                }
                await pdfReport.Report(document);


                DateTime current = DateTime.Now;
                reportFile = new Model.ReportFile
                {
                    UniqueId        = $"{Guid.NewGuid()}",
                    ReportType      = extension,
                    ContentType     = "application/pdf",
                    FileName        = issuesList.Count == 1 ? $"{issuesList.First()}.{extension}" : $"Issues.{extension}",
                    StorageFileName = reportFileName,
                    ClientId        = registrationData.Id,
                    Created         = current,
                    Expired         = current.AddHours(_configuration.GetValue("Settings:FileExpirationHours", 24)),
                };
                _dbContext.ReportFile.Add(reportFile);
                statItems = taskMeasurer.Stat.Concat(pdfReport.Stat).ToList();

                await _dbContext.SaveChangesAsync();

                _logger.LogInformation($"{current} Finished {registrationData.ClientKey} in {DateTime.Now - requestDateTime}");
                return(result = new OkObjectResult(new {
                    fileid = reportFile.UniqueId
                    , downloadlink = _basePathReplacement.ReplaceBaseUrl(Url.Link("GetDownload", new { id = reportFile.UniqueId }))
                    , expText = TimeSpan.FromHours(_configuration.GetValue("Settings:FileExpirationHours", 24)).ToReadableString()
                    , exp = reportFile.Expired
                }));
            }
            catch (Exception ex)
            {
                ZipFileArchive archive = new ZipFileArchive().AddFile("010_request_params.json", new
                {
                    RequestId = _client.RequestId,
                    FileId    = fileId,
                    FileName  = reportFileName,
                    includeQRCode, referer, realIp, userAgent, forwardedFor,
                    issues = issuesList
                });
                foreach (var f in new Dictionary <string, object> {
                    { "020_registration.json", registrationData },
                    { "030_fields.json", fields },
                    { "040_issues.json", issues },
                    { "050_epic_stories.json", epicStories },
                    { "051_RenderedDocument.yaml", reportJiraCloudModel?.RenderedYamlDocument },
                    { "052_RenderedJsonDocument.yaml", reportJiraCloudModel?.RenderedJsonDocument },
                    { "060_document.json", document },
                    { "070_report_file.json", reportFile },
                    { "080_result.json", result },
                }.ToArray())
                {
                    archive.AddFile(f.Key, f.Value);
                }
                throw new ControllerException($"Error generating {reportFileName}", innerException: ex, customData: await archive.Archive());
            }
            finally
            {
                _client.Stat = statItems;
            }
        }