--[[----------------------------------------------------------------------------

NmbDeletionBacklogTest.lua

--------------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2017 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remain the property of
Adobe Systems Incorporated and its suppliers, if any. The intellectual and
technical concepts contained herein are proprietary to Adobe Systems
Incorporated and its suppliers and may be covered by U.S. and Foreign
Patents, patents in process, and are protected by trade secret or copyright
law.  Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

------------------------------------------------------------------------------]]

	-- WF.core.self_test
local WFRxTestCase = require 'WFRxTestCase'


	-- WF.oz_client.managed_catalog
local WFCatMockCatalog = require 'WFCatMockCatalog'

	-- WF.core.utils
local KSPathUtils = require 'KSPathUtils'
local KSIdGenerator = require 'KSIdGenerator'
local WFFileUtils = require 'WFFileUtils'
local KSData = require 'KSData'

--============================================================================--

local NmbDeletionBacklogTest = {}

--------------------------------------------------------------------------------

local pathToOriginals = KSPathUtils.child( KSPathUtils.getStandardFilePath( 'testdata' ), KSIdGenerator.uuidInLowercaseHex() )
pathToOriginals = KSPathUtils.child( pathToOriginals, 'originals' )

local pathToProxies = KSPathUtils.child( KSPathUtils.getStandardFilePath( 'testdata' ), KSIdGenerator.uuidInLowercaseHex() )
pathToProxies = KSPathUtils.child( pathToProxies, 'proxies' )

local volumeGuid = WFFileUtils.getVolumeGuidForPath( pathToOriginals )

local mockImage = KSData.make( 'data' )

--------------------------------------------------------------------------------

local function setUp( rxTest, optOverrides )

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest, nil, nil, optOverrides )

	local deletionBacklog = wfCatalog:getDeletionBacklog()

	rxTest:finally( function()
	
		deletionBacklog:close()
	
	end )

	WFFileUtils.mkdir( pathToOriginals )
	WFFileUtils.mkdir( pathToProxies )
	
	return deletionBacklog, wfCatalog

end

--------------------------------------------------------------------------------

local function saveFile( data, path )

	local parent = KSPathUtils.parent( path )
	WFFileUtils.mkdir( parent )
	KSData.saveToFile( data, path )
	
end 

--------------------------------------------------------------------------------

local function basicDocValue( binaryType, isTracked )

	local maybeLocalOriginal 
	
	local path
	local relativePath
	
	if binaryType == 'original' then
	
		path = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
		relativePath = WFFileUtils.removeVolumeFromPath( path )
		
		if isTracked then
		
			maybeLocalOriginal = {
				master = {
					relativePath = relativePath,
					volumeGuid = volumeGuid,
				}
			}
			
		end
		
	end
	
	local maybeLocalProxy 
	
	if binaryType == 'proxy' then
	
		path = KSPathUtils.child( pathToProxies, KSIdGenerator.uuidInLowercaseHex() )
		relativePath = WFFileUtils.removeVolumeFromPath( path )
		
		if isTracked then
		
			maybeLocalProxy = {
				[ '2560' ] = {
					relativePath = relativePath,
					volumeGuid = volumeGuid,
				}
			}
		
		end
		
	end

	if path then
	
		saveFile( mockImage, path )
	
	end

	return {

		type = 'asset',
		subtype = 'image',
		
		importSource = {
			importTimestamp = "2015-05-26T17:34:23-07:00",
			fileName = "Image.jpg",
		},
		
		_localOnly = {
			isMarkedForOfflineUse = false,
			files = {
				original = maybeLocalOriginal,
				proxy = maybeLocalProxy
			}
		},

		_serverProvidedMetadata = {
			revision_ids = {
				KSIdGenerator.uuidInLowercaseHex()
			},
			links = {
			
				[ '/rels/master' ] = {
					href = 'path/to/original.jpg',
				},
				[ '/rels/proxy_type/2560' ] = {
					href = 'path/to/proxy.jpg',
				}
			}
		}

	}, relativePath, path
	
end

--------------------------------------------------------------------------------

