private void Setup_Widget_Areas(params int[] widgetIds) { // system-defined widget area "blog-sidebar1" var widgetArea = new WidgetArea { Id = "blog-sidebar1" }; var meta = new Meta { Id = 1, Key = widgetArea.Id, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaBySystem }; metaRepoMock.Setup(repo => repo.GetAsync(meta.Key, EMetaType.WidgetAreaBySystem)).Returns(Task.FromResult(meta)); // system-defined widget area "blog-sidebar2" widgetArea = new WidgetArea { Id = "blog-sidebar2" }; meta = new Meta { Id = 2, Key = widgetArea.Id, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaBySystem }; metaRepoMock.Setup(repo => repo.GetAsync(meta.Key, EMetaType.WidgetAreaBySystem)).Returns(Task.FromResult(meta)); // theme-defined widget area "my-area" widgetArea = widgetIds.Length > 0 ? new WidgetArea { Id = MY_AREA_ID, WidgetIds = widgetIds } : new WidgetArea { Id = MY_AREA_ID }; meta = new Meta { Id = 3, Key = MY_AREA_META_KEY, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaByTheme }; metaRepoMock.Setup(repo => repo.GetAsync(meta.Key, EMetaType.WidgetAreaByTheme)).Returns(Task.FromResult(meta)); }
public async void AddWidgetToAreaAsync_adds_widget_to_widget_area() { // Arrange Setup_MyWidget(); Setup_Widget_Areas(); // Act: user drags MyWidget to "my-area" // NOTE: area id is "my-area" not its meta key which is "mytheme-my-area" var widgetInst = await widgetService.AddWidgetToAreaAsync(MY_WIDGET_ID, MY_AREA_ID, index : 0); // Assert: repo UpdateAsync is called twice metaRepoMock.Verify(repo => repo.UpdateAsync(It.IsAny <Meta>()), Times.Exactly(2)); // Once: update widget instance with widget id and widget area id var myWidget = new MyWidget { Id = MY_WIDGET_ID, AreaId = MY_AREA_ID, Folder = MY_WIDGET_FOLDER }; metaRepoMock.Verify(repo => repo.UpdateAsync( It.Is <Meta>(m => m.Value == JsonConvert.SerializeObject(myWidget))), Times.Once); // Once: update widget area "my-area" with MyWidget of id 4 var myArea = new WidgetArea { Id = MY_AREA_ID, WidgetIds = new int[] { MY_WIDGET_ID } }; metaRepoMock.Verify(repo => repo.UpdateAsync( It.Is <Meta>(m => m.Value == JsonConvert.SerializeObject(myArea))), Times.Once); Assert.Equal(MY_WIDGET_ID, widgetInst.Id); Assert.Equal(MY_WIDGET_FOLDER, widgetInst.Folder); Assert.Equal(MY_AREA_ID, widgetInst.AreaId); Assert.Equal("My Widget", widgetInst.Title); Assert.Equal("/Widgets/MyWidgetSettings?widgetId=4", widgetInst.SettingsUrl); }
private void Setup_Widget_Areas_for_create() { // system-defined widget area "blog-sidebar1" var widgetArea = new WidgetArea { Id = "blog-sidebar1" }; var meta = new Meta { Id = 1, Key = widgetArea.Id, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaBySystem }; metaRepoMock.Setup(repo => repo.GetAsync(meta.Key, EMetaType.WidgetAreaBySystem)).Returns(Task.FromResult(meta)); // system-defined widget area "blog-sidebar2" widgetArea = new WidgetArea { Id = "blog-sidebar2" }; meta = new Meta { Id = 2, Key = widgetArea.Id, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaBySystem }; metaRepoMock.Setup(repo => repo.GetAsync(meta.Key, EMetaType.WidgetAreaBySystem)).Returns(Task.FromResult(meta)); // suppose now MyTheme just added a theme-defined area, repo CreateAsync will be called widgetArea = new WidgetArea { Id = MY_AREA_ID }; meta = new Meta { Id = 3, Key = MY_AREA_META_KEY, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaByTheme }; metaRepoMock.Setup(repo => repo.CreateAsync(It.Is <Meta>(m => m.Key == meta.Key && m.Value == meta.Value && m.Type == meta.Type))).Returns(Task.FromResult(meta)); }
/// <summary> /// Activates a theme. /// </summary> /// <param name="folderName">Theme's folder name.</param> /// <returns></returns> /// <remarks> /// It registers theme and the widget areas used by the theme. /// </remarks> public async Task ActivateThemeAsync(string folderName) { // verify folderName var regex = new Regex(THEME_FOLDER_REGEX); if (!regex.IsMatch(folderName)) { throw new FanException($"Theme {folderName} contains invalid characters."); } // register theme if not exist if (await metaRepository.GetAsync(folderName, EMetaType.Theme) == null) { await metaRepository.CreateAsync(new Meta { Key = folderName.ToLower(), // lower case Value = "", // empty for now Type = EMetaType.Theme, }); } // register theme-defined widget areas var installedThemes = await GetInstalledThemesInfoAsync(); var themeToActivate = installedThemes.Single(t => t.Name.Equals(folderName, StringComparison.OrdinalIgnoreCase)); // check if there is any empty area ids if (themeToActivate.WidgetAreas.Any(a => a.Id.IsNullOrEmpty())) { throw new FanException("Widget area id cannot be empty."); } var themeDefinedAreas = themeToActivate.WidgetAreas.Where(ta => !WidgetService.SystemDefinedWidgetAreaInfos.Any(sa => sa.Id == ta.Id)); foreach (var area in themeDefinedAreas) { var key = string.Format($"{folderName}-{area.Id}").ToLower(); // register only if not exist if (await metaRepository.GetAsync(key, EMetaType.WidgetAreaByTheme) == null) { var widgetArea = new WidgetArea { Id = area.Id }; await metaRepository.CreateAsync(new Meta { Key = key, Value = JsonConvert.SerializeObject(widgetArea), Type = EMetaType.WidgetAreaByTheme, }); } } }
public async void OrderWidgetInAreaAsync_orders_widget_index_within_an_area() { // Arrange: my-area contains two of my widget [4, 5] Setup_MyWidget(); Setup_Widget_Areas(MY_WIDGET_ID, MY_WIDGET_ID2); // Act: user drags the second my widget to be first await widgetService.OrderWidgetInAreaAsync(MY_WIDGET_ID2, MY_AREA_ID, 0); // Assert: the order of the two widgets swapped var myArea = new WidgetArea { Id = MY_AREA_ID, WidgetIds = new int[] { 5, 4 } }; metaRepoMock.Verify(repo => repo.UpdateAsync( It.Is <Meta>(m => m.Value == JsonConvert.SerializeObject(myArea))), Times.Once); }
public async void RemoveWidgetFromAreaAsync_removes_widget_from_widget_area() { // Arrange: my-area contains my widget Setup_MyWidget(); Setup_Widget_Areas(MY_WIDGET_ID); // Act: remove my widget from my-area await widgetService.RemoveWidgetFromAreaAsync(MY_WIDGET_ID, MY_AREA_ID); // Assert: my-area contains no widget var myArea = new WidgetArea { Id = MY_AREA_ID, WidgetIds = new int[] { } }; metaRepoMock.Verify(repo => repo.UpdateAsync( It.Is <Meta>(m => m.Value == JsonConvert.SerializeObject(myArea))), Times.Once); }
public async void GetCurrentThemeAreasAsync_registers_theme_defined_widget_areas_if_not_already_exists() { // Arrange Setup_Widget_Areas_for_create(); // Act var areas = await widgetService.GetCurrentThemeAreasAsync(); // Assert repo create is called once Assert.Equal(3, areas.Count()); var myArea = new WidgetArea { Id = MY_AREA_ID }; metaRepoMock.Verify(repo => repo.CreateAsync(It.Is <Meta>(m => m.Key == MY_AREA_META_KEY && m.Value == JsonConvert.SerializeObject(myArea) && m.Type == EMetaType.WidgetAreaByTheme)), Times.Once); }