/// <inheritdoc/> public ShortenedNoteViewModel( INavigationService navigationService, ILanguageService languageService, ISvgIconService svgIconService, IThemeService themeService, IBaseUrlService webviewBaseUrl, SearchableHtmlConverter searchableTextConverter, IRepositoryStorageService repositoryService, IFeedbackService feedbackService, ISettingsService settingsService, ICryptor cryptor, SafeListModel safes, NoteModel noteFromRepository) : base(navigationService, languageService, svgIconService, themeService, webviewBaseUrl, searchableTextConverter, repositoryService, feedbackService, settingsService, cryptor, safes, noteFromRepository) { if (_unlockedContent != null) { // Create a short version for large notes, with only the first part of the note. // This is a performance improvement if there are large notes in the repository. HtmlShortener shortener = new HtmlShortener(); shortener.WantedLength = 600; // Should be enough even for settings with shortener.WantedTagNumber = 20; // small font and very height notes. string shortenedContent = shortener.Shorten(_unlockedContent); if (shortenedContent.Length != _unlockedContent.Length) { // Because the note will be truncated, we have to build the searchable content // first, before overwriting the original content. string dummy = SearchableContent; _unlockedContent = shortenedContent; } } }
/// <summary> /// Initializes a new instance of the <see cref="NoteViewModel"/> class. /// </summary> public NoteViewModel( INavigationService navigationService, ILanguageService languageService, ISvgIconService svgIconService, IThemeService themeService, IBaseUrlService webviewBaseUrl, SearchableHtmlConverter searchableTextConverter, IRepositoryStorageService repositoryService, IFeedbackService feedbackService, ISettingsService settingsService, ICryptor cryptor, SafeListModel safes, NoteModel noteFromRepository) : base(navigationService, languageService, svgIconService, themeService, webviewBaseUrl) { _repositoryService = repositoryService; _feedbackService = feedbackService; _settingsService = settingsService; _searchableTextConverter = searchableTextConverter; _cryptor = cryptor; _safes = safes; MarkSearchableContentAsDirty(); PushNoteToOnlineStorageCommand = new RelayCommand(PushNoteToOnlineStorage); PullNoteFromOnlineStorageCommand = new RelayCommand(PullNoteFromOnlineStorage); ToggleShoppingModeCommand = new RelayCommand(ToggleShoppingMode); GoBackCommand = new RelayCommand(GoBack); Model = noteFromRepository; _unlockedContent = IsInSafe ? UnlockIfSafeOpen(Model.HtmlContent) : Model.HtmlContent; }
public void DoesNotShowContentWhenSafeIsClosed() { SearchableHtmlConverter searchableConverter = new SearchableHtmlConverter(); Mock <IRepositoryStorageService> repositoryService = new Mock <IRepositoryStorageService>(); Mock <ISettingsService> settingsService = new Mock <ISettingsService>(); Mock <ICryptor> cryptor = new Mock <ICryptor>(); SafeListModel safes = new SafeListModel(new[] { new SafeModel { Id = Guid.NewGuid() }, }); NoteModel note = new NoteModel { Id = Guid.NewGuid(), HtmlContent = "secret", SafeId = safes[0].Id }; NoteViewModel noteViewModel = new NoteViewModel( new Mock <INavigationService>().Object, new Mock <ILanguageService>().Object, new Mock <ISvgIconService>().Object, new Mock <IThemeService>().Object, new Mock <IBaseUrlService>().Object, searchableConverter, repositoryService.Object, new Mock <IFeedbackService>().Object, settingsService.Object, cryptor.Object, safes, new List <string>(), note); Assert.IsNull(noteViewModel.UnlockedHtmlContent); Assert.IsNull(noteViewModel.SearchableContent); }
public void NormalizeWhitespacesLeavesTagsIntact() { string note = @" Hello <p> world </p> "; string res = SearchableHtmlConverter.NormalizeWhitespaces(note); Assert.AreEqual(" Hello <p> world </p> ", res); }
public void ModifiedNoteIsEncryptedAndStored() { string modelHtmlContent = "c2VjcmV0"; byte[] safeKey = new byte[] { 88 }; SettingsModel settingsModel = new SettingsModel(); SearchableHtmlConverter searchableConverter = new SearchableHtmlConverter(); Mock <IRepositoryStorageService> repositoryService = new Mock <IRepositoryStorageService>(); Mock <ISettingsService> settingsService = new Mock <ISettingsService>(); settingsService. Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel); Mock <ICryptor> cryptor = new Mock <ICryptor>(); cryptor. Setup(m => m.Decrypt(It.IsAny <byte[]>(), It.Is <byte[]>(v => v == safeKey))). Returns(CryptoUtils.StringToBytes("not secret anymore")); SafeListModel safes = new SafeListModel(new[] { new SafeModel { Id = Guid.NewGuid(), Key = safeKey }, }); NoteModel note = new NoteModel { Id = Guid.NewGuid(), HtmlContent = modelHtmlContent, SafeId = safes[0].Id }; NoteViewModel noteViewModel = new NoteViewModel( new Mock <INavigationService>().Object, new Mock <ILanguageService>().Object, new Mock <ISvgIconService>().Object, new Mock <IThemeService>().Object, new Mock <IBaseUrlService>().Object, searchableConverter, repositoryService.Object, new Mock <IFeedbackService>().Object, settingsService.Object, cryptor.Object, safes, new List <string>(), note); noteViewModel.UnlockedHtmlContent = "something new"; noteViewModel.OnStoringUnsavedData(); cryptor.Verify(m => m.Encrypt( It.Is <byte[]>(p => p.SequenceEqual(CryptoUtils.StringToBytes("something new"))), It.Is <byte[]>(p => p.SequenceEqual(safeKey)), It.IsAny <string>(), It.Is <string>(p => p == null)), Times.Once); repositoryService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Once); }
public void NormalizeWhitespacesAcceptsNullAndSpace() { string res = SearchableHtmlConverter.NormalizeWhitespaces(null); Assert.AreEqual(string.Empty, res); res = SearchableHtmlConverter.NormalizeWhitespaces(string.Empty); Assert.AreEqual(string.Empty, res); res = SearchableHtmlConverter.NormalizeWhitespaces(" "); Assert.AreEqual(" ", res); }
/// <summary> /// Initializes a new instance of the <see cref="NoteRepositoryViewModel"/> class. /// </summary> public NoteRepositoryViewModel( INavigationService navigationService, ILanguageService languageService, ISvgIconService svgIconService, IThemeService themeService, IBaseUrlService webviewBaseUrl, IStoryBoardService storyBoardService, IFeedbackService feedbackService, ISettingsService settingsService, IEnvironmentService environmentService, ICryptoRandomSource randomSource, IRepositoryStorageService repositoryService) : base(navigationService, languageService, svgIconService, themeService, webviewBaseUrl) { _storyBoardService = storyBoardService; _repositoryService = repositoryService; _feedbackService = feedbackService; _settingsService = settingsService; _environmentService = environmentService; _noteCryptor = new Cryptor(NoteModel.CryptorPackageName, randomSource); _searchableTextConverter = new SearchableHtmlConverter(); AllNotes = new List <NoteViewModel>(); FilteredNotes = new ObservableCollection <NoteViewModel>(); _repositoryService.LoadRepositoryOrDefault(out NoteRepositoryModel noteRepository); Model = noteRepository; // Initialize commands and events ShowNoteCommand = new RelayCommand <object>(ShowNote); NewNoteCommand = new RelayCommand(NewNote); NewChecklistCommand = new RelayCommand(NewChecklist); DeleteNoteCommand = new RelayCommand <object>(DeleteNote); ClearFilterCommand = new RelayCommand(ClearFilter); SynchronizeCommand = new RelayCommand(Synchronize); ShowTransferCodeCommand = new RelayCommand(ShowTransferCode); ShowSettingsCommand = new RelayCommand(ShowSettings); ShowRecycleBinCommand = new RelayCommand(ShowRecycleBin); ShowExportCommand = new RelayCommand(ShowExport); ShowInfoCommand = new RelayCommand(ShowInfo); OpenSafeCommand = new RelayCommand(OpenSafe); CloseSafeCommand = new RelayCommand(CloseSafe); ChangeSafePasswordCommand = new RelayCommand(ChangeSafePassword); Modified = false; // If a filter was set before e.g. opening a note, set the same filter again. if (!string.IsNullOrEmpty(_lastFilter)) { Filter = _lastFilter; } }
private void ApplyFilter(string filter) { string normalizedFilter = SearchableHtmlConverter.NormalizeWhitespaces(filter); NoteFilter noteFilter = new NoteFilter(normalizedFilter); FilteredNotes.Clear(); foreach (NoteViewModel noteViewModel in AllNotes) { if (!noteViewModel.InRecyclingBin && noteFilter.ContainsPattern(noteViewModel.SearchableContent)) { FilteredNotes.Add(noteViewModel); } } }
public NoteRepositoryViewModel( INavigationService navigationService, ILanguageService languageService, ISvgIconService svgIconService, IThemeService themeService, IBaseUrlService webviewBaseUrl, IStoryBoardService storyBoardService, IFeedbackService feedbackService, ISettingsService settingsService, IEnvironmentService environmentService, ICryptoRandomSource randomSource, IRepositoryStorageService repositoryService) : base(navigationService, languageService, svgIconService, themeService, webviewBaseUrl) { _storyBoardService = storyBoardService; _repositoryService = repositoryService; _feedbackService = feedbackService; _settingsService = settingsService; _environmentService = environmentService; _noteCryptor = new Cryptor(NoteModel.CryptorPackageName, randomSource); _searchableTextConverter = new SearchableHtmlConverter(); AllNotes = new List <NoteViewModel>(); FilteredNotes = new ObservableCollection <NoteViewModel>(); _repositoryService.LoadRepositoryOrDefault(out NoteRepositoryModel noteRepository); Model = noteRepository; // Initialize commands and events ShowNoteCommand = new RelayCommand <Guid>(ShowNote); NewNoteCommand = new RelayCommand(NewNote); NewChecklistCommand = new RelayCommand(NewChecklist); DeleteNoteCommand = new RelayCommand <Guid>(DeleteNote); ClearFilterCommand = new RelayCommand(ClearFilter); SynchronizeCommand = new RelayCommand(Synchronize); ShowTransferCodeCommand = new RelayCommand(ShowTransferCode); ShowSettingsCommand = new RelayCommand(ShowSettings); ShowRecycleBinCommand = new RelayCommand(ShowRecycleBin); ShowInfoCommand = new RelayCommand(ShowInfo); OpenSafeCommand = new RelayCommand(OpenSafe); CloseSafeCommand = new RelayCommand(CloseSafe); ChangeSafePasswordCommand = new RelayCommand(ChangeSafePassword); OnPropertyChanged(nameof(FilterButtonMagnifierVisible)); OnPropertyChanged(nameof(FilterButtonCancelVisible)); Modified = false; }
public NoteViewModel( INavigationService navigationService, ILanguageService languageService, ISvgIconService svgIconService, IBaseUrlService webviewBaseUrl, SearchableHtmlConverter searchableTextConverter, IRepositoryStorageService repositoryService, ISettingsService settingsService, NoteModel noteFromRepository) : base(navigationService, languageService, svgIconService, webviewBaseUrl) { _repositoryService = repositoryService; _settingsService = settingsService; _searchableTextConverter = searchableTextConverter; MarkSearchableContentAsDirty(); GoBackCommand = new RelayCommand(GoBack); Model = noteFromRepository; }
public void ShowsUnlockedContentWhenSafeIsOpen() { string modelHtmlContent = "c2VjcmV0"; byte[] safeKey = new byte[] { 88 }; SearchableHtmlConverter searchableConverter = new SearchableHtmlConverter(); Mock <IRepositoryStorageService> repositoryService = new Mock <IRepositoryStorageService>(); Mock <ISettingsService> settingsService = new Mock <ISettingsService>(); Mock <ICryptor> cryptor = new Mock <ICryptor>(); cryptor. Setup(m => m.Decrypt(It.IsAny <byte[]>(), It.Is <byte[]>(v => v == safeKey))). Returns(CryptoUtils.StringToBytes("not secret anymore")); SafeListModel safes = new SafeListModel(new[] { new SafeModel { Id = Guid.NewGuid(), Key = safeKey }, }); NoteModel note = new NoteModel { Id = Guid.NewGuid(), HtmlContent = modelHtmlContent, SafeId = safes[0].Id }; NoteViewModel noteViewModel = new NoteViewModel( new Mock <INavigationService>().Object, new Mock <ILanguageService>().Object, new Mock <ISvgIconService>().Object, new Mock <IThemeService>().Object, new Mock <IBaseUrlService>().Object, searchableConverter, repositoryService.Object, new Mock <IFeedbackService>().Object, settingsService.Object, cryptor.Object, safes, new List <string>(), note); Assert.AreEqual("not secret anymore", noteViewModel.UnlockedHtmlContent); Assert.AreEqual("not secret anymore", noteViewModel.SearchableContent); }
private void ApplyFilter(string filter) { SettingsModel settings = _settingsService?.LoadSettingsOrDefault(); string normalizedFilter = SearchableHtmlConverter.NormalizeWhitespaces(filter); NoteFilter noteFilter = new NoteFilter(normalizedFilter); FilteredNotes.Clear(); foreach (NoteViewModel noteViewModel in AllNotes) { bool hideNote = noteViewModel.InRecyclingBin || (settings.HideClosedSafeNotes && noteViewModel.IsLocked) || !noteFilter.ContainsPattern(noteViewModel.SearchableContent); if (!hideNote) { FilteredNotes.Add(noteViewModel); } } }