local function createAsset( rxTest, wfCatalog, binaryType, isTracked )

	local docId = KSIdGenerator.uuidInLowercaseHex()
	local localId
	
	local docValue, relativePath, fullPath = basicDocValue( binaryType, isTracked )
	docValue._id = docId
	
	local docStore = wfCatalog:docStore()
	
	rxTest:expectSingleValue( docStore:setDocValue( docValue ), ':ignore:' )

	rxTest:expectSingleValue(
		docStore:docValue( docId )
			:map( function( docValue )
			
				localId = docValue._localId
				
				return true
				
			end ), true )

	return localId, volumeGuid, relativePath, fullPath

end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestBasic( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = '<guid>'
	local relativePath = 'I/AM/A/PATH'
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestDontDeleteTrackedAssets( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog, wfCatalog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	local originalId, origVolumeGuid, origRelativePath, fullOrigPath = createAsset( rxTest, wfCatalog, 'original', true )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( origVolumeGuid, origRelativePath, originalId, 'original' ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local proxyId, proxyVolumeGuid, proxyRelativePath, fullProxyPath = createAsset( rxTest, wfCatalog, 'proxy', true )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( proxyVolumeGuid, proxyRelativePath, proxyId, 'proxy' ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			binaryType = 'original',
			localId = 1,
			volumeGuid = origVolumeGuid,
			relativePath = origRelativePath
		},
		{
			binaryType = 'proxy',
			localId = 2,
			volumeGuid = proxyVolumeGuid,
			relativePath = proxyRelativePath
		},
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	rxTest:expectEqual( WFFileUtils.exists( fullOrigPath ), 'file' )
	rxTest:expectEqual( WFFileUtils.exists( fullProxyPath ), 'file' )

	rxTest:finally( function()
	
		WFFileUtils.delete( pathToOriginals )
		WFFileUtils.delete( pathToProxies )
		
	end )

end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestDeleteUntrackedAssets( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog, wfCatalog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	local originalId, origVolumeGuid, origRelativePath, fullOrigPath = createAsset( rxTest, wfCatalog, 'original', false )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( origVolumeGuid, origRelativePath, originalId, 'original' ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local proxyId, proxyVolumeGuid, proxyRelativePath, fullProxyPath = createAsset( rxTest, wfCatalog, 'proxy', false )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( proxyVolumeGuid, proxyRelativePath, proxyId, 'proxy' ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			binaryType = 'original',
			localId = 1,
			volumeGuid = origVolumeGuid,
			relativePath = origRelativePath
		},
		{
			binaryType = 'proxy',
			localId = 2,
			volumeGuid = proxyVolumeGuid,
			relativePath = proxyRelativePath
		},
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	rxTest:expectEqual( WFFileUtils.exists( fullOrigPath ), false )
	rxTest:expectEqual( WFFileUtils.exists( fullProxyPath ), false )

	rxTest:finally( function()
	
		WFFileUtils.delete( pathToOriginals )
		WFFileUtils.delete( pathToProxies )
		
	end )

end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestMixedDelete( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog, wfCatalog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	local originalId, origVolumeGuid, origRelativePath, fullOrigPath = createAsset( rxTest, wfCatalog, 'original', false )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( origVolumeGuid, origRelativePath, originalId, 'original' ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local _, proxyVolumeGuid, proxyRelativePath, fullProxyPath = createAsset( rxTest, wfCatalog, 'proxy', false )

	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( proxyVolumeGuid, proxyRelativePath ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			binaryType = 'original',
			localId = 1,
			volumeGuid = origVolumeGuid,
			relativePath = origRelativePath
		},
		{
			volumeGuid = proxyVolumeGuid,
			relativePath = proxyRelativePath
		},
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	rxTest:expectEqual( WFFileUtils.exists( fullOrigPath ), false )
	rxTest:expectEqual( WFFileUtils.exists( fullProxyPath ), false )

	rxTest:finally( function()
	
		WFFileUtils.delete( pathToOriginals )
		WFFileUtils.delete( pathToProxies )
		
	end )

end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestDeletionSucceeds( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = volumeGuid
	
	local filePath = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath )
	
	local relativePath = WFFileUtils.removeVolumeFromPath( filePath )
	
	local obs = rxTest:observe( deletionBacklog:DEBUG_processedDeletionBacklogStream() )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	obs:expectDataWithinTime( 5, 1 )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:finally( function()
	
		WFFileUtils.delete( filePath )
	
	end )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestMultipleDeletes( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = volumeGuid
	
	local filePath1 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath1 )
	
	local relativePath1 = WFFileUtils.removeVolumeFromPath( filePath1 )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath1 ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local filePath2 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath2 )
	
	local relativePath2 = WFFileUtils.removeVolumeFromPath( filePath2 )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath2 ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local filePath3 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath3 )
	
	local relativePath3 = WFFileUtils.removeVolumeFromPath( filePath3 )
	
	local obs = rxTest:observe( deletionBacklog:DEBUG_processedDeletionBacklogStream() )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath3 ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()

	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath1
		},
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath2
		},
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath3
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	obs:expectDataWithinTime( 5, 3 )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:finally( function()
	
		WFFileUtils.delete( filePath1 )
		WFFileUtils.delete( filePath2 )
		WFFileUtils.delete( filePath3 )
		
	end )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestDeletionFailsForOfflineAsset( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = KSIdGenerator.uuidInLowercaseHex()
	
	local filePath = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	
	local relativePath = WFFileUtils.removeVolumeFromPath( filePath )
	
	local obs = rxTest:observe( deletionBacklog:DEBUG_processedDeletionBacklogStream() )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	obs:expectDataWithinTime( 5, 0 )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestPathDoesNotExist( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = volumeGuid
	
	local filePath = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	
	local relativePath = WFFileUtils.removeVolumeFromPath( filePath )
	
	local obs = rxTest:observe( deletionBacklog:DEBUG_processedDeletionBacklogStream() )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	obs:expectDataWithinTime( 5, 1 )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestBuildWhereClause( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local onlineVolumeGuids = {
		'1',
		'2',
		'3'
	}

	local whereClause = deletionBacklog:DEBUG_buildDeletionBacklogWhereClause( onlineVolumeGuids )

	rxTest:expectSingleValue( whereClause, [[ WHERE ( volumeGuid = '1' OR volumeGuid = '2' OR volumeGuid = '3' )]] )

	onlineVolumeGuids = {'1'}

	whereClause = deletionBacklog:DEBUG_buildDeletionBacklogWhereClause( onlineVolumeGuids )
	
	rxTest:expectSingleValue( whereClause, [[ WHERE ( volumeGuid = '1' )]] )
	
	onlineVolumeGuids = {}
	
	whereClause = deletionBacklog:DEBUG_buildDeletionBacklogWhereClause( onlineVolumeGuids )
	
	rxTest:expectSingleValue( whereClause, [[ WHERE ( volumeGuid = '' )]] )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestBringDeletionBacklogUpToDate( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = '<guid>'
	local relativePath = 'I/AM/A/PATH'
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents( true )
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestProcessDeletionBacklog( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = volumeGuid
	local filePath = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	local relativePath = WFFileUtils.removeVolumeFromPath( filePath )
	
	rxTest:expectSingleValue( deletionBacklog:addToDeletionBacklog( volumeGuid, relativePath ), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end

--------------------------------------------------------------------------------

function NmbDeletionBacklogTest.rxTestBulkAddToDeletionBacklog( rxTest )

	local args = {
		writeInterval = 60,
		processBacklogDelay = 60
	}

	local deletionBacklog = setUp( rxTest, args )

	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = volumeGuid
	
	local filePath1 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath1 )
	
	local relativePath1 = WFFileUtils.removeVolumeFromPath( filePath1 )

	local files = {}

	table.insert( files, {
		volumeGuid = volumeGuid,
		relativePath = relativePath1
	} )

	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local filePath2 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath2 )
	
	local relativePath2 = WFFileUtils.removeVolumeFromPath( filePath2 )
	
	table.insert( files, {
		volumeGuid = volumeGuid,
		relativePath = relativePath2
	} )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	local filePath3 = KSPathUtils.child( pathToOriginals, KSIdGenerator.uuidInLowercaseHex() )
	saveFile( mockImage, filePath3 )
	
	table.insert( files, {
		absolutePath = filePath3,
	} )
	
	rxTest:expectSingleValue( deletionBacklog:bulkAddToDeletionBacklog( files ), true )
	
	deletionBacklog:bringDeletionBacklogUpToDate()
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
			:map( function( dump )
			
				for _, entry in ipairs( dump ) do
				
					entry.relativePath = '<path>'
				
				end
			
				return dump
			
			end )

	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = '<path>'
		},
		{
			volumeGuid = volumeGuid,
			relativePath = '<path>'
		},
		{
			volumeGuid = volumeGuid,
			relativePath = '<path>'
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:expectSingleValue( deletionBacklog:processDeletionBacklog(), true )
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	rxTest:finally( function()
	
		WFFileUtils.delete( filePath1 )
		WFFileUtils.delete( filePath2 )
		WFFileUtils.delete( filePath3 )
		
	end )
	
end

--------------------------------------------------------------------------------

--[[
function NmbDeletionBacklogTest.rxTestTransferTableContents( rxTest )

	local deletionBacklog = setUp( rxTest )

	local db = deletionBacklog.private._getDb( deletionBacklog )
	local _transferTableContentsFn = deletionBacklog.private._transferTableContents
	
	local dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	local expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	local volumeGuid = '<guid>'
	local relativePath = 'I/AM/A/PATH'
	
	local insertSQL = "INSERT OR IGNORE INTO deletionBacklog( volumeGuid, relativePath ) VALUES( ?, ? )"
	db:exec( insertSQL, volumeGuid, relativePath )
	
	local volumeGuid2 = '<guid2>'
	local relativePath2 = 'I/AM/A/PATH2'
	db:exec( insertSQL, volumeGuid2, relativePath2 )
	
	local volumeGuid3 = '<guid3>'
	local relativePath3 = 'I/AM/A/PATH3'
	db:exec( insertSQL, volumeGuid3, relativePath3 )
	
	local volumeGuid4 = '<guid4>'
	local relativePath4 = 'I/AM/A/PATH4'
	db:exec( insertSQL, volumeGuid4, relativePath4 )
	
	local volumeGuid5 = '<guid5>'
	local relativePath5 = 'I/AM/A/PATH5'
	db:exec( insertSQL, volumeGuid5, relativePath5 )
	
	-- Verify the v1 table has the expected contents.
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContentsV1()	

	expectedDump = {
		{
			volumeGuid,
			relativePath
		},
		{
			volumeGuid2,
			relativePath2
		},
		{
			volumeGuid3,
			relativePath3
		},
		{
			volumeGuid4,
			relativePath4
		},
		{
			volumeGuid5,
			relativePath5
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )

	-- Verify the v2 Table is empty.

	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	-- This should transfer the info from the deletionBacklog to the new table.
	
	_transferTableContentsFn( deletionBacklog )
	
	-- Verify the old table is now empty.
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContentsV1()	

	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	-- Check the V2 Table for contents.
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		},
		{
			volumeGuid = volumeGuid2,
			relativePath = relativePath2
		},
		{
			volumeGuid = volumeGuid3,
			relativePath = relativePath3
		},
		{
			volumeGuid = volumeGuid4,
			relativePath = relativePath4
		},
		{
			volumeGuid = volumeGuid5,
			relativePath = relativePath5
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	-- This should be a no-op
	
	_transferTableContentsFn( deletionBacklog )
	
	-- Verify the old table is still empty.
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContentsV1()	

	expectedDump = {}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
	-- Check the V2 Table contents haven't changed.
	
	dataDump = deletionBacklog:DEBUG_dumpDeletionBacklogContents()
	
	expectedDump = {
		{
			volumeGuid = volumeGuid,
			relativePath = relativePath
		},
		{
			volumeGuid = volumeGuid2,
			relativePath = relativePath2
		},
		{
			volumeGuid = volumeGuid3,
			relativePath = relativePath3
		},
		{
			volumeGuid = volumeGuid4,
			relativePath = relativePath4
		},
		{
			volumeGuid = volumeGuid5,
			relativePath = relativePath5
		}
	}
	
	rxTest:expectSingleValue( dataDump, expectedDump )
	
end
]]--

--------------------------------------------------------------------------------

return WFRxTestCase.wrapSuite( 'NmbDeletionBacklogTest', NmbDeletionBacklogTest )
