public void FileIssueAsync_NoRuleIsSpecified_SetsCorrectTelemetry()
        {
            IssueInformation expectedIssueInformation = new IssueInformation();
            IssueInformation actualIssueInformation   = null;

            List <PropertyBag> capturedTelemetry = CaptureTelemetryEvents(TelemetryAction.Issue_File_Attempt.ToString());

            Mock <IIssueResult> issueResultMock = new Mock <IIssueResult>(MockBehavior.Strict);

            issueResultMock.Setup(x => x.IssueLink).Returns <Uri>(null);

            IssueReporter.TestControlledIsEnabled      = true;
            IssueReporter.TestControlledDisplayName    = DISPLAY_NAME;
            IssueReporter.TestControlledFileIssueAsync = (issueInformation) =>
            {
                actualIssueInformation = issueInformation;
                return(issueResultMock.Object);
            };

            IIssueResult result = FileIssueAction.FileIssueAsync(expectedIssueInformation);

            Assert.AreSame(issueResultMock.Object, result);
            Assert.AreSame(expectedIssueInformation, actualIssueInformation);
            Assert.AreEqual(1, capturedTelemetry.Count);
            Assert.AreEqual(DISPLAY_NAME, capturedTelemetry[0][TelemetryProperty.IssueReporter.ToString()]);

            _telemetrySinkMock.VerifyAll();
            issueResultMock.VerifyAll();
        }
示例#2
0
 /// <summary>
 /// Truncate key fields from the input IssueInformation and return a revised object
 ///     certain values are truncated to {length} characters long,
 ///     certain values are formatted to be more readable
 /// </summary>
 /// <param name="issueInfo">Non-truncated information from caller</param>
 /// <param name="issueFieldPairs">The collection of IssueField/string pairs to truncate</param>
 /// <returns></returns>
 private static void TruncateSelectedFields(IssueInformation issueInfo, IDictionary <IssueField, string> issueFieldPairs)
 {
     issueFieldPairs[IssueField.ProcessName]  = TruncateString(issueInfo.ProcessName, 50, ".exe");
     issueFieldPairs[IssueField.Glimpse]      = TruncateString(issueInfo.Glimpse, 50);
     issueFieldPairs[IssueField.TestMessages] = TruncateString(issueInfo.TestMessages, 150, Properties.Resources.ConcatenationMessage);
     issueFieldPairs[IssueField.RuleSource]   = RemoveSurroundingBrackets(issueInfo.RuleSource);
 }
