2020-05-19 10:10:46 +00:00
using Flow.Launcher.Plugin ;
2020-05-11 13:19:41 +00:00
using Flow.Launcher.Plugin.Explorer ;
2020-05-19 10:10:46 +00:00
using Flow.Launcher.Plugin.Explorer.Search ;
2020-05-27 22:55:41 +00:00
using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo ;
2020-05-11 13:19:41 +00:00
using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex ;
2020-05-24 10:14:36 +00:00
using Flow.Launcher.Plugin.SharedCommands ;
2020-05-11 13:15:15 +00:00
using NUnit.Framework ;
2020-05-11 13:19:41 +00:00
using System ;
2020-05-19 10:10:46 +00:00
using System.Collections.Generic ;
2021-01-03 02:52:59 +00:00
using System.Threading ;
using System.Threading.Tasks ;
2020-05-11 13:15:15 +00:00
namespace Flow.Launcher.Test.Plugins
{
2020-06-12 11:19:55 +00:00
/// <summary>
/// These tests require the use of CSearchManager class from Microsoft.Search.Interop.
/// Windows Search service needs to be running to complete the tests
/// </summary>
2020-05-11 13:15:15 +00:00
[TestFixture]
public class ExplorerTest
{
2021-01-03 02:52:59 +00:00
private async Task < List < Result > > MethodWindowsIndexSearchReturnsZeroResultsAsync ( Query dummyQuery , string dummyString , CancellationToken dummyToken )
2020-05-19 10:10:46 +00:00
{
return new List < Result > ( ) ;
}
2021-01-19 14:46:18 +00:00
private List < Result > MethodDirectoryInfoClassSearchReturnsTwoResults ( Query dummyQuery , string dummyString , CancellationToken token )
2020-05-19 10:10:46 +00:00
{
2021-01-03 02:52:59 +00:00
return new List < Result >
{
2020-05-19 10:10:46 +00:00
new Result
{
Title = "Result 1"
} ,
new Result
{
Title = "Result 2"
}
} ;
}
2020-05-26 10:18:18 +00:00
private bool PreviousLocationExistsReturnsTrue ( string dummyString ) = > true ;
2020-05-26 09:49:18 +00:00
2020-05-26 10:18:18 +00:00
private bool PreviousLocationNotExistReturnsFalse ( string dummyString ) = > false ;
2020-05-26 09:49:18 +00:00
2020-05-28 08:23:00 +00:00
[TestCase("C:\\SomeFolder\\", "directory='file:C:\\SomeFolder\\'")]
2020-05-11 19:56:51 +00:00
public void GivenWindowsIndexSearch_WhenProvidedFolderPath_ThenQueryWhereRestrictionsShouldUseDirectoryString ( string path , string expectedString )
2020-05-11 13:19:41 +00:00
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
// When
2020-05-11 19:56:51 +00:00
var folderPath = path ;
var result = queryConstructor . QueryWhereRestrictionsForTopLevelDirectorySearch ( folderPath ) ;
2020-05-11 13:19:41 +00:00
// Then
Assert . IsTrue ( result = = expectedString ,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual: {result}{Environment.NewLine}" ) ;
}
2020-05-11 13:15:15 +00:00
2021-01-23 03:32:41 +00:00
[TestCase("C:\\", "SELECT TOP 100 System.FileName, System.ItemUrl, System.ItemType FROM SystemIndex WHERE directory='file:C:\\' ORDER BY System.FileName")]
[TestCase("C:\\SomeFolder\\", "SELECT TOP 100 System.FileName, System.ItemUrl, System.ItemType FROM SystemIndex WHERE directory='file:C:\\SomeFolder\\' ORDER BY System.FileName")]
2020-05-28 08:23:00 +00:00
public void GivenWindowsIndexSearch_WhenSearchTypeIsTopLevelDirectorySearch_ThenQueryShouldUseExpectedString ( string folderPath , string expectedString )
2020-05-11 20:50:17 +00:00
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
2021-01-03 02:52:59 +00:00
2020-05-11 20:50:17 +00:00
//When
var queryString = queryConstructor . QueryForTopLevelDirectorySearch ( folderPath ) ;
2021-01-03 02:52:59 +00:00
2020-05-19 10:10:46 +00:00
// Then
2020-05-11 20:50:17 +00:00
Assert . IsTrue ( queryString = = expectedString ,
2020-05-26 09:34:45 +00:00
$"Expected string: {expectedString}{Environment.NewLine} " +
2020-05-11 20:50:17 +00:00
$"Actual string was: {queryString}{Environment.NewLine}" ) ;
}
2020-08-23 22:21:16 +00:00
[ TestCase ( "C:\\SomeFolder\\flow.launcher.sln" , "SELECT TOP 100 System.FileName, System.ItemUrl, System.ItemType " +
2020-05-28 08:23:00 +00:00
"FROM SystemIndex WHERE (System.FileName LIKE 'flow.launcher.sln%' " +
2020-05-26 09:35:30 +00:00
"OR CONTAINS(System.FileName,'\"flow.launcher.sln*\"',1033))" +
2021-01-23 03:32:41 +00:00
" AND directory='file:C:\\SomeFolder' ORDER BY System.FileName" ) ]
2020-05-26 09:35:30 +00:00
public void GivenWindowsIndexSearchTopLevelDirectory_WhenSearchingForSpecificItem_ThenQueryShouldUseExpectedString (
string userSearchString , string expectedString )
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
//When
var queryString = queryConstructor . QueryForTopLevelDirectorySearch ( userSearchString ) ;
// Then
Assert . IsTrue ( queryString = = expectedString ,
$"Expected string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {queryString}{Environment.NewLine}" ) ;
}
2020-05-27 22:06:49 +00:00
[ TestCase ( "C:\\SomeFolder\\SomeApp" , "(System.FileName LIKE 'SomeApp%' " +
"OR CONTAINS(System.FileName,'\"SomeApp*\"',1033))" +
" AND directory='file:C:\\SomeFolder'" ) ]
2020-05-26 09:35:30 +00:00
public void GivenWindowsIndexSearchTopLevelDirectory_WhenSearchingForSpecificItem_ThenQueryWhereRestrictionsShouldUseDirectoryString (
string userSearchString , string expectedString )
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
//When
var queryString = queryConstructor . QueryWhereRestrictionsForTopLevelDirectorySearch ( userSearchString ) ;
// Then
Assert . IsTrue ( queryString = = expectedString ,
$"Expected string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {queryString}{Environment.NewLine}" ) ;
}
2020-05-18 10:14:38 +00:00
[TestCase("scope='file:'")]
2021-01-03 02:52:59 +00:00
public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryWhereRestrictionsShouldUseScopeString ( string expectedString )
2020-05-18 10:14:38 +00:00
{
//When
2021-01-23 02:59:37 +00:00
var resultString = QueryConstructor . QueryWhereRestrictionsForAllFilesAndFoldersSearch ;
2020-05-18 10:14:38 +00:00
2020-05-19 10:10:46 +00:00
// Then
2020-05-18 10:14:38 +00:00
Assert . IsTrue ( resultString = = expectedString ,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}" ) ;
}
2020-08-23 22:21:16 +00:00
[ TestCase ( "flow.launcher.sln" , "SELECT TOP 100 \"System.FileName\", \"System.ItemUrl\", \"System.ItemType\" " +
2020-05-18 10:14:38 +00:00
"FROM \"SystemIndex\" WHERE (System.FileName LIKE 'flow.launcher.sln%' " +
2021-01-23 03:32:41 +00:00
"OR CONTAINS(System.FileName,'\"flow.launcher.sln*\"',1033)) AND scope='file:' ORDER BY System.FileName" ) ]
2020-05-18 10:14:38 +00:00
public void GivenWindowsIndexSearch_WhenSearchAllFoldersAndFiles_ThenQueryShouldUseExpectedString (
2021-01-03 02:52:59 +00:00
string userSearchString , string expectedString )
2020-05-18 10:14:38 +00:00
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
2021-07-18 10:34:17 +00:00
var baseQuery = queryConstructor . CreateBaseQuery ( ) ;
2021-07-18 12:40:53 +00:00
// system running this test could have different locale than the hard-coded 1033 LCID en-US.
2021-07-18 10:34:17 +00:00
var queryKeywordLocale = baseQuery . QueryKeywordLocale ;
expectedString = expectedString . Replace ( "1033" , queryKeywordLocale . ToString ( ) ) ;
2020-05-18 10:14:38 +00:00
//When
var resultString = queryConstructor . QueryForAllFilesAndFolders ( userSearchString ) ;
2020-05-19 10:10:46 +00:00
// Then
2020-05-18 10:14:38 +00:00
Assert . IsTrue ( resultString = = expectedString ,
$"Expected query string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}" ) ;
}
2020-05-11 13:15:15 +00:00
2020-05-19 10:10:46 +00:00
[TestCase]
2021-01-03 02:52:59 +00:00
public async Task GivenTopLevelDirectorySearch_WhenIndexSearchNotRequired_ThenSearchMethodShouldContinueDirectoryInfoClassSearch ( )
2020-05-19 10:10:46 +00:00
{
// Given
2020-05-19 12:36:56 +00:00
var searchManager = new SearchManager ( new Settings ( ) , new PluginInitContext ( ) ) ;
2021-01-03 02:52:59 +00:00
2020-05-19 10:10:46 +00:00
// When
2021-01-03 02:52:59 +00:00
var results = await searchManager . TopLevelDirectorySearchBehaviourAsync (
MethodWindowsIndexSearchReturnsZeroResultsAsync ,
MethodDirectoryInfoClassSearchReturnsTwoResults ,
false ,
2020-05-24 10:14:36 +00:00
new Query ( ) ,
2021-01-03 02:52:59 +00:00
"string not used" ,
default ) ;
2020-05-19 10:10:46 +00:00
// Then
Assert . IsTrue ( results . Count = = 2 ,
$"Expected to have 2 results from DirectoryInfoClassSearch {Environment.NewLine} " +
$"Actual number of results is {results.Count} {Environment.NewLine}" ) ;
}
[TestCase]
2021-01-03 02:52:59 +00:00
public async Task GivenTopLevelDirectorySearch_WhenIndexSearchNotRequired_ThenSearchMethodShouldNotContinueDirectoryInfoClassSearch ( )
2020-05-19 10:10:46 +00:00
{
// Given
2020-05-19 12:36:56 +00:00
var searchManager = new SearchManager ( new Settings ( ) , new PluginInitContext ( ) ) ;
2020-05-19 10:10:46 +00:00
// When
2021-01-03 02:52:59 +00:00
var results = await searchManager . TopLevelDirectorySearchBehaviourAsync (
MethodWindowsIndexSearchReturnsZeroResultsAsync ,
2020-05-19 10:10:46 +00:00
MethodDirectoryInfoClassSearchReturnsTwoResults ,
2020-05-31 22:03:04 +00:00
true ,
2020-05-24 10:14:36 +00:00
new Query ( ) ,
2021-01-03 02:52:59 +00:00
"string not used" ,
default ) ;
2020-05-19 10:10:46 +00:00
// Then
Assert . IsTrue ( results . Count = = 0 ,
$"Expected to have 0 results because location is indexed {Environment.NewLine} " +
$"Actual number of results is {results.Count} {Environment.NewLine}" ) ;
}
2020-05-11 13:15:15 +00:00
2020-07-12 11:51:30 +00:00
[TestCase(@"some words", @"FREETEXT('some words')")]
public void GivenWindowsIndexSearch_WhenQueryWhereRestrictionsIsForFileContentSearch_ThenShouldReturnFreeTextString (
string querySearchString , string expectedString )
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
//When
var resultString = queryConstructor . QueryWhereRestrictionsForFileContentSearch ( querySearchString ) ;
// Then
Assert . IsTrue ( resultString = = expectedString ,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}" ) ;
}
2020-08-23 22:21:16 +00:00
[ TestCase ( "some words" , "SELECT TOP 100 System.FileName, System.ItemUrl, System.ItemType " +
2021-01-23 03:32:41 +00:00
"FROM SystemIndex WHERE FREETEXT('some words') AND scope='file:' ORDER BY System.FileName" ) ]
2020-07-12 11:51:30 +00:00
public void GivenWindowsIndexSearch_WhenSearchForFileContent_ThenQueryShouldUseExpectedString (
string userSearchString , string expectedString )
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
//When
var resultString = queryConstructor . QueryForFileContentSearch ( userSearchString ) ;
// Then
Assert . IsTrue ( resultString = = expectedString ,
$"Expected query string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}" ) ;
}
2020-07-19 12:24:02 +00:00
public void GivenQuery_WhenActionKeywordForFileContentSearchExists_ThenFileContentSearchRequiredShouldReturnTrue ( )
2020-07-12 12:41:01 +00:00
{
// Given
2020-07-19 12:24:02 +00:00
var query = new Query { ActionKeyword = "doc:" , Search = "search term" } ;
2020-07-12 12:41:01 +00:00
2020-07-19 12:24:02 +00:00
var searchManager = new SearchManager ( new Settings ( ) , new PluginInitContext ( ) ) ;
2021-01-03 02:52:59 +00:00
2020-07-12 12:41:01 +00:00
// When
2020-07-19 12:24:02 +00:00
var result = searchManager . IsFileContentSearch ( query . ActionKeyword ) ;
2020-07-12 12:41:01 +00:00
// Then
Assert . IsTrue ( result ,
$"Expected True for file content search. {Environment.NewLine} " +
$"Actual result was: {result}{Environment.NewLine}" ) ;
}
2020-05-19 12:36:56 +00:00
[TestCase(@"c:\\", false)]
[TestCase(@"i:\", true)]
[TestCase(@"\c:\", false)]
[TestCase(@"cc:\", false)]
[TestCase(@"\\\SomeNetworkLocation\", false)]
2020-05-28 08:23:00 +00:00
[TestCase("RandomFile", false)]
2021-01-24 09:51:56 +00:00
[TestCase(@"c:\>*", true)]
[TestCase(@"c:\>", true)]
[TestCase(@"c:\SomeLocation\SomeOtherLocation\>", true)]
2020-05-28 08:23:00 +00:00
public void WhenGivenQuerySearchString_ThenShouldIndicateIfIsLocationPathString ( string querySearchString , bool expectedResult )
2020-05-19 12:36:56 +00:00
{
// When, Given
2020-05-24 10:14:36 +00:00
var result = FilesFolders . IsLocationPathString ( querySearchString ) ;
2020-05-19 12:36:56 +00:00
//Then
Assert . IsTrue ( result = = expectedResult ,
$"Expected query search string check result is: {expectedResult} {Environment.NewLine} " +
$"Actual check result is {result} {Environment.NewLine}" ) ;
}
2021-01-03 02:52:59 +00:00
2020-05-27 22:06:49 +00:00
[TestCase(@"C:\SomeFolder\SomeApp", true, @"C:\SomeFolder\")]
[TestCase(@"C:\SomeFolder\SomeApp\SomeFile", true, @"C:\SomeFolder\SomeApp\")]
[TestCase(@"C:\NonExistentFolder\SomeApp", false, "")]
2020-05-26 10:18:18 +00:00
public void GivenAPartialPath_WhenPreviousLevelDirectoryExists_ThenShouldReturnThePreviousDirectoryPathString (
string path , bool previousDirectoryExists , string expectedString )
2020-05-26 09:49:18 +00:00
{
2020-05-26 10:18:18 +00:00
// When
Func < string , bool > previousLocationExists = null ;
if ( previousDirectoryExists )
{
previousLocationExists = PreviousLocationExistsReturnsTrue ;
}
else
{
previousLocationExists = PreviousLocationNotExistReturnsFalse ;
}
2020-05-26 09:49:18 +00:00
2020-05-26 10:18:18 +00:00
// Given
var previousDirectoryPath = FilesFolders . GetPreviousExistingDirectory ( previousLocationExists , path ) ;
2020-05-26 09:49:18 +00:00
2020-05-26 10:18:18 +00:00
//Then
Assert . IsTrue ( previousDirectoryPath = = expectedString ,
$"Expected path string: {expectedString} {Environment.NewLine} " +
$"Actual path string is {previousDirectoryPath} {Environment.NewLine}" ) ;
2020-05-26 09:49:18 +00:00
}
2020-05-25 08:58:28 +00:00
2020-05-28 11:33:18 +00:00
[TestCase(@"C:\NonExistentFolder\SomeApp", @"C:\NonExistentFolder\")]
[TestCase(@"C:\NonExistentFolder\SomeApp\", @"C:\NonExistentFolder\SomeApp\")]
public void WhenGivenAPath_ThenShouldReturnThePreviousDirectoryPathIfIncompleteOrOriginalString (
string path , string expectedString )
{
2020-06-02 10:21:28 +00:00
var returnedPath = FilesFolders . ReturnPreviousDirectoryIfIncompleteString ( path ) ;
2020-05-28 11:33:18 +00:00
//Then
Assert . IsTrue ( returnedPath = = expectedString ,
$"Expected path string: {expectedString} {Environment.NewLine} " +
$"Actual path string is {returnedPath} {Environment.NewLine}" ) ;
}
2020-05-27 22:06:49 +00:00
[TestCase("c:\\SomeFolder\\>", "scope='file:c:\\SomeFolder'")]
2021-01-23 03:32:41 +00:00
[ TestCase ( "c:\\SomeFolder\\>SomeName" , "(System.FileName LIKE 'SomeName%' "
+ "OR CONTAINS(System.FileName,'\"SomeName*\"',1033)) AND "
+ "scope='file:c:\\SomeFolder'" ) ]
2021-01-03 02:52:59 +00:00
public void GivenWindowsIndexSearch_WhenSearchPatternHotKeyIsSearchAll_ThenQueryWhereRestrictionsShouldUseScopeString ( string path , string expectedString )
2020-05-27 21:38:41 +00:00
{
// Given
var queryConstructor = new QueryConstructor ( new Settings ( ) ) ;
//When
var resultString = queryConstructor . QueryWhereRestrictionsForTopLevelDirectoryAllFilesAndFoldersSearch ( path ) ;
// Then
Assert . IsTrue ( resultString = = expectedString ,
$"Expected QueryWhereRestrictions string: {expectedString}{Environment.NewLine} " +
$"Actual string was: {resultString}{Environment.NewLine}" ) ;
}
2020-05-27 22:55:41 +00:00
2021-01-03 02:52:59 +00:00
[TestCase("c:\\somefolder\\>somefile", "*somefile*")]
2020-05-27 22:55:41 +00:00
[TestCase("c:\\somefolder\\somefile", "somefile*")]
[TestCase("c:\\somefolder\\", "*")]
public void GivenDirectoryInfoSearch_WhenSearchPatternHotKeyIsSearchAll_ThenSearchCriteriaShouldUseCriteriaString ( string path , string expectedString )
{
//When
2021-01-29 10:40:51 +00:00
var resultString = DirectoryInfoSearch . ConstructSearchCriteria ( path ) ;
2020-05-27 22:55:41 +00:00
// Then
Assert . IsTrue ( resultString = = expectedString ,
$"Expected criteria string: {expectedString}{Environment.NewLine} " +
$"Actual criteria string was: {resultString}{Environment.NewLine}" ) ;
}
2020-05-11 13:15:15 +00:00
}
}