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

WFRxIndexStoreSchemaVersionListTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2020 Adobe
All Rights Reserved.

NOTICE: All information contained herein is, and remains
the property of Adobe and its suppliers, if any. The intellectual
and technical concepts contained herein are proprietary to Adobe
and its suppliers and are protected by all applicable intellectual
property laws, including trade secret and copyright laws.
Dissemination of this information or reproduction of this material
is strictly forbidden unless prior written permission is obtained
from Adobe.

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

-- /$$      /$$  /$$$$$$  /$$$$$$$  /$$   /$$ /$$$$$$ /$$   /$$  /$$$$$$
--| $$  /$ | $$ /$$__  $$| $$__  $$| $$$ | $$|_  $$_/| $$$ | $$ /$$__  $$
--| $$ /$$$| $$| $$  \ $$| $$  \ $$| $$$$| $$  | $$  | $$$$| $$| $$  \__/
--| $$/$$ $$ $$| $$$$$$$$| $$$$$$$/| $$ $$ $$  | $$  | $$ $$ $$| $$ /$$$$
--| $$$$_  $$$$| $$__  $$| $$__  $$| $$  $$$$  | $$  | $$  $$$$| $$|_  $$
--| $$$/ \  $$$| $$  | $$| $$  \ $$| $$\  $$$  | $$  | $$\  $$$| $$  \ $$
--| $$/   \  $$| $$  | $$| $$  | $$| $$ \  $$ /$$$$$$| $$ \  $$|  $$$$$$/
--|__/     \__/|__/  |__/|__/  |__/|__/  \__/|______/|__/  \__/ \______/
--==============================================================================

-- BEFORE MODIFYING THIS FILE, PLEASE READ AND UNDERSTAND:

-- https://git.corp.adobe.com/lua/wf/blob/main/doc/reindexing.md

-- REACH OUT ON THE #WF SLACK CHANNEL WITH QUESTIONS.

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

	-- Rx
local Rx = require 'Rx'

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

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'
local KSLuaUtils = require 'KSLuaUtils'
local KSTableUtils = require 'KSTableUtils'
local WFCapabilities = require 'WFCapabilities'
local WFLogger = require 'WFLogger'
local WFPlatformInfo = require 'WFPlatformInfo'
local WFTableArchiving = require 'WFTableArchiving'
local WFTableMerge = require 'WFTableMerge'

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

	-- WF.sqlite.doc_store
local WFRxDocStore = require 'WFRxDocStore'
local WFRxIndexStore = require 'WFRxIndexStore'

	-- WF.sqlite.index_store
local WFRxIndexStoreImpUtils = require 'WFRxIndexStoreImpUtils'
local WFRxIndexStoreSchemaVersionList = require 'WFRxIndexStoreSchemaVersionList'

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

-- @mark WFRxIndexStoreSchemaVersionListTest namespace

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

local WFRxIndexStoreSchemaVersionListTest = {}

--==============================================================================
-- @mark Test Setup & Teardown
--==============================================================================

local logger = WFLogger( 'WFRxIndexStoreSchemaVersionListTest' )

local docStore, indexStore, coveragePath

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

function WFRxIndexStoreSchemaVersionListTest.setUp( inCoveragePath )

	coveragePath = inCoveragePath

end

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