示例#3
0
        public void FileNewIssue_FieldsAreValid_ReturnsExpectedData()
        {
            AzureDevOps.Models.AdoTeam expectedAdoTeam = new AzureDevOps.Models.AdoTeam(testTeamName, Guid.Empty);
            IReadOnlyDictionary <AzureDevOpsField, string> actualFields = null;

            var connInfo = new ConnectionInfo(new Uri("https://accessibilityinsights.io"),
                                              new AzureDevOps.Models.TeamProject(testProjectName, Guid.Empty), expectedAdoTeam);

            _adoIntegrationMock.Setup(x => x.GetAreaPath(connInfo))
            .Returns(testArea);
            _adoIntegrationMock.Setup(x => x.GetIteration(connInfo))
            .Returns(testIteration);
            _adoIntegrationMock.Setup(x => x.CreateIssuePreview(testProjectName, testTeamName, It.IsAny <IReadOnlyDictionary <AzureDevOpsField, string> >()))
            .Callback <string, string, IReadOnlyDictionary <AzureDevOpsField, string> >((_, __, fields) => actualFields = fields)
            .Returns(new Uri("https://www.bing.com"));

            var issueInfo = new IssueInformation(internalGuid: testIssueGuid);
            var output    = _fileIssueHelpers.FileNewIssueTestable(issueInfo,
                                                                   connInfo, false, 0, (_) => { }, testIssueId);

            Assert.AreEqual(testIssueId, output.issueId);
            Assert.IsNotNull(output.newIssueId);
            Assert.AreEqual(testIssueGuidString, output.newIssueId);
            Assert.AreEqual(5, actualFields.Count);
            Assert.IsFalse(string.IsNullOrEmpty(actualFields[AzureDevOpsField.Title]));
            Assert.IsFalse(string.IsNullOrEmpty(actualFields[AzureDevOpsField.Tags]));
            Assert.IsFalse(string.IsNullOrEmpty(actualFields[AzureDevOpsField.ReproSteps]));
            Assert.AreEqual(testArea, actualFields[AzureDevOpsField.AreaPath]);
            Assert.AreEqual(testIteration, actualFields[AzureDevOpsField.IterationPath]);
            _adoIntegrationMock.VerifyAll();
        }
 /// <summary>
 /// Truncate key fields from the input IssueInformation and return a revised object
 ///     certain values are truncated to {length} characters long,
 ///     certain values are formatted to be more readable
 /// </summary>
 /// <param name="issueInfo">Non-truncated information from caller</param>
 /// <param name="issueFieldPairs">The collection of IssueField/string pairs to truncate</param>
 /// <returns></returns>
 private static void TruncateSelectedFields(IssueInformation issueInfo, IDictionary <IssueField, string> issueFieldPairs)
 {
     issueFieldPairs[IssueField.ProcessName]  = TruncateString(issueInfo.ProcessName, 50, ".exe");
     issueFieldPairs[IssueField.Glimpse]      = TruncateString(issueInfo.Glimpse, 50);
     issueFieldPairs[IssueField.TestMessages] = TruncateString(issueInfo.TestMessages, 150, "...open attached A11y test file for full details.");
     issueFieldPairs[IssueField.RuleSource]   = RemoveSurroundingBrackets(issueInfo.RuleSource);
 }
        /// <summary>
        /// Testable version of FileNewIssue, allows caller to specify an issueId instead of going off-box
        /// </summary>
        internal (int?issueId, string newIssueId) FileNewIssueTestable(IssueInformation issueInfo, ConnectionInfo connection, bool onTop, int zoomLevel, Action <int> updateZoom, int?testIssueId)
        {
            if (issueInfo == null)
            {
                throw new ArgumentNullException(nameof(issueInfo));
            }

            try
            {
                // Create a A11y-specific Guid for this issue to verify that we are uploading
                //  attachment to the correct issue
                var a11yIssueId = issueInfo.InternalGuid.HasValue
                    ? issueInfo.InternalGuid.Value.ToString()
                    : string.Empty;
                Uri url = CreateIssuePreviewAsync(connection, issueInfo).Result;

                int?issueId = testIssueId.HasValue
                    ? testIssueId.Value
                    : FileIssueWindow(url, onTop, zoomLevel, updateZoom);

                return(issueId, a11yIssueId);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception e)
            {
                e.ReportException();
                return(null, string.Empty);
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }
示例#6
0
        public void CreateIssuePreviewAsync_TeamNameIsNotNull_ChainsThroughCorrectly()
        {
            using (ShimsContext.Create())
            {
                const string expectedProjectName = "Ultra Project";
                const string expectedTeamName    = "Ultra Team";
                string       actualProjectName   = null;
                string       actualTeamName      = null;
                Uri          expectedUri         = new Uri("https://www.bing.com");

                AzureDevOpsIntegration integration = new ShimAzureDevOpsIntegration
                {
                    CreateIssuePreviewStringStringIReadOnlyDictionaryOfAzureDevOpsFieldString = (p, t, f) =>
                    {
                        actualProjectName = p;
                        actualTeamName    = t;
                        return(expectedUri);
                    },
                    ConnectedToAzureDevOpsGet = () => true,
                };

                ShimAzureDevOpsIntegration.GetCurrentInstance = () => integration;

                ConnectionInfo connectionInfo = new ConnectionInfo(expectedUri,
                                                                   new TeamProject(expectedProjectName, Guid.Empty),
                                                                   new Team(expectedTeamName, Guid.Empty));
                IssueInformation issueInfo = new IssueInformation();

                Uri actualUri = FileIssueHelpers.CreateIssuePreviewAsync(connectionInfo, issueInfo).Result;

                Assert.AreEqual(expectedUri, actualUri);
                Assert.AreEqual(expectedProjectName, actualProjectName);
                Assert.AreEqual(expectedTeamName, actualTeamName);
            }
        }
示例#7
0
        public void IssueFormattingTest()
        {
            string           link = "https://github.com/bla/bla-blas";
            IssueInformation singleFailureIssue = new IssueInformation(null, "glimpse", null,
                                                                       new Uri("https://www.helpUri.com"), "ruleSource", "ruleDescription",
                                                                       "testMessages", null, null,
                                                                       "elementPath", null, null,
                                                                       "processName", IssueType.SingleFailure, null);

            IssueInformation noFailureIssue = new IssueInformation(null, "glimpse", null,
                                                                   new Uri("https://www.helpUri.com"), "ruleSource", "ruleDescription",
                                                                   "testMessages", null, null,
                                                                   "elementPath", null, null,
                                                                   "processName", IssueType.NoFailure, null);

            IIssueFormatter singleIssueFormatter = new SingleFailureIssueFormatter(singleFailureIssue);
            IIssueFormatter noIssueFormatter     = new NoFailuresIssueFormatter(noFailureIssue);

            string singleFailureLinkActual   = IssueFormatterFactory.GetNewIssueLink(link, singleFailureIssue);
            string singleFailureLinkExpected = GetLink(link, singleIssueFormatter);
            string noFailureLinkActual       = IssueFormatterFactory.GetNewIssueLink(link, noFailureIssue);
            string noFailureLinkExpected     = GetLink(link, noIssueFormatter);

            Assert.AreEqual(singleFailureLinkExpected, singleFailureLinkActual);
            Assert.AreEqual(noFailureLinkExpected, noFailureLinkActual);
            Assert.AreNotEqual(singleFailureLinkExpected, noFailureLinkActual);
            Assert.AreNotEqual(noFailureLinkExpected, singleFailureLinkActual);
        }
        public static string GetNewIssueLink(string link, IssueInformation issueInfo)
        {
            IIssueFormatter formatter = null;

            switch (issueInfo.IssueType)
            {
            case IssueType.NoFailure:
                formatter = new NoFailuresIssueFormatter(issueInfo);
                break;

            case IssueType.SingleFailure:
                formatter = new SingleFailureIssueFormatter(issueInfo);
                break;

            default:
                return(string.Empty);
            }

            string FormattedURL = string.Format(CultureInfo.InvariantCulture, Properties.Resources.FormattedLink,
                                                link,
                                                formatter.GetFormattedTitle(),
                                                formatter.GetFormattedBody());
            string escapedURL = Uri.EscapeUriString(FormattedURL).Replace("#", "%23");

            return(escapedURL);
        }
示例#9
0
        public void TestBugFilingTelemetrySpecificRule()
        {
            using (ShimsContext.Create())
            {
                SetUpShims();

                ShimIssueReporter.FileIssueAsyncIssueInformation = (_) =>
                {
                    var mockIssueResult = new Mock <IIssueResult>();
                    mockIssueResult.Setup(p => p.DisplayText).Returns("Issue Display text");
                    mockIssueResult.Setup(p => p.IssueLink).Returns(new Uri("https://www.google.com"));
                    return(mockIssueResult.Object);
                };

                // Save telemetry locally
                List <Tuple <TelemetryAction, IReadOnlyDictionary <TelemetryProperty, string> > > telemetryLog = new List <Tuple <TelemetryAction, IReadOnlyDictionary <TelemetryProperty, string> > >();
                ShimLogger.PublishTelemetryEventTelemetryActionIReadOnlyDictionaryOfTelemetryPropertyString = (action, dict) =>
                {
                    telemetryLog.Add(new Tuple <TelemetryAction, IReadOnlyDictionary <TelemetryProperty, string> >(action, dict));
                };

                var issueInfo = new IssueInformation(ruleForTelemetry: RuleId.BoundingRectangleContainedInParent.ToString());
                var result    = FileIssueAction.FileIssueAsync(issueInfo);

                Assert.AreEqual(RuleId.BoundingRectangleContainedInParent.ToString(), telemetryLog[0].Item2[TelemetryProperty.RuleId]);
                Assert.AreEqual("", telemetryLog[0].Item2[TelemetryProperty.UIFramework]);
                Assert.AreEqual(2, telemetryLog[0].Item2.Count);
            }
        }
        public void FileIssueAsync_RuleIsSpecified_SetsCorrectTelemetry()
        {
            const string expectedRule = "An awesome rule";

            IssueInformation expectedIssueInformation = new IssueInformation(ruleForTelemetry: expectedRule);
            IssueInformation actualIssueInformation   = null;

            List <PropertyBag> capturedTelemetry = CaptureTelemetryEvents(TelemetryAction.Issue_Save.ToString());

            Mock <IIssueResult> issueResultMock = new Mock <IIssueResult>(MockBehavior.Strict);

            issueResultMock.Setup(x => x.IssueLink).Returns(new Uri("https://AccessibilityInsights.io"));

            IssueReporter.TestControlledIsEnabled      = true;
            IssueReporter.TestControlledDisplayName    = DISPLAY_NAME;
            IssueReporter.TestControlledFileIssueAsync = (issueInformation) =>
            {
                actualIssueInformation = issueInformation;
                return(issueResultMock.Object);
            };

            IIssueResult result = FileIssueAction.FileIssueAsync(expectedIssueInformation);

            Assert.AreEqual(3, capturedTelemetry[0].Count);
            Assert.AreEqual(expectedRule, capturedTelemetry[0][TelemetryProperty.RuleId.ToString()]);
            Assert.AreEqual("", capturedTelemetry[0][TelemetryProperty.UIFramework.ToString()]);
            Assert.AreEqual(DISPLAY_NAME, capturedTelemetry[0][TelemetryProperty.IssueReporter.ToString()]);

            _telemetrySinkMock.VerifyAll();
            issueResultMock.VerifyAll();
        }
        /// <summary>
        /// Attaches screenshot and results file to existing issue
        /// Default case - resulting test file will open in A11yFileMode.Inspect mode,
        ///     no additional loading parameters needed
        /// </summary>
        /// <param name="rect">Bounding rect of element for screenshot</param>
        /// <param name="a11yIssueId">Issue's A11y-specific id</param>
        /// <param name="issueId">Issue's server-side id</param>
        /// <returns>Success or failure</returns>
        internal async Task <bool> AttachIssueData(IssueInformation issueInfo, string a11yIssueId, int issueId)
        {
            if (issueInfo == null)
            {
                throw new ArgumentNullException(nameof(issueInfo));
            }

            return(await AttachIssueDataInternal(issueInfo.TestFileName, issueInfo.Screenshot, a11yIssueId, issueId).ConfigureAwait(false));
        }
        public void FileBug(HierarchyNodeViewModel vm = null)
        {
            vm = vm ?? this.treeviewHierarchy.SelectedItem as HierarchyNodeViewModel;

            if (vm == null)
            {
                MessageDialog.Show(Properties.Resources.HierarchyControl_FileBug_Could_not_find_the_selected_item__the_bug_filing_is_canceled);
                return;
            }

            if (vm.IssueLink != null)
            {
                // Bug already filed, open it in a new window
                try
                {
                    System.Diagnostics.Process.Start(vm.IssueLink.OriginalString);
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
                {
                    ex.ReportException();
                    // Happens when bug is deleted, message describes that work item doesn't exist / possible permission issue
                    MessageDialog.Show(ex.InnerException?.Message);
                    vm.IssueDisplayText = null;
                }
#pragma warning restore CA1031 // Do not catch general exception types
            }
            else
            {
                // File a new bug
                var telemetryEvent = TelemetryEventFactory.ForIssueFilingRequest(FileBugRequestSource.Hierarchy);
                Logger.PublishTelemetryEvent(telemetryEvent);

                if (IssueReporter.IsConnected)
                {
                    IssueInformation issueInformation = this.SelectedElement.GetIssueInformation(IssueType.NoFailure);
                    FileIssueAction.AttachIssueData(issueInformation, this.ElementContext.Id, this.SelectedElement.BoundingRectangle,
                                                    this.SelectedElement.UniqueId);
                    IIssueResult issueResult = FileIssueAction.FileIssueAsync(issueInformation);
                    if (issueResult != null)
                    {
                        vm.IssueDisplayText = issueResult.DisplayText;
                        vm.IssueLink        = issueResult.IssueLink;
                    }
                    File.Delete(issueInformation.TestFileName);
                }
                else
                {
                    bool?accepted = MessageDialog.Show(Properties.Resources.HierarchyControl_FileIssue_Configure);
                    if (accepted.HasValue && accepted.Value)
                    {
                        this.HierarchyActions.SwitchToServerLogin();
                    }
                }
            }
        }
        public void FileBug(HierarchyNodeViewModel vm = null)
        {
            vm = vm ?? this.treeviewHierarchy.SelectedItem as HierarchyNodeViewModel;

            if (vm == null)
            {
                MessageDialog.Show(Properties.Resources.HierarchyControl_FileBug_Could_not_find_the_selected_item__the_bug_filing_is_canceled);
                return;
            }

            if (vm.IssueLink != null)
            {
                // Bug already filed, open it in a new window
                try
                {
                    System.Diagnostics.Process.Start(vm.IssueLink.OriginalString);
                }
                catch (Exception ex)
                {
                    // Happens when bug is deleted, message describes that work item doesn't exist / possible permission issue
                    MessageDialog.Show(ex.InnerException?.Message);
                    vm.IssueDisplayText = null;
                }
            }
            else
            {
                // File a new bug
                Logger.PublishTelemetryEvent(TelemetryAction.Scan_File_Bug, new Dictionary <TelemetryProperty, string>
                {
                    { TelemetryProperty.By, FileBugRequestSource.Hierarchy.ToString() },
                    { TelemetryProperty.IsAlreadyLoggedIn, IssueReporter.IsConnected.ToString(CultureInfo.InvariantCulture) },
                });

                if (IssueReporter.IsConnected)
                {
                    IssueInformation issueInformation = this.SelectedElement.GetIssueInformation(IssueType.NoFailure);
                    FileIssueAction.AttachIssueData(issueInformation, this.ElementContext.Id, this.SelectedElement.BoundingRectangle,
                                                    this.SelectedElement.UniqueId);
                    IIssueResult issueResult = FileIssueAction.FileIssueAsync(issueInformation);
                    if (issueResult != null)
                    {
                        vm.IssueDisplayText = issueResult.DisplayText;
                        vm.IssueLink        = issueResult.IssueLink;
                    }
                    File.Delete(issueInformation.TestFileName);
                }
                else
                {
                    bool?accepted = MessageDialog.Show(Properties.Resources.HierarchyControl_FileIssue_Configure);
                    if (accepted.HasValue && accepted.Value)
                    {
                        this.HierarchyActions.SwitchToServerLogin();
                    }
                }
            }
        }
示例#14
0
        /// <summary>
        /// Attaches screenshot and results file to existing issue
        /// Default case - resulting test file will open in A11yFileMode.Inspect mode,
        ///     no additional loading parameters needed
        /// </summary>
        /// <param name="issueInformation"> Issue information object that needs to be populated with attachments</param>
        /// <param name="ecId">Element context id</param>
        /// <param name="rect">Bounding rect of element for screenshot</param>
        /// <param name="elId">Element unique id</param>
        /// <returns>Success or failure</returns>
        public static void AttachIssueData(IssueInformation issueInformation, Guid ecId, Rectangle?rect, int?elId)
        {
            // Save snapshot locally in prep for uploading attachment
            var snapshotFileName = GetTempFileName(FileFilters.TestExtension);

            // when the file is open, it will be open in Inspect view, not Test view.
            SaveAction.SaveSnapshotZip(snapshotFileName, ecId, elId, Axe.Windows.Desktop.Settings.A11yFileMode.Inspect);
            issueInformation.Screenshot   = GetScreenShotForIssueDescription(ecId, rect);
            issueInformation.TestFileName = snapshotFileName;
        }
 /// <summary>
 /// Extract the template name from an IssueInformation object
 /// </summary>
 /// <param name="issueInfo"></param>
 /// <returns>The name of the template</returns>
 private static string GetTemplateName(IssueInformation issueInfo)
 {
     if (issueInfo.IssueType.HasValue)
     {
         switch (issueInfo.IssueType.Value)
         {
         case IssueType.SingleFailure: return("IssueSingleFailure");
         }
     }
     return("IssueNoFailures");
 }
示例#16
0
        public void FileNewBug_IsNotEnabled_ReturnsNull()
        {
            using (ShimsContext.Create())
            {
                ShimIssueReporter.IsEnabledGet = () => false;
                var issueInfo = new IssueInformation();
                var output    = FileIssueAction.FileIssueAsync(issueInfo);

                Assert.IsNull(output);
            }
        }
示例#17
0
 public static IIssueResult FileIssueAsync(IssueInformation issueInformation)
 {
     if (IsEnabled && IsConnected)
     {
         // Coding to the agreement that FileIssueAsync will return a kicked off task.
         // This will block the main thread.
         // It does seem like we currently block the main thread when we show the win form for azure devops
         // so keeping it as is till we have a discussion. Check for blocking behavior at that link.
         // https://github.com/Microsoft/accessibility-insights-windows/blob/master/src/AccessibilityInsights.SharedUx/Controls/HierarchyControl.xaml.cs#L858
         return(IssueReporting.FileIssueAsync(issueInformation).Result);
     }
     return(null);
 }
示例#18
0
        public Task <IIssueResultWithPostAction> FileIssueAsync(IssueInformation issueInfo)
        {
            bool topMost = false;

            Application.Current.Dispatcher.Invoke(() => topMost = Application.Current.MainWindow.Topmost);

            Action <int> updateZoom = (int x) => Configuration.ZoomLevel = x;

            (int?issueId, string newIssueId) = _fileIssueHelpers.FileNewIssue(issueInfo, Configuration.SavedConnection,
                                                                              topMost, Configuration.ZoomLevel, updateZoom, this.ConfigurationPath);

            return(Task.Run <IIssueResultWithPostAction>(() =>
            {
                // Check whether issue was filed once dialog closed & process accordingly
                if (!issueId.HasValue)
                {
                    return null;
                }

                try
                {
                    if (!_fileIssueHelpers.AttachIssueData(issueInfo, newIssueId, issueId.Value).Result)
                    {
                        return new IssueResultWithPostAction()
                        {
                            DisplayText = null,
                            IssueLink = null,
                            PostAction = () =>
                            {
                                MessageDialog.Show(Properties.Resources.There_was_an_error_identifying_the_created_issue_This_may_occur_if_the_ID_used_to_create_the_issue_is_removed_from_its_Azure_DevOps_description_Attachments_have_not_been_uploaded);
                            },
                        };
                    }

                    return new IssueResultWithPostAction()
                    {
                        DisplayText = issueId.ToString(),
                        IssueLink = _devOpsIntegration.GetExistingIssueUrl(issueId.Value),
                        PostAction = null,
                    };
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception e)
                {
                    e.ReportException();
                }
#pragma warning restore CA1031 // Do not catch general exception types

                return null;
            }));
        }
示例#19
0
        /// <summary>
        /// Handles click on file bug button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFileBug_Click(object sender, RoutedEventArgs e)
        {
            var vm = ((Button)sender).Tag as RuleResultViewModel;

            if (vm.IssueLink != null)
            {
                // Bug already filed, open it in a new window
                try
                {
                    Process.Start(vm.IssueLink.OriginalString);
                }
#pragma warning disable CA1031 // Do not catch general exception types
                catch (Exception ex)
                {
                    ex.ReportException();
                    // Happens when bug is deleted, message describes that work item doesn't exist / possible permission issue
                    MessageDialog.Show(ex.InnerException?.Message);
                    vm.IssueDisplayText = null;
                }
#pragma warning restore CA1031 // Do not catch general exception types
            }
            else
            {
                // File a new bug
                var telemetryEvent = TelemetryEventFactory.ForIssueFilingRequest(FileBugRequestSource.AutomatedChecks);
                Logger.PublishTelemetryEvent(telemetryEvent);

                if (IssueReporter.IsConnected)
                {
                    IssueInformation issueInformation = vm.GetIssueInformation();
                    FileIssueAction.AttachIssueData(issueInformation, this.ElementContext.Id, vm.Element.BoundingRectangle, vm.Element.UniqueId);

                    IIssueResult issueResult = FileIssueAction.FileIssueAsync(issueInformation);
                    if (issueResult != null)
                    {
                        vm.IssueDisplayText = issueResult.DisplayText;
                        vm.IssueLink        = issueResult.IssueLink;
                    }
                    File.Delete(issueInformation.TestFileName);
                }
                else
                {
                    bool?accepted = MessageDialog.Show(Properties.Resources.AutomatedChecksControl_btnFileBug_Click_File_Issue_Configure);
                    if (accepted.HasValue && accepted.Value)
                    {
                        SwitchToServerLogin();
                    }
                }
            }
        }
        /// <summary>
        /// Handles click on file bug button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFileBug_Click(object sender, RoutedEventArgs e)
        {
            var vm = ((Button)sender).Tag as RuleResultViewModel;

            if (vm.IssueLink != null)
            {
                // Bug already filed, open it in a new window
                try
                {
                    Process.Start(vm.IssueLink.OriginalString);
                }
                catch (Exception ex)
                {
                    // Happens when bug is deleted, message describes that work item doesn't exist / possible permission issue
                    MessageDialog.Show(ex.InnerException?.Message);
                    vm.IssueDisplayText = null;
                }
            }
            else
            {
                // File a new bug
                Logger.PublishTelemetryEvent(TelemetryAction.Scan_File_Bug, new Dictionary <TelemetryProperty, string>()
                {
                    { TelemetryProperty.By, FileBugRequestSource.AutomatedChecks.ToString() },
                    { TelemetryProperty.IsAlreadyLoggedIn, IssueReporter.IsConnected.ToString(CultureInfo.InvariantCulture) }
                });

                if (IssueReporter.IsConnected)
                {
                    IssueInformation issueInformation = vm.GetIssueInformation();
                    FileIssueAction.AttachIssueData(issueInformation, this.ElementContext.Id, vm.Element.BoundingRectangle, vm.Element.UniqueId);

                    IIssueResult issueResult = FileIssueAction.FileIssueAsync(issueInformation);
                    if (issueResult != null)
                    {
                        vm.IssueDisplayText = issueResult.DisplayText;
                        vm.IssueLink        = issueResult.IssueLink;
                    }
                    File.Delete(issueInformation.TestFileName);
                }
                else
                {
                    bool?accepted = MessageDialog.Show(Properties.Resources.AutomatedChecksControl_btnFileBug_Click_File_Issue_Configure);
                    if (accepted.HasValue && accepted.Value)
                    {
                        SwitchToServerLogin();
                    }
                }
            }
        }
示例#21
0
        public void TruncateSelectedFields_AllFieldsNull_AddsNullValues()
        {
            Dictionary <IssueField, string> issueFieldPairs = new Dictionary <IssueField, string>();
            IssueInformation issueInfo = new IssueInformation();

            PrivateType privateFileIssueHelpers = new PrivateType(typeof(FileIssueHelpers));

            privateFileIssueHelpers.InvokeStatic("TruncateSelectedFields", issueInfo, issueFieldPairs);

            Assert.AreEqual(4, issueFieldPairs.Count);
            Assert.IsNull(issueFieldPairs[IssueField.ProcessName]);
            Assert.IsNull(issueFieldPairs[IssueField.Glimpse]);
            Assert.IsNull(issueFieldPairs[IssueField.TestMessages]);
            Assert.IsNull(issueFieldPairs[IssueField.RuleSource]);
        }
        public void FileNewIssue_IsNotEnabled_ReturnsPlaceholder()
        {
            using (ShimsContext.Create())
            {
                ShimAzureDevOpsIntegration.AllInstances.ConnectedToAzureDevOpsGet = (_) => false;
                var issueInfo = new IssueInformation();
                var connInfo  = new ConnectionInfo();
                var output    = FileIssueHelpers.FileNewIssue(issueInfo,
                                                              connInfo, false, 0, (_) => { });

                Assert.IsNull(output.issueId);
                Assert.IsNotNull(output.newIssueId);
                Assert.IsTrue(string.IsNullOrEmpty(output.newIssueId));
            }
        }
        public void FileNewBug_IsNotEnabled_ReturnsNull()
        {
            bool wasIssueFiled = false;

            IssueReporter.TestControlledIsEnabled      = false;
            IssueReporter.TestControlledFileIssueAsync = (issueInformation) =>
            {
                wasIssueFiled = true;
                return(null);
            };

            var issueInfo = new IssueInformation();
            var output    = FileIssueAction.FileIssueAsync(issueInfo);

            Assert.IsNull(output);
            Assert.IsFalse(wasIssueFiled);
        }
示例#24
0
        public void TruncateSelectedFields_TestMessagesIsSpecified_AddsTestMessagesValue()
        {
            string originalTestMessages = new string('z', 200);
            Dictionary <IssueField, string> issueFieldPairs = new Dictionary <IssueField, string>();
            IssueInformation issueInfo = new IssueInformation(testMessages: originalTestMessages);

            PrivateType privateFileIssueHelpers = new PrivateType(typeof(FileIssueHelpers));

            privateFileIssueHelpers.InvokeStatic("TruncateSelectedFields", issueInfo, issueFieldPairs);

            Assert.AreEqual(4, issueFieldPairs.Count);
            string modifiedTestMessages = issueFieldPairs[IssueField.TestMessages];

            Assert.AreEqual(new string('z', 150) + "...open attached", modifiedTestMessages.Substring(0, 166));
            Assert.IsNull(issueFieldPairs[IssueField.ProcessName]);
            Assert.IsNull(issueFieldPairs[IssueField.Glimpse]);
            Assert.IsNull(issueFieldPairs[IssueField.RuleSource]);
        }
示例#25
0
        public void TruncateSelectedFields_GlimpseIsSpecified_AddsGlimpseValue()
        {
            string originalGlimpse = new string('y', 60);
            Dictionary <IssueField, string> issueFieldPairs = new Dictionary <IssueField, string>();
            IssueInformation issueInfo = new IssueInformation(glimpse: originalGlimpse);

            PrivateType privateFileIssueHelpers = new PrivateType(typeof(FileIssueHelpers));

            privateFileIssueHelpers.InvokeStatic("TruncateSelectedFields", issueInfo, issueFieldPairs);

            Assert.AreEqual(4, issueFieldPairs.Count);
            string modifiedGlimpse = issueFieldPairs[IssueField.Glimpse];

            Assert.AreEqual(new string('y', 50) + "...", modifiedGlimpse);
            Assert.IsNull(issueFieldPairs[IssueField.ProcessName]);
            Assert.IsNull(issueFieldPairs[IssueField.TestMessages]);
            Assert.IsNull(issueFieldPairs[IssueField.RuleSource]);
        }
        internal Task <Uri> CreateIssuePreviewAsync(ConnectionInfo connectionInfo, IssueInformation issueInfo)
        {
            if (issueInfo == null)
            {
                throw new ArgumentNullException(nameof(issueInfo));
            }

            string templateName = GetTemplateName(issueInfo);
            Dictionary <IssueField, string> issueFieldPairs = issueInfo.ToAzureDevOpsIssueFields();

            TruncateSelectedFields(issueInfo, issueFieldPairs);

            Dictionary <AzureDevOpsField, string> fieldPairs = GenerateIssueTemplate(issueFieldPairs, templateName);

            AddAreaAndIterationPathFields(connectionInfo, fieldPairs);

            return(Task <Uri> .Run(() => _devOpsIntegration.CreateIssuePreview(connectionInfo.Project.Name, connectionInfo.Team?.Name, fieldPairs)));
        }
        private IIssueResult FileIssueAsyncAction(IssueInformation issueInfo)
        {
            if (this.IsConfigured)
            {
                try
                {
                    string url = IssueFormatterFactory.GetNewIssueLink(this.configurationControl.Config.RepoLink, issueInfo);
                    System.Diagnostics.Process.Start(url);
                }
                catch (Exception e)
                {
                    e.ReportException();
                    MessageDialog.Show(Properties.Resources.InvalidLink);
                }
            }

            return(null);
        }
示例#28
0
 internal static Dictionary <IssueField, string> ToAzureDevOpsIssueFields(this IssueInformation issueInfo)
 {
     return(new Dictionary <IssueField, string>
     {
         { IssueField.WindowTitle, GetStringValue(issueInfo.WindowTitle) },
         { IssueField.Glimpse, GetStringValue(issueInfo.Glimpse) },
         { IssueField.HowToFixLink, GetStringValue(issueInfo.HowToFixLink) },
         { IssueField.HelpURL, GetStringValue(issueInfo.HelpUri) },
         { IssueField.RuleSource, GetStringValue(issueInfo.RuleSource) },
         { IssueField.RuleDescription, GetStringValue(issueInfo.RuleDescription) },
         { IssueField.TestMessages, GetStringValue(issueInfo.TestMessages) },
         { IssueField.ProcessName, GetStringValue(issueInfo.ProcessName) },
         { IssueField.InternalGuid, GetStringValue(issueInfo.InternalGuid) },
         { IssueField.ElementPath, GetStringValue(issueInfo.ElementPath) },
         { IssueField.RuleForTelemetry, GetStringValue(issueInfo.RuleForTelemetry) },
         { IssueField.UIFramework, GetStringValue(issueInfo.UIFramework) },
     });
 }
示例#29
0
        public void FileNewIssue_GetIterationReturnsNull_ReturnsPlaceholder()
        {
            var connInfo = new ConnectionInfo(new Uri("https://accessibilityinsights.io"),
                                              new AzureDevOps.Models.TeamProject(testProjectName, Guid.Empty), null);

            _adoIntegrationMock.Setup(x => x.GetAreaPath(connInfo))
            .Returns(testArea);
            _adoIntegrationMock.Setup(x => x.GetIteration(connInfo))
            .Returns <string>(null);

            var issueInfo = new IssueInformation(internalGuid: testIssueGuid);
            var output    = _fileIssueHelpers.FileNewIssue(issueInfo,
                                                           connInfo, false, 0, (_) => { });

            Assert.IsNull(output.issueId);
            Assert.AreEqual(string.Empty, output.newIssueId);
            _adoIntegrationMock.VerifyAll();
        }
示例#30
0
        /// <summary>
        /// Opens issue filing window with prepopulated data
        /// </summary>
        /// <p  aram name="issueInfo">Dictionary of issue info from with which to populate the issue</param>
        /// <param name="connection">connection info</param>
        /// <param name="onTop">Is window always on top</param>
        /// <param name="zoomLevel">Zoom level for issue file window</param>
        /// <param name="updateZoom">Callback to update configuration with zoom level</param>
        /// <returns></returns>
        public static (int?issueId, string newIssueId) FileNewIssue(IssueInformation issueInfo, ConnectionInfo connection, bool onTop, int zoomLevel, Action <int> updateZoom)
        {
            try
            {
                // Create a A11y-specific Guid for this issue to verify that we are uploading
                //  attachment to the correct issue
                var a11yIssueId = issueInfo.InternalGuid.HasValue
                    ? issueInfo.InternalGuid.Value.ToString()
                    : string.Empty;
                Uri url     = CreateIssuePreviewAsync(connection, issueInfo).Result;
                var issueId = FileIssueWindow(url, onTop, zoomLevel, updateZoom);

                return(issueId, a11yIssueId);
            }
            catch
            {
                return(null, string.Empty);
            }
        }