public void DetailedItemViewModelTests_VisibleFields_MultipleEntitiesOfSameTime_ChangesAreReflectedInAllEntities()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var secondStory = StoryUtilities.CreateStory();

            try
            {
                var secondViewModel = new DetailedItemViewModel(_story);
                secondViewModel.InitializeAsync().Wait();

                ChangeFieldVisibility(viewModel, "Release", false);
                ChangeFieldVisibility(viewModel, "Committers", true);

                var expectedVisibleFields = viewModel.VisibleFields.Select(f => f.Name).OrderBy(f => f).ToList();
                var actualVisibleFields   = secondViewModel.FilteredEntityFields.Where(f => f.IsSelected).Select(f => f.Name).OrderBy(f => f).ToList();
                CollectionAssert.AreEqual(expectedVisibleFields, actualVisibleFields, "Mismathed visible fields");
            }
            finally
            {
                EntityService.DeleteById <Story>(WorkspaceContext, secondStory.Id);
            }
        }
        private void ValidateResetCommand(bool allFieldsVisible)
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            Assert.IsTrue(viewModel.OnlyDefaultFieldsAreShown, "Only default fields should be visible when detailed item is initialized");

            foreach (var field in viewModel.FilteredEntityFields)
            {
                field.IsSelected = allFieldsVisible;
                viewModel.ToggleEntityFieldVisibilityCommand.Execute(null);
            }

            Assert.IsFalse(viewModel.OnlyDefaultFieldsAreShown, "Visible fields should be different than default fields");

            viewModel.ResetFieldsCustomizationCommand.Execute(null);

            var dynamicFieldsCache = ExposedClass.From(typeof(FieldsCache));
            var cache = dynamicFieldsCache._defaultFieldsCache as FieldsCache.Metadata;

            var persistedVisibleFields = cache.data[Utility.GetConcreteEntityType(_story)];

            Assert.AreEqual(persistedVisibleFields.Count, viewModel.VisibleFields.Count(), "Inconsistent number of visible fields");
            foreach (var field in viewModel.VisibleFields)
            {
                Assert.IsTrue(persistedVisibleFields.Contains(field.Name), $"Field {field.Name} should be visible");
            }

            Assert.IsTrue(viewModel.OnlyDefaultFieldsAreShown, "Only default fields should be visible after reset command");
        }
        public void DetailedItemViewModelTests_AddComment_Succes()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();
            string textForComment = Guid.NewGuid().ToString();

            viewModel.CommentText = "<html><body>" + textForComment + "</body></html>";
            Assert.AreNotEqual("", viewModel.CommentText);

            viewModel.AddCommentCommand.Execute(null);
            Thread.Sleep(8196);
            int detectedCommentsWithText = 0;

            foreach (var comment in viewModel.Comments)
            {
                if (comment.Text == textForComment)
                {
                    detectedCommentsWithText++;
                }
            }
            Assert.AreEqual(1, detectedCommentsWithText);

            var commentFromStory = viewModel.Comments.First();

            Assert.AreEqual(commentFromStory.Text, textForComment);
        }
        public void DetailedItemViewModelTests_Filter_FilterPartialMatch_ReturnMatchList()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var expectedFilteredFields = new List <string> {
                "Blocked reason", "Creation time", "Feature", "Release", "Team", "Team Phase"
            };

            viewModel.Filter = "ea";
            var actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Label).ToList();

            CollectionAssert.AreEqual(expectedFilteredFields, actualFilteredFields,
                                      $"Mismathed filtered fields for filter '{viewModel.Filter}'");

            expectedFilteredFields = new List <string> {
                "Creation time", "Feature",
            };
            viewModel.Filter     = "eat";
            actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Label).ToList();
            CollectionAssert.AreEqual(expectedFilteredFields, actualFilteredFields,
                                      $"Mismathed filtered fields for filter '{viewModel.Filter}'");

            expectedFilteredFields = new List <string> {
                "Feature"
            };
            viewModel.Filter     = "feature";
            actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Label).ToList();
            CollectionAssert.AreEqual(expectedFilteredFields, actualFilteredFields,
                                      $"Mismathed filtered fields for filter '{viewModel.Filter}'");
        }
        /// <summary>
        /// Load the necessary information for the given entity
        /// </summary>
        internal void LoadEntity(BaseEntity entity)
        {
            var viewModel = new DetailedItemViewModel(entity);

            viewModel.InitializeAsync();

            var entityTypeInformation = EntityTypeRegistry.GetEntityTypeInformation(viewModel.Entity);

            Caption = $"{entityTypeInformation?.ShortLabel} {viewModel.ID}";
            detailsControl.DataContext = viewModel;
        }
        public void DetailedItemViewModelTests_Filter_FilterDoesntMatchAnyItem_ReturnEmptyList()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            viewModel.Filter = "FilterDoesntMatchAnyItem";

            var actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Name).ToList();

            Assert.AreEqual(0, actualFilteredFields.Count,
                            "Filter that doesn't match any item should return an empty search result");
        }
        public void DetailedItemViewModelTests_Filter_EmptyFilter_ReturnAllFields()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var expectedFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Name).ToList();

            viewModel.Filter = string.Empty;

            var actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Name).ToList();

            CollectionAssert.AreEqual(expectedFilteredFields, actualFilteredFields, "Mismathed filtered fields");
        }
        public void DetailedItemViewModelTests_VisibleFields_ShowHideFields_ShowSelectedFields()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            ChangeFieldVisibility(viewModel, "Release", false);
            ChangeFieldVisibility(viewModel, "Committers", true);

            var expectedVisibleFields = viewModel.FilteredEntityFields.Where(f => f.IsSelected).Select(f => f.Name).OrderBy(f => f).ToList();
            var actualVisibleFields   = viewModel.VisibleFields.Select(f => f.Name).OrderBy(f => f).ToList();

            CollectionAssert.AreEqual(expectedVisibleFields, actualVisibleFields, "Mismathed visible fields");
        }
        public void DetailedItemViewModelTests_VariousProperties_BeforeAndAfterInitialize_Success()
        {
            var viewModel = new DetailedItemViewModel(_story);

            Assert.AreEqual(WindowMode.Loading, viewModel.Mode, "Mismatched initial mode");

            viewModel.InitializeAsync().Wait();
            Assert.AreEqual(WindowMode.Loaded, viewModel.Mode, "Mismatched mode after initialization");

            var entityTypeInformation = EntityTypeRegistry.GetEntityTypeInformation(_story);

            Assert.AreEqual(entityTypeInformation.ShortLabel, viewModel.IconText, "Mismatched icon text");
            Assert.AreEqual(entityTypeInformation.Color, viewModel.IconBackgroundColor, "Mismatched icon background color");
        }
        public void DetailedItemViewModelTests_Filter_FilterIgnoreCase_ReturnMatchList()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var expectedFilteredFields = new List <string> {
                "Creation time", "Feature",
            };

            viewModel.Filter = "EaT";
            var actualFilteredFields = viewModel.FilteredEntityFields.Select(f => f.Label).ToList();

            CollectionAssert.AreEqual(expectedFilteredFields, actualFilteredFields,
                                      $"Mismathed filtered fields for filter 'EaT'");
        }
        //TODO: Fix this - Error is 403 forbidden: EXTENSION_TO_MIME_TYPE is the problem I think, because it says
        //something regarding the text/plain content type and we try to upload something of type .txt (not sure)
        public void DetailedItemViewModelTests_HandleImagesInDescription_DownloadImage_Success()
        {
            var fileName = "DetailedItemViewModelTests_HandleImagesInDescription_" + Guid.NewGuid() + ".txt";

            var fileContentsBytes = new byte[2500];
            var rnd = new Random();

            rnd.NextBytes(fileContentsBytes);

            Api.Core.Connector.RestConnector.AwaitContinueOnCapturedContext = false;
            // simulating uploading a picture; using plain text to also test content randomness
            var attachment = EntityService.AttachToEntity(WorkspaceContext, _story, fileName, fileContentsBytes, "text/plain", new string[] { "owner_work_item" });

            Assert.IsNotNull(attachment.Id, "Attachment id shouldn't be null");
            Assert.AreEqual(WorkItem.SUBTYPE_STORY, attachment.owner_work_item.TypeName, "Mismatched attachment parent type");
            Assert.AreEqual(_story.Id, attachment.owner_work_item.Id, "Mismatched attachment parent id");

            var updatedStory = new Story(_story.Id);

            updatedStory.SetValue(CommonFields.Description,
                                  "<html><body>" +
                                  "<div style=\"\">" +
                                  "<img data-size-percentage=\"100\" src=\"" + WorkspaceContext.GetPath() + "/attachments/" + attachment.Id + "/" + fileName + "\" style=\"width:437px;height:303px;\" />" +
                                  "</div>" +
                                  "<p>&nbsp;</p>" +
                                  "</body></html>");
            updatedStory = EntityService.Update(WorkspaceContext, updatedStory, new[] { "name", "subtype", CommonFields.Description });

            var viewModel = new DetailedItemViewModel(updatedStory);

            viewModel.InitializeAsync().Wait();

            var path = DetailedItemViewModel.TempPath + WorkItem.SUBTYPE_STORY + updatedStory.Id + fileName;

            ValidateFileContents(path, fileContentsBytes);

            var fileInfo = new FileInfo(path);
            var expectedLastWriteTime = fileInfo.LastWriteTime;

            Thread.Sleep(1000);

            viewModel.RefreshCommand.Execute(null);

            fileInfo = new FileInfo(path);
            Assert.AreEqual(expectedLastWriteTime, fileInfo.LastWriteTime, "Downloaded attachement was modified by refresh");
        }
        public void DetailedItemViewModelTests_RefreshCommand_RefreshWithoutAnyChanges_Success()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var expectedVisibleFields = viewModel.VisibleFields.Select(f => f.Name).ToList();

            viewModel.RefreshCommand.Execute(null);

            Utilities.Utility.WaitUntil(() => viewModel.Mode == WindowMode.Loaded,
                                        "Timeout while refreshing the entity", new TimeSpan(0, 0, 30));

            var actualVisibleFields = viewModel.VisibleFields.Select(f => f.Name).ToList();

            CollectionAssert.AreEqual(expectedVisibleFields, actualVisibleFields, "Mismathed visible fields");
        }
        public void DetailedItemViewModelTests_VisibleFields_HideAllFields_ShowSelectedFields()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            foreach (var field in viewModel.FilteredEntityFields)
            {
                field.IsSelected = false;
                viewModel.ToggleEntityFieldVisibilityCommand.Execute(null);
            }

            var expectedVisibleFields = viewModel.FilteredEntityFields.Where(f => f.IsSelected).Select(f => f.Name).ToList();
            var actualVisibleFields   = viewModel.VisibleFields.Select(f => f.Name).ToList();

            CollectionAssert.AreEqual(expectedVisibleFields, actualVisibleFields, "Mismathed visible fields");
        }
        public void DetailedItemViewModelTests_SaveEntityCommand_Name_Success()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var newName = "New_Story_" + Guid.NewGuid();

            viewModel.Title = newName;
            Assert.AreEqual(newName, viewModel.Title, "Mismatched entity name after setting it");

            viewModel.SaveEntityCommand.Execute(null);

            Utilities.Utility.WaitUntil(() => viewModel.Mode == WindowMode.Loaded,
                                        "Timeout while refreshing the entity", new TimeSpan(0, 0, 30));

            Assert.AreEqual(newName, viewModel.Title, "Mismatched entity name after save");
        }
        public void DetailedItemViewModelTests_SaveEntityCommand_ChangeIntField_Success()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            var storyPointsField = viewModel.VisibleFields.FirstOrDefault(f => f.Name == CommonFields.StoryPoints);

            storyPointsField.Content = 1234;
            Assert.AreEqual(1234, storyPointsField.Content);

            viewModel.SaveEntityCommand.Execute(null);

            Utilities.Utility.WaitUntil(() => viewModel.Mode == WindowMode.Loaded,
                                        "Timeout while refreshing the entity", new TimeSpan(0, 0, 30));

            storyPointsField = viewModel.VisibleFields.FirstOrDefault(f => f.Name == CommonFields.StoryPoints);
            Assert.AreEqual(1234, storyPointsField.Content);
        }
        public void DetailedItemViewModelTests_OnlyDefaultFieldsAreShown_ToggleShowingOnlyDefaultFields_True()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            Assert.IsTrue(viewModel.OnlyDefaultFieldsAreShown, "Only default fields should be visible when detailed item is initialized");

            ChangeFieldVisibility(viewModel, "Release", false);
            Assert.IsFalse(viewModel.OnlyDefaultFieldsAreShown, "Not all default fields are visible");

            ChangeFieldVisibility(viewModel, "Release", true);
            Assert.IsTrue(viewModel.OnlyDefaultFieldsAreShown, "All default fields should be visible");

            ChangeFieldVisibility(viewModel, "Committers", true);
            Assert.IsFalse(viewModel.OnlyDefaultFieldsAreShown, "More fields than the default fields are visible");

            ChangeFieldVisibility(viewModel, "Committers", false);
            Assert.IsTrue(viewModel.OnlyDefaultFieldsAreShown, "All default fields should be visible");
        }
        public void DetailedItemViewModelTests_RefreshCommand_RefreshAfterChangingVisibleFields_Succes()
        {
            var viewModel = new DetailedItemViewModel(_story);

            viewModel.InitializeAsync().Wait();

            foreach (var field in viewModel.FilteredEntityFields)
            {
                field.IsSelected = true;
                viewModel.ToggleEntityFieldVisibilityCommand.Execute(null);
            }

            var expectedVisibleFields = viewModel.VisibleFields.Select(f => f.Name).ToList();

            viewModel.RefreshCommand.Execute(null);

            Utilities.Utility.WaitUntil(() => viewModel.Mode == WindowMode.Loaded,
                                        "Timeout while refreshing the entity", new TimeSpan(0, 0, 30));

            var actualVisibleFields = viewModel.VisibleFields.Select(f => f.Name).ToList();

            CollectionAssert.AreEqual(expectedVisibleFields, actualVisibleFields, "Mismathed visible fields");
        }
        private void ValidateChangePhase(BaseEntity entity)
        {
            var viewModel = new DetailedItemViewModel(entity);

            viewModel.InitializeAsync().Wait();

            Assert.IsNull(viewModel.SelectedNextPhase, "SelectedNextPhase should be null after initialization");

            for (int i = 0; i < 5; i++)
            {
                Assert.IsTrue(viewModel.NextPhaseNames.Count > 0, "There should be at least one next phase name");
                var nextPhaseName = viewModel.NextPhaseNames[0];
                viewModel.SelectedNextPhase = nextPhaseName;

                viewModel.SaveEntityCommand.Execute(null);
                Utilities.Utility.WaitUntil(() => viewModel.Mode == WindowMode.Loaded,
                                            "Timeout while refreshing the entity for next phase " + nextPhaseName, new TimeSpan(0, 0, 30));
                Thread.Sleep(4096); // wait for update to be propagated

                Assert.AreEqual(nextPhaseName, viewModel.Phase, "Mismatched entity phase after save");
                Assert.IsNull(viewModel.SelectedNextPhase, "SelectedNextPhase should be null after save");
            }
        }