function WFRxIndexStoreSchemaVersionListTest.tearDown()

	local obs = {}

	if coveragePath then
		if indexStore then
			obs[ #obs + 1 ] = indexStore:DEBUG_dumpCoverage( coveragePath )
		end
		coveragePath = nil
	end

	if indexStore then
		local oldIndexStore = indexStore
		obs[ #obs + 1 ] = indexStore:haltAndDelete()
			:tapOnCompleted( function()
				oldIndexStore:close()
			end )
		indexStore = nil
	end

	if docStore then
		local oldDocStore = docStore
		obs[ #obs + 1 ] = docStore:haltAndDelete()
			:tapOnCompleted( function()
				oldDocStore:close()
			end )
		docStore = nil
	end

	return Rx.Observable.concat( unpack( obs ) )
		:call( require 'WFRxRunUntilDone' )

end

--==============================================================================
-- @mark Expected Index Store Table Hashes
--==============================================================================

-- The way knownIndexStoreTableHashesAndInfo is built, it may contain entries
-- for tables that are not indexed by a specific platform.

local function getCatalogSpec()

	local catalogSpec
	
	if WFPlatformInfo.isDesktop then
		
		if WFPlatformInfo.isClassic() then
		
			catalogSpec = "LrClassicIndexDefinitions.lua"
			
		else 
		
			catalogSpec = "WFCatIndexDefinitions.lua"
			
		end
		
	else
	
		catalogSpec = "LrmCatalogIndexDefinitions.lua"
			
	end
	
	return catalogSpec
end

local function getKnownIndexStoreTableHashesAndInfo()
	
	local knownIndexStoreTableHashesAndInfo =
		{
			album_asset_v2 = {
				mapFunctionHash = "e1911888f28f1a9a7645af31b97cd9a7",
				relevantTypeSubtypeTuples = {
					{
						"album_asset",
						"NULL",
					},
				},
				sqlSchemaHash = "abb2b4babd963524da42badc899cc92b",
			},
			albums = {
				mapFunctionHash = "79731e28e3008ade850452a4f4c169c9",
				relevantTypeSubtypeTuples = {
					{
						"album",
						"collection",
					},
					{
						"album",
						"collection_set",
					},
				},
				sqlSchemaHash = "a904ff98a3e2eac0244956a1e0b29dcf",
			},
			archivedFiles = {
				mapFunctionHash = "93da033aac59498fa2d18eb6219da168",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "6f41641552bdcfe6a9630d593933d01f",
			},
			assetEnhanced = {
				mapFunctionHash = "f19377a195b5671b1fe5aacfc0c3f0fb",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "5ada4de514ae56ee417f3a72b9865dfe",
			},
			assetPathsAndInfo = {
				mapFunctionHash = "2a136fa7b9d6439d25e6692efbd3c9e4",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "23a33a22c24d188727e0b4a70a485292",
			},
			assetReferredCameraProfile = {
				mapFunctionHash = "6cae8ed802b4612a214b908b203bbb91",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
				},
				sqlSchemaHash = "42bb514a371a5d2721a986b1c38e7b73",
			},
			asset_importedByUser = {
				docValueFilter = "40978ec7b85325046f3e65585b6440c0",
				mapFunctionHash = "7e5b880b0f5298f244fcd74784f0b4a3",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "f79df49514d02662f2cf79c195dce4e5",
			},
			asset_sync_local_file_type_ui = {
				docValueFilter = "f50b4fc60d2210ee1bc68ef80bfd33ed",
				mapFunctionHash = "b50cfa0f94b474a66f920e0cfb6ae589",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "184acbf062a20bcb6eb881451394c0e5",
			},
			asset_sync_status_ui = {
				mapFunctionHash = "a1e01ade3c6f2789ba7fb44f9d79d753",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "c28c1a401f118190a1741b1d67107be5",
			},
			assets = {
				mapFunctionHash = "0557c5f5aedd6c123d614a39b0d401bd",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"stack",
					},
				},
				sqlSchemaHash = "062baf4f6e5be5c2ef8a3aac83a8dd2f",
			},
			assetsNeedingCameraProfileLinks = {
				mapFunctionHash = "cb896a42525a4caeee12dbaedd812982",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
				},
				sqlSchemaHash = "1e4575668b89cec576d750955177764e",
			},
			assetsPendingRestore = {
				includeDocumentsFromSource = "catalog",
				mapFunctionHash = "2633b3347de725bc6c601c522866f777",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "664f5fdf0975ff8f8ec7cfd4fcf2f5b1",
			},
			auxReferenceTracker = {
				mapFunctionHash = "89fa68262292d8d5f0b8b73ee72a5f7b",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "08ecc46083f864ca6f37119fc86ba316",
			},
			blocked_uploads = {
				mapFunctionHash = "535edc6542dc787a7b93b6a8b747d52f",
				relevantTypeSubtypeTuples = {
					{
						"*",
						"*",
					},
				},
				sqlSchemaHash = "9d08da181b53f12af562faf2012a0b2b",
			},
			cameraModelsInUse = {
				docValueFilter = "5468b204381ed036a238258698cd7079",
				mapFunctionHash = "74d2c5a6d75b3e3818e74f59d52903e9",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
				},
				sqlSchemaHash = "39097a46308d1b5c0d3edd0f343399e1",
			},
			cameras = {
				mapFunctionHash = "330fc036975fd82b27558b1dad5faeed",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "4198498e1e44475aee70a695d9f1251e",
			},
			captureDate = {
				mapFunctionHash = "084029467259a3b62c15662c87fa2fbb",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "85b0abf7efea89784efc636dd1096ce5",
			},
			comment = {
				mapFunctionHash = "901fa6ddab7b7d09c441f077d47bb02c",
				relevantTypeSubtypeTuples = {
					{
						"comment",
						"user",
					},
				},
				sqlSchemaHash = "45a3f863bec049b3c57d5b9314fe573c",
			},
			conflicts = {
				mapFunctionHash = "c5005664c695badeffcae7d3ff25be98",
				relevantTypeSubtypeTuples = {
					{
						"*",
						"*",
					},
				},
				sqlSchemaHash = "86dbb5aa202777ec775aeb5b9198a21a",
			},
			customCameraProfiles = {
				mapFunctionHash = "8f1969600a018380ba349be56213b1b9",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"camera_profile",
					},
				},
				sqlSchemaHash = "91800711c76bce8c76d1015d25c98383",
			},
			unconfirmedDeletions = {
				mapFunctionHash = "60813769548c123af9b4499fdc6c4260",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "cfda774622dd87f6759dd73171efb2f8",
			},
			docsToUpdate = {
				mapFunctionHash = "0c3eb878c704b24f7fe3211991e2c468",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"version",
						"*",
					},
				},
				sqlSchemaHash = "ae08aeb8fd1fbdd46a75d36dace3c442",
			},
			editedDate = {
				mapFunctionHash = "465315a0c60bd964bc0d2773b6fb8da5",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "769b62f2a06c425b597627fa6dbbf0c8",
			},
			errors = {
				mapFunctionHash = "e8a290daadbf18ae5d2b194bbc1031c8",
				relevantTypeSubtypeTuples = {
					{
						"error",
						"*",
					},
				},
				sqlSchemaHash = "f2f1826efd3d98b0fb4edcc15cfc413e",
			},
			extensions = {
				mapFunctionHash = "03b0afd25cfe015c0fa2036830487b0c",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "f573fd6e09b9bc06dc7a1818228b85a4",
			},
			externalDevelopSettings = {
				mapFunctionHash = "13109e98398112756002efb62fa4aaa0",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "f24ef0d368c4c03d602ace0ae643c3b2",
			},
			faces = {
				mapFunctionHash = "8be011a1c1e2d6a0fad5f4b1d56b8612",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "cd5faa297bc2a192f622bd6461c28001",
			},
			feedback_user = {
				mapFunctionHash = "eda8717d1f2fae3f310d9cd619b92572",
				relevantTypeSubtypeTuples = {
					{
						"feedbackuser",
						"NULL",
					},
				},
				sqlSchemaHash = "36e6399225ce7a527c2a997938bc49f1",
			},
			importSource = {
				mapFunctionHash = "f2f0d8eb5766875b190710260e95d6cc",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "227dfb4ba6164ac23155437ca7b4fb08",
			},
			importTime = {
				mapFunctionHash = "248cfb6873b2a796da3afb664ece4333",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "97d01e0922d61b74587b7071f8795282",
			},
			keywords = {
				docValueFilter = "cf4862dd9434b1ec708123142aa41598",
				mapFunctionHash = "9d1297be4e528e5f222eff2363ead98c",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "733845ff4443bb2d7a2647e3db2672db",
			},
			localAuxTracker = {
				mapFunctionHash = "8894d48a6a482c4e3d39def5e268f81e",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "b2d9c37c07c9ad8631b070aaf420fc9b",
			},
			localStatusAndOzStatus = {
				mapFunctionHash = "a2476d09be3beb0c699ebbba65634e07",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
					{
						"version",
						"*",
					},
				},
				sqlSchemaHash = "ee21e7b655eea3d18c59fdc2ec03cfaf",
			},
			locations = {
				mapFunctionHash = "0ab024f7d0c18b127c573753472e46bf",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "620560099738b950035e9c63c775a5cd",
			},
			mediaTypes = {
				mapFunctionHash = "cad3bd0661a12dc701e7279516978e93",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "e78f07bbf93c37efcaa2954d95de6e4d",
			},
			modifiedTime = {
				mapFunctionHash = "4c288205a46e39085a83dc95bf6dc2b3",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "4959b278e6f459eea0bb4c0760b77212",
			},
			needsBinaryUpload = {
				mapFunctionHash = "4460e62efb8cd9abd36c26c47ee06c48",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
					{
						"version",
						"*",
					},
					{
						"watermark",
						"*",
					},
				},
				sqlSchemaHash = "2659fc3014a0abf9bdf7039ebdcd112f",
			},
			person = {
				mapFunctionHash = "8dfe45e975b1f1576b696358d9e051e4",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"person",
					},
				},
				sqlSchemaHash = "9370ad20dc35e227426cf5cd6ad02e99",
			},
			presetsAndProfiles = {
				mapFunctionHash = "61a7ff6a1cef7839a90a23718fc45d1f",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"preset",
					},
					{
						"asset",
						"profile",
					},
				},
				sqlSchemaHash = "ac589dc04f22c72a1fff6717b4b7ff3f",
			},
			project_albums = {
				mapFunctionHash = "5aeab91f1e3feb8d088683e7d64e7ce1",
				relevantTypeSubtypeTuples = {
					{
						"album",
						"project",
					},
				},
				sqlSchemaHash = "32945701f993a51c4ab9ecdda4bab41a",
			},
			purgeCandidates = {
				mapFunctionHash = "6349f4abc695428ca04d22205a9140e7",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "faabfab6aff32cc237d4355b038ff63c",
			},
			quota_exceeded = {
				mapFunctionHash = "fd08c55b4f08b4e04a6843ceab6fd4e6",
				relevantTypeSubtypeTuples = {
					{
						"*",
						"*",
					},
				},
				sqlSchemaHash = "e55d172f9c2b356789463bed3ad18919",
			},
			ratings = {
				mapFunctionHash = "de6936a874d21a0e75faebe8c6c2b95a",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "08595bfb8e0a585452ec90065a7a76ef",
			},
			reviews = {
				mapFunctionHash = "211eed2d351b6ae6a9c950a8c7f56e36",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "230ba4b4df19601bb34c716a1f41ebda",
			},
			simple_updates = {
				mapFunctionHash = "0e9349f4afd3a39f739a3d7b75870101",
				relevantTypeSubtypeTuples = {
					{
						"*",
						"*",
					},
				},
				sqlSchemaHash = "a7636781c7ed2775c800f8e24557ec0b",
			},
			smart_albums = {
				mapFunctionHash = "4f34096729e27b1c146db7f8385d90e0",
				relevantTypeSubtypeTuples = {
					{
						"album",
						"smart",
					},
				},
				sqlSchemaHash = "c6f90899fb0b7022f804d87021b1230b",
			},
			space = {
				mapFunctionHash = "15a2070eb94057d13aa495201d1d703f",
				relevantTypeSubtypeTuples = {
					{
						"space",
						"shared",
					},
				},
				sqlSchemaHash = "97d6630ff419fc66696ba4970a746701",
			},
			space_album = {
				mapFunctionHash = "73d59901ab06c4bc981e1231bdbea3b8",
				relevantTypeSubtypeTuples = {
					{
						"space_album",
						"NULL",
					},
				},
				sqlSchemaHash = "2d7e700309224e8ab1587c0ed0223bb9",
			},
			space_invite = {
				mapFunctionHash = "e7ad77eb3968bd0f8e3bc31bbcd33436",
				relevantTypeSubtypeTuples = {
					{
						"spaceinvite",
						"request",
					},
					{
						"spaceinvite",
						"single_use",
					},
				},
				sqlSchemaHash = "fda3a72b6300175c403ec72af3c893b9",
			},
			space_user = {
				mapFunctionHash = "2e021becb81d2d904345ce7f87d3bb43",
				relevantTypeSubtypeTuples = {
					{
						"space_user",
						"NULL",
					},
				},
				sqlSchemaHash = "7674dbe1698fac94d46b8edf8054c062",
			},
			spacefavorite = {
				mapFunctionHash = "2539cc65d5e2309072f9d8d43eb89f21",
				relevantTypeSubtypeTuples = {
					{
						"favorite",
						"user",
					},
				},
				sqlSchemaHash = "500e322239776c7a7a6a734cdabd5f4b",
			},
			stack_assets = {
				mapFunctionHash = "a5a9f09de89919eca5aa194709bb948f",
				relevantTypeSubtypeTuples = {
					{
						"stack_asset",
						"NULL",
					},
				},
				sqlSchemaHash = "26a194be3b57586eb423fdb837311e68",
			},
			stacks = {
				mapFunctionHash = "ff285a6784c97188ec2d4ed6b35e5abb",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"stack",
					},
				},
				sqlSchemaHash = "47e28c82c99cf73282210b1c3cc36f58",
			},
			staleNegatives = {
				mapFunctionHash = "9968185eec6434347ccc3db9783309a0",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"*",
					},
				},
				sqlSchemaHash = "5927bf0c3a53147bf38b601468bfc9fe",
			},
			trashAssets = {
				includeDocumentsFromSource = "catalog",
				mapFunctionHash = "ddbebbe0b68d2257348da2a221568c80",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "e4d716aa0f046d82cb1b58640801cbb7",
			},
			versions = {
				sqlSchemaHash = "3768d7a10d592c29165e680400fddc81",
				relevantTypeSubtypeTuples = {
					{
						"version",
						"*",
					},
				},
				mapFunctionHash = "4ed1eb221e0556d9c2fe6d4abaceb080"
			},
			watermark = {
				mapFunctionHash = "a00c252e5ccbb24244b16ba1598a775b",
				relevantTypeSubtypeTuples = {
					{
						"watermark",
						"text",
					},
				},
				sqlSchemaHash = "71e87ac674fd360566a256ee257952a0",
			}
		}
		
		
	if WFPlatformInfo.isDesktop and WFPlatformInfo.isNimbus() then
		
		if WFPlatformInfo.isWindows and WFPlatformInfo.getArchitecture() == 'arm64' then

			KSTableUtils.setNested(
					knownIndexStoreTableHashesAndInfo,
					'93ec5129032b6d8b66e502ae7257ca78',
					'asset_importedByUser',
					'docValueFilter' )

		end
	
	elseif WFPlatformInfo.isClassic() then
		
		local classic_asset_sync_status ={
			classic_asset_sync_status = {
				mapFunctionHash = "e73c4fcce9965857fc57bd89c98e30a0",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "c72ff6004f330a494f992eef236501b1",
			},
		}
		
		knownIndexStoreTableHashesAndInfo[ #knownIndexStoreTableHashesAndInfo + 1 ] = classic_asset_sync_status
		
		if WFPlatformInfo.isWindows and WFPlatformInfo.getArchitecture() == 'arm64' then

			KSTableUtils.setNested(
					knownIndexStoreTableHashesAndInfo,
					'93ec5129032b6d8b66e502ae7257ca78',
					'asset_importedByUser',
					'docValueFilter' )

		end
		
	else

		-- some table names and map fn hashes are different for mobile
		local mobileKnownIndexStoreTableHashesAndInfo = {
			album_asset = {
				mapFunctionHash = "32c5ad85de301f168958bbe91b10aa14",
				relevantTypeSubtypeTuples = {
					{
						"album_asset",
						"NULL",
					},
				},
				sqlSchemaHash = "ab305e1e09bf667554f6e741b063233f",
			},
			albums = {
				mapFunctionHash = "3221301cb11143526d7ec01df3f06961",
				relevantTypeSubtypeTuples = {
					{
						"album",
						"collection",
					},
					{
						"album",
						"collection_set",
					},
					{
						"album",
						"topic",
					},
					{
						"album",
						"cluster",
					},
				},
				sqlSchemaHash = "d7c6c56ff1e2bb8ee14b481e1aecee0b",
			},
			assetProfileLinks = {
				mapFunctionHash = "e032cd296ac1b881c551d2d9436fb587",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "c02150c9b98e60dc7534f81df0316134",
			},
			avatarCacheReferences = {
				mapFunctionHash = "7ac6e9567df35d1119e6fc0548833a19",
				relevantTypeSubtypeTuples = {
					{
						"feedbackuser",
						"NULL",
					},
				},
				sqlSchemaHash = "1a54790dfd79312739739cc790fa1c9e",
			},
			blocked_uploads = {
				mapFunctionHash = "535edc6542dc787a7b93b6a8b747d52f",
				relevantTypeSubtypeTuples = {
					{
						"*",
						"*",
					},
				},
				sqlSchemaHash = "986409327852993407573ed583fcb279",
			},
			cacheReferences = {
				mapFunctionHash = "664590432906729d945cf1d27ca7afa3",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"video",
					},
					{
						"asset",
						"deleted_video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "df9faacbc52f024b9fe042fe3051de08",
			},
			coreInfo = {
				mapFunctionHash = "d704863ce332dde50d1c98d8d8f86c35",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "47b8f0a07f6cee6693b50e93494119ae",
			},
			faces = {
				mapFunctionHash = "406d80ad76b1d69c958e7b76bf660f66",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "0615a0fb8995a7d97b69baf3ddb2b93a",
			},
			keywords = {
				mapFunctionHash = "bb9a32e0e51241bb7ba21dab5d9d2c21",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
				},
				sqlSchemaHash = "9cb9b65623e93fc84069f599f5ff20b0",
			},
			persons = {
				mapFunctionHash = "849cbe33104770b79b8db996d4d645b9",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"person",
					},
				},
				sqlSchemaHash = "76d1dd87cc373c776e8cd9e04618584b",
			},
			presetsProfiles = {
				mapFunctionHash = "3dcd3b27a48ac0535e8f468cb053a19e",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"preset",
					},
					{
						"asset",
						"profile",
					},
					{
						"asset",
						"camera_profile",
					},
				},
				sqlSchemaHash = "d3ee26b367695d324ee04668b78ace7c",
			},
			profileRegistration = {
				mapFunctionHash = "3c7e4f9d1144e36cd45790e6fe5f1d7d",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"camera_profile",
					},
					{
						"profile",
						"NULL",
					},
				},
				sqlSchemaHash = "495b822a0e58e8e3b148972192a58ee8",
			},
			renditionRevisions = {
				mapFunctionHash = "35a7eb676206543bcb9f6f36e8dccbb6",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"image",
					},
					{
						"asset",
						"video",
					},
					{
						"version",
						"edit",
					},
				},
				sqlSchemaHash = "c7e25f8bc92d93e9ee93317924e756a4",
			},
			trashAssets = {
				mapFunctionHash = "9cb8095ab8a86df79af2e55337857907",
				relevantTypeSubtypeTuples = {
					{
						"asset",
						"deleted_image",
					},
					{
						"asset",
						"deleted_video",
					},
				},
				sqlSchemaHash = "3082817180a0d6053106c348ff09be02",
			}
		}

		for tableName, tableInfo in pairs( mobileKnownIndexStoreTableHashesAndInfo ) do
			knownIndexStoreTableHashesAndInfo[ tableName ] = tableInfo
		end

		if WFPlatformInfo.isAndroid then

			-- LrAndroid has three additional tables compared to LriOS.

			-- LrAndroid generates different hashes for all map functions
			-- due to platform difference in sring.dump.

			-- Some Android tables don't include video assets, or have
			-- slightly different table schemas.

			local androidknownIndexStoreTableHashesAndInfoOverlays = {
				album_asset = {
					mapFunctionHash = "32c5ad85de301f168958bbe91b10aa14",
				},
				albums = {
					mapFunctionHash = "3221301cb11143526d7ec01df3f06961",
				},
				assetProfileLinks = {
					mapFunctionHash = "e032cd296ac1b881c551d2d9436fb587",
				},
				avatarCacheReferences = {
					mapFunctionHash = "7ac6e9567df35d1119e6fc0548833a19",
				},
				auxReferenceTracker = {
					mapFunctionHash = "89fa68262292d8d5f0b8b73ee72a5f7b",
				},
				blocked_uploads = {
					mapFunctionHash = "535edc6542dc787a7b93b6a8b747d52f",
				},
				cacheReferences = {
					mapFunctionHash = "664590432906729d945cf1d27ca7afa3",
					sqlSchemaHash = "c844d3de6e7883726f200f4c84da27bf",
				},
				comment = {
					mapFunctionHash = "901fa6ddab7b7d09c441f077d47bb02c",
				},
				coreInfo = {
					mapFunctionHash = "d704863ce332dde50d1c98d8d8f86c35",
					sqlSchemaHash = "bec3a2e3e1bfe5f357e141117713edb6",
				},
				conflicts = {
					mapFunctionHash = "c5005664c695badeffcae7d3ff25be98",
				},
				CustomCameraProfiles = {
					mapFunctionHash = "e082e0517c263ca6ef051b0663b26862",
					relevantTypeSubtypeTuples = {
						{
							"asset",
							"camera_profile",
						},
					},
					sqlSchemaHash = "15eb16040b63bced5cf95fbf6472cebc",
				},
				coreMD5 = {
					mapFunctionHash = "d57afeb4ea858b4bcd84699d86c02259",
					relevantTypeSubtypeTuples = {
						{
							"asset",
							"image",
						},
						{
							"asset",
							"video",
						},
					},
					sqlSchemaHash = "6a6545de4d1df65cd8a406c29d667dc5",
				},
				unconfirmedDeletions = {
					mapFunctionHash = "60813769548c123af9b4499fdc6c4260",
				},
				errors = {
					mapFunctionHash = "e8a290daadbf18ae5d2b194bbc1031c8",
				},
				faces = {
					mapFunctionHash = "406d80ad76b1d69c958e7b76bf660f66",
					sqlSchemaHash = "9bfc216a39c939f504e545eb4629f8d5",
				},
				feedback_user = {
					mapFunctionHash = "eda8717d1f2fae3f310d9cd619b92572",
				},
				importSource = {
					mapFunctionHash = "f2f0d8eb5766875b190710260e95d6cc",
				},
				keywords = {
					mapFunctionHash = "bb9a32e0e51241bb7ba21dab5d9d2c21",
				},
				localAuxTracker = {
					mapFunctionHash = "8894d48a6a482c4e3d39def5e268f81e",
				},
				needsBinaryUpload = {
					mapFunctionHash = "4460e62efb8cd9abd36c26c47ee06c48",
				},
				persons = {
					mapFunctionHash = "849cbe33104770b79b8db996d4d645b9",
					sqlSchemaHash = "631cb1b6b232aada1def9f7a3289297e",
				},
				presetsProfiles = {
					mapFunctionHash = "c368a853d2090b52a9b0192c5c86ad17",
					relevantTypeSubtypeTuples = {
						{
							"asset",
							"preset",
						},
						{
							"asset",
							"profile",
						},
					},
					sqlSchemaHash = "ca3a69e6054d26eb748f35a1e919244c",
				},
				profileRegistration = {
					mapFunctionHash = "3c7e4f9d1144e36cd45790e6fe5f1d7d",
				},
				purgeCandidates = {
					mapFunctionHash = "6349f4abc695428ca04d22205a9140e7",
				},
				quota_exceeded = {
					mapFunctionHash = "fd08c55b4f08b4e04a6843ceab6fd4e6",
				},
				renditionRevisions = {
					mapFunctionHash = "35a7eb676206543bcb9f6f36e8dccbb6",
				},
				similar_person = {
					mapFunctionHash = "d33eb4ce7d99a326e7646238663775a9",
					relevantTypeSubtypeTuples = {
						{
							"asset",
							"person",
						},
					},
					sqlSchemaHash = "1389556f94729938b1e806cc91277918",
				},
				space = {
					mapFunctionHash = "15a2070eb94057d13aa495201d1d703f",
				},
				space_album = {
					mapFunctionHash = "73d59901ab06c4bc981e1231bdbea3b8",
				},
				space_invite = {
					mapFunctionHash = "e7ad77eb3968bd0f8e3bc31bbcd33436",
				},
				space_user = {
					mapFunctionHash = "2e021becb81d2d904345ce7f87d3bb43",
				},
				spacefavorite = {
					mapFunctionHash = "2539cc65d5e2309072f9d8d43eb89f21",
				},
				trashAssets = {
					mapFunctionHash = "9cb8095ab8a86df79af2e55337857907",
					sqlSchemaHash = "d3db4daafef5dc640be46d583b257263",
				},
				unconfirmedDeletions = {
					mapFunctionHash = "60813769548c123af9b4499fdc6c4260",
				},

				versions = {
					mapFunctionHash = "4ed1eb221e0556d9c2fe6d4abaceb080"
				},
				watermark = {
					mapFunctionHash = "a00c252e5ccbb24244b16ba1598a775b",
				}
			}

			knownIndexStoreTableHashesAndInfo = WFTableMerge.applyOverlay( knownIndexStoreTableHashesAndInfo, androidknownIndexStoreTableHashesAndInfoOverlays )

			local androidknownIndexStoreTableHashesAndInfo = {
				presetsProfiles = {
					mapFunctionHash = "c368a853d2090b52a9b0192c5c86ad17",
					relevantTypeSubtypeTuples = {
						{
							"asset",
							"preset",
						},
						{
							"asset",
							"profile",
						},
					},
					sqlSchemaHash = "ca3a69e6054d26eb748f35a1e919244c",
				}

			}

			for tableName, tableInfo in pairs( androidknownIndexStoreTableHashesAndInfo ) do
				knownIndexStoreTableHashesAndInfo[ tableName ] = tableInfo
			end

		end
	
	end
	
	return knownIndexStoreTableHashesAndInfo

end

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

local function bringIndexStoreUpToDate( rxTest, docStore, indexStore )

	-- Run a dummy query to bring the index store up to date.

	rxTest:waitFor(
		docStore:setDocValue {
			_id = KSIdGenerator.uuidInLowercaseHex(),
			type = "album",
			subtype = "collection",
			name = "foo",
		} )

	rxTest:waitFor(
		indexStore:queryOnce( {
			sql = [[SELECT count(*) FROM versions]], -- Using versions because it's cross-platform
		} ) )

end

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

local function getPlatformSpecificIndexStoreTableHashesAndInfo( indexStoreTableHashesAndInfo )

	return indexStore:DEBUG_getReindexingTableInfo()

		:map( function( platformTableInfo )

			local platformIndexStoreTableHashesAndInfo = {}

			for tableName in pairs( platformTableInfo ) do
				platformIndexStoreTableHashesAndInfo[ tableName ] = indexStoreTableHashesAndInfo[ tableName ]
			end

			return platformIndexStoreTableHashesAndInfo

		end )

end

--==============================================================================
-- @mark Reindexing Monitoring Test Cases
--==============================================================================

local function testVerifyReindexIsExpected( rxTest, catalogSpec )
	-- The following test is used to verify that there are no unintentional changes
	-- to the index store table definitions. The test verifies the map function hash,
	-- the sql schema hash, the doc value filter hash, and the relevant type and
	-- subtype tuples for each index store table; any changes to these values may
	-- require a reindex and an associated entry in WFRxIndexStoreSchemaVersionList.

	docStore = docStore or WFRxDocStore( ':memory:' )
	indexStore = indexStore or WFRxIndexStore( docStore, catalogSpec )

	bringIndexStoreUpToDate( rxTest, docStore, indexStore )

	-- The following code compares the current index store hashes, as calculated
	-- in real-time from the index store, against the known set of hashes that
	-- are tracked within this file via knownIndexStoreTableHashesAndInfo.
	local knownIndexStoreTableHashesAndInfo = getKnownIndexStoreTableHashesAndInfo()
	
	local obs = rxTest:observe( Rx.Observable.combineLatest(
			indexStore:DEBUG_getReindexingTableInfo(),
			getPlatformSpecificIndexStoreTableHashesAndInfo( knownIndexStoreTableHashesAndInfo ) )

			:map( function( tableInfo, platformIndexStoreTableHashesAndInfo )

				local mismatches = {}

				for tblName, tblInfo in pairs( tableInfo ) do

					for k, actualValue in pairs( tblInfo ) do

						local expectedValue = KSTableUtils.derefOpt( platformIndexStoreTableHashesAndInfo, tblName, k )

						if ( type( expectedValue ) == 'table' and not KSTableUtils.deepEquals( expectedValue, actualValue ) )
								or ( type( expectedValue ) ~= 'table' and expectedValue ~= actualValue ) then

							local mismatchesForTable = mismatches[ tblName ] or {}
							mismatchesForTable[ k ] = actualValue
							mismatches[ tblName ] = mismatchesForTable
							mismatches[ "DEVELOPER NOTE" ] = "Was this reindex intentional? Please see https://git.corp.adobe.com/lua/wf/blob/main/doc/reindexing.md#developer-notes for more info on how to proceed."

						end

					end

				end

				return mismatches

			end ) )

	obs:expectData( {} )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyReindexIsExpected_testSerially( rxTest )
	
	rxTest:setTimeLimit( 10 )
	
	local catalogSpec = getCatalogSpec()
	testVerifyReindexIsExpected( rxTest, catalogSpec )
	
	if  WFPlatformInfo.isDesktop then
		-- test Lr Classic platform 
		WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', 'true' )
		
		rxTest:finally( function()
			WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', nil )
		end )
		
		local classicCatalogSpec = "LrClassicIndexDefinitions.lua"
		testVerifyReindexIsExpected( rxTest, classicCatalogSpec )

	end
	
end

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

local function verifyOptInOrOptOut( knownIndexStoreTableHashesAndInfoDiff, schemaVersionListDiff, optOutListDiff )

	local function diffHasEntryForTable( listDiff, tableName )

		for _, entry in pairs( listDiff ) do

			local entryContents = entry.value
			local tablesArr = entryContents.tables
			local tablesMap = KSTableUtils.invert( tablesArr )

			if tablesMap[ tableName ] and
					WFRxIndexStoreSchemaVersionList.affectsThisPlatform( entryContents.platforms ) then

				return true

			end

		end

		return false

	end

	local tablesWithoutOptInOrOptOut = {}
	local tablesWithBothOptInAndOptOut = {}

	for tableName, entry in pairs( knownIndexStoreTableHashesAndInfoDiff ) do

		local optIn = diffHasEntryForTable( schemaVersionListDiff, tableName )

		local optOut = diffHasEntryForTable( optOutListDiff, tableName )

		if optIn and optOut then
			tablesWithBothOptInAndOptOut[ #tablesWithBothOptInAndOptOut + 1 ] = tableName
		elseif not optIn and not optOut then
			tablesWithoutOptInOrOptOut[ #tablesWithoutOptInOrOptOut + 1 ] = tableName
		end

	end

	for _, entry in pairs( schemaVersionListDiff ) do

		local modificationType = entry.type

		-- The following check enforces that the user has not accidentally
		-- modified or deleted entries from the Schema Version List.

		assert( modificationType == 'added',
				string.format( "Error! You've modified or deleted an entry in the schema version list: %s. This is not allowed.",
				WFTableArchiving.tableToString( entry ) ) )

	end

	for _, entry in pairs( optOutListDiff ) do

		local modificationType = entry.type

		-- The following check enforces that the user has not accidentally
		-- modified or deleted entries from the Schema Version Opt-Out List.

		assert( modificationType == 'added',
				string.format( "Error! You've modified or deleted an entry in the schema version opt-out list: %s. This is not allowed.",
				WFTableArchiving.tableToString( entry ) ) )

	end

	return tablesWithoutOptInOrOptOut, tablesWithBothOptInAndOptOut

end

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

-- This is a simplified version of WFTableDiff, which is probably only useful
-- on this context; it's not worth extracting into a utility function. This
-- function performs a non-recursive diff, and uses KSTableUtils.deepEquals to
-- detect changes in nested table elements.

local function nonRecursiveTableDiff( tbl1, tbl2 )

	local diffNodes = {}

	-- Start by looking at the keys in tbl1

	for k, v in pairs( tbl1 ) do

		if tbl2[ k ] == nil then

			-- Deletion

			diffNodes[ k ] = {
				value = v,
				type = 'deleted'
			}

		elseif not KSTableUtils.deepEquals( v, tbl2[ k ] ) then

			-- Modification

			diffNodes[ k ] = {
				value = v,
				type = 'modified'
			}

		end

	end

	for k, v in pairs( tbl2 ) do

		if tbl1[ k ] == nil then

			-- Addition

			diffNodes[ k ] = {
				value = v,
				type = 'added'
			}

		end

	end

	return diffNodes

end

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

local function testVerifyOptInOrOptOut( rxTest, catalogSpec )

	-- These are special lua files, which are populated by the build machines. They contain
	-- the historical implementations of the files.

	local filesExist, WFRxIndexStoreSchemaVersionList_prev, WFRxIndexStoreSchemaVersionListTest_prev

	filesExist, WFRxIndexStoreSchemaVersionList_prev
			= KSLuaUtils.requireIfExists( 'WFRxIndexStoreSchemaVersionList_prev' )

	if filesExist then

		filesExist, WFRxIndexStoreSchemaVersionListTest_prev
				= KSLuaUtils.requireIfExists( 'WFRxIndexStoreSchemaVersionListTest_prev' )

	end

	if filesExist
			and WFRxIndexStoreSchemaVersionList_prev.getSchemaVersionListOptOutList
			and WFRxIndexStoreSchemaVersionListTest_prev.getKnownIndexStoreTableHashesAndInfo then

		-- Make sure the files exist and have content. If they don't, then the target branch
		-- is too old to run this test case against.

		-- IF THIS TEST IS FAILING, THEN IT MEANS THAT YOU HAVE MODIFIED AN INDEX
		-- STORE TABLE DEFINITION, BUT HAVE NOT OPTED-IN OR OPTED-OUT OF REINDEXING.
		-- DO NOT MODIFY THIS TEST CASE.

		-- PLEASE READ AND UNDERSTAND:
		-- https://git.corp.adobe.com/lua/wf/blob/main/doc/reindexing.md

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

		-- The following test is used to verify that a developer has explicitly opted-in
		-- or explicitly opted-out of reindexing within a Pull Request that modifies the
		-- the expected index store table hashes.

		-- This test case relies on syncing down a version of the `WFRxIndexStoreSchemaVersionList`
		-- file from the target branch of the PR. Therefore, it can only run on automation. If you'd
		-- like to run it locally, you must manually copy an older version of `WFRxIndexStoreSchemaVersionList`
		-- to the same directory as this test file, and add a `_prev` suffix to the file name.

		rxTest:setTimeLimit( 5 )

		docStore = docStore or WFRxDocStore( ':memory:' )
		indexStore = indexStore or WFRxIndexStore( docStore, catalogSpec )

		bringIndexStoreUpToDate( rxTest, docStore, indexStore )

		WFCapabilities.setCapability( 'WFRxIndexStoreTest.indexStoreSchemaVersionListOverride', nil )
			-- This is not necessary, I'm just paranoid.

		-- First, figure out which Index Store Tables have been modified

		local previousKnownIndexStoreTableHashesAndInfo
				= WFRxIndexStoreSchemaVersionListTest_prev.getKnownIndexStoreTableHashesAndInfo()

		local previousPlatformIndexStoreTableHashesAndInfo = rxTest:getFirstValue(
				getPlatformSpecificIndexStoreTableHashesAndInfo( previousKnownIndexStoreTableHashesAndInfo ) )
		
		local knownIndexStoreTableHashesAndInfo = getKnownIndexStoreTableHashesAndInfo()
		local platformIndexStoreTableHashesAndInfo = rxTest:getFirstValue(
				getPlatformSpecificIndexStoreTableHashesAndInfo( knownIndexStoreTableHashesAndInfo ) )

		local knownIndexStoreTableHashesAndInfoDiff = nonRecursiveTableDiff(
				previousPlatformIndexStoreTableHashesAndInfo,
				platformIndexStoreTableHashesAndInfo )

		-- Now figure out the delta between the previous and current Schema Version Lists

		local schemaVersionList = WFRxIndexStoreSchemaVersionList.getSchemaVersionList()
		local previousSchemaVersionList = WFRxIndexStoreSchemaVersionList_prev.getSchemaVersionList()

		local schemaVersionListDiff = nonRecursiveTableDiff(
				previousSchemaVersionList,
				schemaVersionList )

		-- ... and the delta between the previous and current Schema Version Opt-Out Lists

		local optOutList = WFRxIndexStoreSchemaVersionList.getSchemaVersionListOptOutList()
		local previousOptOutList = WFRxIndexStoreSchemaVersionList_prev.getSchemaVersionListOptOutList()

		local optOutListDiff = nonRecursiveTableDiff( previousOptOutList, optOutList )

		-- Iterate through the knownIndexStoreTableHashesAndInfoDiff. If there are any modifications,
		-- then verify that there are associated entries in either the schema version list, or in
		-- the schema version opt-out list.

		local tablesWithoutOptInOrOptOut, tablesWithBothOptInAndOptOut
				= verifyOptInOrOptOut( knownIndexStoreTableHashesAndInfoDiff, schemaVersionListDiff, optOutListDiff )

		local reindexingGuide = "https://git.corp.adobe.com/lua/wf/blob/main/doc/reindexing.md"

		assert( #tablesWithoutOptInOrOptOut == 0, string.format( "You must opt-in or opt-out of reindexing for tables %s. See %s for more info.",
				WFTableArchiving.tableToString( tablesWithoutOptInOrOptOut ), reindexingGuide ) )

		assert( #tablesWithBothOptInAndOptOut == 0, string.format( "You cannot opt-in AND opt-out of reindexing for tables %s. See %s for more info.",
				WFTableArchiving.tableToString( tablesWithBothOptInAndOptOut ), reindexingGuide ) )

	end

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyOptInOrOptOut_testSerially( rxTest )

	local catalogSpec = getCatalogSpec()
	testVerifyOptInOrOptOut( rxTest, catalogSpec )

end

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

if WFPlatformInfo.isDesktop then

	function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyOptInOrOptOut_classic_testSerially( rxTest )

		-- Test LrC

		WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', 'true' )

		rxTest:finally( function()
			WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', nil )
		end )

		local classicCatalogSpec = "LrClassicIndexDefinitions.lua"
		testVerifyOptInOrOptOut( rxTest, classicCatalogSpec )

	end

end

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

--==============================================================================
-- @mark Opt-In / Opt-Out Meta Test Cases
--==============================================================================

-- The following "Meta" test cases verify the logic that verifies the opt-in
-- and opt-out reindexing logic.

function WFRxIndexStoreSchemaVersionListTest.rxTestMetaVerifyOptInOrOptOut_Noop( rxTest )

	-- First, figure out which Index Store Tables have been modified

	local mockPreviousKnownIndexStoreTableHashesAndInfo = {
		foo = {
			mapFunctionHash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
			relevantTypeSubtypeTuples = { { "asset", "image" } },
			sqlSchemaHash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		}
	}

	local mockKnownIndexStoreTableHashesAndInfo = mockPreviousKnownIndexStoreTableHashesAndInfo

	local knownIndexStoreTableHashesAndInfoDiff = nonRecursiveTableDiff(
			mockPreviousKnownIndexStoreTableHashesAndInfo,
			mockKnownIndexStoreTableHashesAndInfo )

	-- Now figure out the delta between the previous and current Schema Version Lists

	local mockSchemaVersionList = {
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "All" },
			tables = { "foo" }
		}
	}

	local mockPreviousSchemaVersionList = mockSchemaVersionList

	local schemaVersionListDiff = nonRecursiveTableDiff(
			mockPreviousSchemaVersionList,
			mockSchemaVersionList )

	-- ... and the delta between the previous and current Schema Version Opt-Out Lists

	local mockOptOutList = {
		{
			platforms = { "All" },
			tables = { "foo" }
		}
	}

	local mockPreviousOptOutList = mockOptOutList

	local optOutListDiff = nonRecursiveTableDiff(
			mockPreviousOptOutList,
			mockOptOutList )

	-- Perform Verification

	local tablesWithoutOptInOrOptOut, tablesWithBothOptInAndOptOut
			= verifyOptInOrOptOut( knownIndexStoreTableHashesAndInfoDiff, schemaVersionListDiff, optOutListDiff )

	local expectedTablesWithoutOptInOrOptOut = {}

	rxTest:expectEqual( expectedTablesWithoutOptInOrOptOut, tablesWithoutOptInOrOptOut )

	local expectedTablesWithBothOptInAndOptOut = {}

	rxTest:expectEqual( expectedTablesWithBothOptInAndOptOut, tablesWithBothOptInAndOptOut )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestMetaVerifyOptInOrOptOut( rxTest )

	local mockPreviousKnownIndexStoreTableHashesAndInfo = {
		foo = {
			mapFunctionHash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
			sqlSchemaHash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
		},
		bar = {
			mapFunctionHash = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
			sqlSchemaHash = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
			relevantTypeSubtypeTuples = { { "asset", "image" } }
		}
	}

	local mockPreviousSchemaVersionList = {
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "All" },
			tables = { "foo", "bar" }
		}
	}

	local mockPreviousOptOutList = {}

	for _, thisPlatform in ipairs { true, false } do

		for _, scenario in ipairs { 'added', 'updatedMap', 'updatedSchema', 'updatedTuples', 'removed' } do

			for _, userAction in ipairs { 'none', 'optIn', 'optOut', 'both', 'errorModify', 'errorDelete' } do

				logger:infof( "This Platform? %s, Senario: %s, User Action: %s", thisPlatform, scenario, userAction )

				local mockKnownIndexStoreTableHashesAndInfo
						= KSTableUtils.deepCopy( mockPreviousKnownIndexStoreTableHashesAndInfo )

				local affectedTableName = 'foo'

				if scenario == 'added' then

					affectedTableName = 'baz'

					mockKnownIndexStoreTableHashesAndInfo[ affectedTableName ] = {
						mapFunctionHash = "cccccccccccccccccccccccccccccccc",
						relevantTypeSubtypeTuples = { { "asset", "image" } },
						sqlSchemaHash = "cccccccccccccccccccccccccccccccc"
					}

				elseif scenario == 'updatedMap' then

					mockKnownIndexStoreTableHashesAndInfo[ affectedTableName ].mapFunctionHash
							= 'dddddddddddddddddddddddddddddddd'

				elseif scenario == 'updatedSchema' then

					mockKnownIndexStoreTableHashesAndInfo[ affectedTableName ].sqlSchemaHash
							= 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'

				elseif scenario == 'updatedTuples' then

					mockKnownIndexStoreTableHashesAndInfo[ affectedTableName ].sqlSchemaHash
							 = { { "album", "collection" } }

				elseif scenario == 'removed' then

					mockKnownIndexStoreTableHashesAndInfo[ affectedTableName ] = nil

				end

				local mockOptOutList = KSTableUtils.deepCopy( mockPreviousOptOutList )

				local mockSchemaVersionList = KSTableUtils.deepCopy( mockPreviousSchemaVersionList )

				local platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" }

				if not thisPlatform then
					platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" }
				end

				if userAction == 'optIn' or userAction == 'both' then

					mockSchemaVersionList[ #mockSchemaVersionList + 1 ] = {
						sequence = 2,
						platforms = platforms,
						tables = { affectedTableName }
					}

				end

				if userAction == 'optOut' or userAction == 'both' then

					mockOptOutList[ #mockOptOutList + 1 ] = {
						platforms = platforms,
						tables = { affectedTableName },
						why = "why"
					}

				end

				if userAction == 'errorModify' then

					mockSchemaVersionList[ 1 ] = {
						sequence = 1,
						platforms = platforms,
						tables = { 'zar' }
					}

				elseif userAction == 'errorDelete' then

					mockSchemaVersionList[ 1 ] = nil

				end

				-- Created our expected responses

				local expectedTablesWithoutOptInOrOptOut = {}
				local expectedTablesWithBothOptInAndOptOut = {}

				if userAction == 'none' or not thisPlatform then

					-- If the user took no action, or they took an action that didn't affect
					-- this platform, this we should detect it. This is the heart of this
					-- test case.

					expectedTablesWithoutOptInOrOptOut = { affectedTableName }

				elseif userAction == 'both' then

					-- If the user both opted in *AND* opted out, then that's also not valid.

					expectedTablesWithBothOptInAndOptOut = { affectedTableName }

				end

				-- Perform Verification

				local mockKnownIndexStoreTableHashesAndInfoDiff = nonRecursiveTableDiff(
						mockPreviousKnownIndexStoreTableHashesAndInfo,
						mockKnownIndexStoreTableHashesAndInfo )

				local schemaVersionListDiff = nonRecursiveTableDiff(
						mockPreviousSchemaVersionList,
						mockSchemaVersionList )

				local mockOptOutListDiff = nonRecursiveTableDiff(
						mockPreviousOptOutList,
						mockOptOutList )

				if userAction == 'errorModify' or userAction == 'errorDelete' then

					local success = pcall( verifyOptInOrOptOut,
							mockKnownIndexStoreTableHashesAndInfoDiff,
							schemaVersionListDiff,
							mockOptOutListDiff )

					rxTest:expectEqual( false, success )

				else

					local tablesWithoutOptInOrOptOut, tablesWithBothOptInAndOptOut = verifyOptInOrOptOut(
							mockKnownIndexStoreTableHashesAndInfoDiff,
							schemaVersionListDiff,
							mockOptOutListDiff )

					rxTest:expectEqual( expectedTablesWithoutOptInOrOptOut, tablesWithoutOptInOrOptOut )

					rxTest:expectEqual( expectedTablesWithBothOptInAndOptOut, tablesWithBothOptInAndOptOut )

				end

			end

		end

	end

end

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

--@mark Standard Unit Tests

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

local validTables = { "versions", "watermark", "album_asset", "conflicts", "faces" }

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

function WFRxIndexStoreSchemaVersionListTest.rxTestBasicSchemaVersionList_testSerially( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "iOS", "Android", "MacOSX", "Windows" },
			tables = { "versions", "watermark" }
		},
		{
			sequence = 2,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" }
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" }
		},
		{
			sequence = 4, -- not this platform
			platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" },
			tables = { "faces" }
		},
		{
			sequence = 5,
			platforms = { "All" },
			tables = { "faces" }
		},
		-- skip sequence 6, ignored
		{
			sequence = 7,
			platforms = { "All" },
			tables = { "conflicts" }, -- dupes are ignored if they are encountered
		}
	})

	-- start from base sequence
	local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( { "versions", "watermark", "album_asset", "conflicts", "faces" }, tables )

	-- start from later sequence
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, validTables )
	rxTest:expectEqual( { "faces", "conflicts" }, tables )

end

--------------------------------------------------------------------------------
if WFPlatformInfo.isDesktop then

	function WFRxIndexStoreSchemaVersionListTest.rxTestBasicSchemaVersionList_nimbus_testSerially( rxTest )

		WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
		{
			{
				sequence = 0,
			},
			{
				sequence = 1,
				platforms = { "iOS", "Android", "MacOSX", "Windows" },
				tables = { "versions", "watermark" }
			},
			{
				sequence = 2,
				platforms = { WFPlatformInfo.getOS() },
				tables = { "album_asset" }
			},
			{
				sequence = 3,
				platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
				tables = { "conflicts" }
			},
			{
				sequence = 4, -- not this platform
				platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" },
				tables = { "faces" }
			},
			{
				sequence = 5,
				platforms = { "All" },
				tables = { "faces" }
			},
			-- skip sequence 6, ignored
			{
				sequence = 7,
				platforms = { "All" },
				tables = { "conflicts" }, -- dupes are ignored if they are encountered
			},
			{
				sequence = 8,
				platforms = { "Classic" },
				tables = { "assets" }, 
			},
			{
				sequence = 9,
				platforms = { "Nimbus" },
				tables = { "stack_album" }, 
			},
			{
				sequence = 10,
				platforms = { "Desktop" },
				tables = { "project_albums" }, 
			}
			
		})

		
		local nimbusValidTables = { "versions", "watermark", "album_asset", "conflicts", "faces", "stack_album", "project_albums" }
			-- start from base sequence
		local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, nimbusValidTables )
		rxTest:expectEqual( 10, newSequence )
		rxTest:expectEqual( { "versions", "watermark", "album_asset", "conflicts", "faces", "stack_album", "project_albums" }, tables )
		
		
		-- start from later sequence
		newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, nimbusValidTables )
		rxTest:expectEqual( { "faces", "conflicts", "stack_album", "project_albums" }, tables )
		

	end

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

	function WFRxIndexStoreSchemaVersionListTest.rxTestBasicSchemaVersionList_classic_testSerially( rxTest )

		WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
		{
			{
				sequence = 0,
			},
			{
				sequence = 1,
				platforms = { "iOS", "Android", "MacOSX", "Windows" },
				tables = { "versions", "watermark" }
			},
			{
				sequence = 2,
				platforms = { WFPlatformInfo.getOS() },
				tables = { "album_asset" }
			},
			{
				sequence = 3,
				platforms = { WFPlatformInfo.isDesktop and "SharedDesktop" or "Mobile" },
				tables = { "conflicts" }
			},
			{
				sequence = 4, -- not this platform
				platforms = { WFPlatformInfo.isDesktop and "Mobile" or "SharedDesktop" },
				tables = { "faces" }
			},
			{
				sequence = 5,
				platforms = { "All" },
				tables = { "faces" }
			},
			-- skip sequence 6, ignored
			{
				sequence = 7,
				platforms = { "All" },
				tables = { "conflicts" }, -- dupes are ignored if they are encountered
			}
			,
			{
				sequence = 8,
				platforms = { "Classic" },
				tables = { "assets" }, 
			}
			,
			{
				sequence = 9,
				platforms = { "Nimbus" },
				tables = { "stack_album" }, 
			}
			,
			{
				sequence = 10,
				platforms = { "SharedDesktop" },
				tables = { "project_albums" }, 
			}
			,
			{
				sequence = 11,
				platforms = { "Desktop" },
				tables = { "locations" }, 
			}
			
		})
		

		-- test Lr Classic platform 
		WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', 'true' )
		
		rxTest:finally( function()
			WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', nil )
		end )
		
		local classicValidTables = { "versions", "watermark", "album_asset", "conflicts", "faces", "assets", "project_albums" }
		-- start from base sequence
		local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, classicValidTables )
		rxTest:expectEqual( 11, newSequence )
		rxTest:expectEqual( { "versions", "watermark", "album_asset", "conflicts", "faces", "assets", "project_albums" }, tables )

		-- start from later sequence
		newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, classicValidTables )
		rxTest:expectEqual( { "faces", "conflicts", "assets", "project_albums" }, tables )

	end

end

--------------------------------------------------------------------------------
	
function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaVersionListBaseLine_testSerially( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 2,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" },
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" },
		},
		{
			sequence = 4, -- not this platform
			platforms = { WFPlatformInfo.isDesktop and "Mobile" or "Desktop" },
			tables = { "faces" },
		},
		{
			sequence = 5,
			platforms = { "All" },
			tables = { "faces" },
		},
		-- skip sequence 6, ignored
		{
			sequence = 7,
			platforms = { "All" },
			tables = { "conflicts" }, -- dupes are ignored if they are encountered
		}
	})

	local validTables = { "versions", "watermark", "album_asset", "conflicts", "faces" }

	-- current sequence not included in versions list
	local newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( 'hashBasedIndexing', tables )

	-- current sequence is included in versions list
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( 3, validTables )
	rxTest:expectEqual( { "faces", "conflicts" }, tables )

	-- There is no current sequence.
	newSequence, tables = WFRxIndexStoreSchemaVersionList.getTablesToReindex( nil, validTables )
	rxTest:expectEqual( 7, newSequence )
	rxTest:expectEqual( 'hashBasedIndexing', tables )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaListErrors_testSerially( rxTest )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		"foo",
		"bar",
	})

	-- invalid schema version list
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid schema version list, expected table" )


	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = "not a number",
		},
	})

	-- invalid sequence
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid sequence" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "iOS", "Android", "MacOSX", "Windows" },
			tables = { "versions", "watermark" },
		},
		{
			sequence = 3,
			platforms = { WFPlatformInfo.getOS() },
			tables = { "album_asset" },
		},
		{
			sequence = 2,
			platforms = { WFPlatformInfo.isDesktop and "Desktop" or "Mobile" },
			tables = { "conflicts" },
		},
	})

	-- invalid sequence
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid sequence" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = "foo",
			tables = { "versions", "watermark" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): invalid platforms" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = { "foo" },
			tables = { "versions", "watermark" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList: invalid platform specificer: 'foo'" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
				{
			sequence = 1,
			platforms = { "All" },
			tables = "foo",
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.getTablesToReindex(): tables must be a list" )

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = "All",
			tables = { "foo" },
		},
	})

	-- invalid platforms
	rxTest:expectError( WFRxIndexStoreSchemaVersionList.getTablesToReindex, 0, validTables,
		"WFRxIndexStoreSchemaVersionList.addTables(): invalid table foo for this platform" )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestSchemaVersionListWithCatalog_testSerially( rxTest )

	rxTest:setTimeLimit( 5 )

	-- TODO: adapt this test after adding indexStore method getIndexTables() and getSchemaVersionListSequence()
	-- which will return as observables a list of the index tables and the current schema version list sequence

	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest,
	{
		{
			sequence = 0,
		},
		{
			sequence = 1,
			platforms = { "All" },
			tables = { "watermark" },
		},
	})

	local wfCatalog = WFCatMockCatalog.createFakeWFCatalog( rxTest )

	local indexStore = wfCatalog:indexStore()

	local obs = rxTest:observe(
				indexStore:DEBUG_getMapFunctionHashes() -- temp. hack to get index tables
					:map( function( hashTable )
						local tableNames = {}
						for _, v in pairs( hashTable ) do
							local tableName, _ = unpack( v )
							tableNames[ #tableNames + 1 ] = tableName
						end
						return tableNames
					end)
					:map( function( indexStoreTables )
						return WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, indexStoreTables)
					end) )

	obs:expectData( 1, { "watermark" } )

end

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

function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyActualSchemaVersionList_testSerially( rxTest, createIndexStoreFn )

	-- If the following test fails, it means that the schema version list -- defined within
	-- WFRxIndexStoreSchemaVersionList -- contains an invalid entry and must be fixed.

	local actualSchemaVersionList = WFRxIndexStoreSchemaVersionList.getSchemaVersionList()
	WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest, actualSchemaVersionList )

	local indexSpecScript
	
	if WFPlatformInfo.isDesktop then
		indexSpecScript = "WFCatIndexDefinitions.lua"
	else
		indexSpecScript = "LrmCatalogIndexDefinitions.lua"
	end
	
	local indexStoreSchema = WFRxIndexStoreImpUtils.loadSchema( indexSpecScript )
	assert( indexStoreSchema, "Cannot load schema" )
	
	local validTablesSet = indexStoreSchema:tableNames()
	local validTables = KSTableUtils.extractKeys( validTablesSet )
	
	rxTest:expectEqual( true, not not WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables ) )

end

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

if WFPlatformInfo.isDesktop then

	function WFRxIndexStoreSchemaVersionListTest.rxTestVerifyActualSchemaVersionList_classic_testSerially( rxTest, createIndexStoreFn )

		-- The LrClassic-specific version of rxTestVerifyActualSchemaVersionList
		-- If the following test fails, it means that the schema version list -- defined within
		-- WFRxIndexStoreSchemaVersionList -- contains an invalid entry and must be fixed.

		WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', 'true' )

		rxTest:finally( function()
			WFCapabilities.setCapability( 'WFPlatformInfo.isClassic', nil )
		end )

		local actualSchemaVersionList = WFRxIndexStoreSchemaVersionList.getSchemaVersionList()
		WFRxIndexStoreSchemaVersionList.TEST_setSchemaVersionList( rxTest, actualSchemaVersionList )

		local indexSpecScript = "LrClassicIndexDefinitions.lua"

		local indexStoreSchema = WFRxIndexStoreImpUtils.loadSchema( indexSpecScript )
		assert( indexStoreSchema, "Cannot load schema" )

		local validTablesSet = indexStoreSchema:tableNames()
		local validTables = KSTableUtils.extractKeys( validTablesSet )

		rxTest:expectEqual( true, not not WFRxIndexStoreSchemaVersionList.getTablesToReindex( 0, validTables ) )

	end

end

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

function WFRxIndexStoreSchemaVersionListTest.getKnownIndexStoreTableHashesAndInfo()

	-- Used by rxTestVerifyOptInOrOptOut
	local knownIndexStoreTableHashesAndInfo = getKnownIndexStoreTableHashesAndInfo()
	return knownIndexStoreTableHashesAndInfo

end

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

return WFRxTestCase.wrapSuite( 'WFRxIndexStoreSchemaVersionListTest', WFRxIndexStoreSchemaVersionListTest )
