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

LrmLibraryReviewTest.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2015 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 WFAsyncTestCase = require 'WFAsyncTestCase'
local WFRxTestCase = require 'WFRxTestCase'

	-- WF.core.utils
local KSIdGenerator = require 'KSIdGenerator'
local KSTableUtils = require 'KSTableUtils'

	-- Lrmobile_models
local LrmCatalogTestHelper = require 'LrmCatalogTestHelper'
local LrmLibraryReviewModelImp = require 'LrmLibraryReviewModelImp'

	-- WF.oz_client.catalog
local WFOzSyncConstants = require 'WFOzSyncConstants'


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

local catalog, fakeModel

local TEST_TIMEOUT = 10

local LrmLibraryReviewTest = {}

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

function LrmLibraryReviewTest.setUp()

	catalog = LrmCatalogTestHelper.makeCatalogService()
	
	fakeModel = {
		catalog = catalog,
	}
	
end

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

function LrmLibraryReviewTest.tearDown()

	if catalog then
		catalog:close()
		catalog = nil
	end
	
end

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

-- @mark Reviews / Ratings by authenticated user

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

function LrmLibraryReviewTest.testSingleAssetFlagging( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
		
		:waitFor( function()
		
			return LrmLibraryReviewModelImp.setAssetFlagStatus( fakeModel, 'pick', { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue )
					
						return 'data', KSTableUtils.derefOpt( docValue, 'reviews', userId )
						
					end )
					:mapDataP( function( _, review )
					
						review.date = nil
						return 'data', review
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { flag = 'pick' } )
		
		:waitFor( function()
		
			return LrmLibraryReviewModelImp.setAssetFlagStatus( fakeModel, 'reject', { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue )
					
						return 'data', KSTableUtils.derefOpt( docValue, 'reviews', userId )
						
					end )
					:mapDataP( function( _, review )
					
						review.date = nil
						return 'data', review
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { flag = 'reject' } )
		
end

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

function LrmLibraryReviewTest.testSingleAssetRating( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
		
		:waitFor( function()
		
			return LrmLibraryReviewModelImp.setAssetRating( fakeModel, 1, { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue )
					
						return 'data', KSTableUtils.derefOpt( docValue, 'ratings', userId )
						
					end )
					:mapDataP( function( _, rating )
					
						rating.date = nil
						return 'data', rating
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { rating = 1 } )
		
		:waitFor( function()
		
			return LrmLibraryReviewModelImp.setAssetRating( fakeModel, 5, { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue )
					
						return 'data', KSTableUtils.derefOpt( docValue, 'ratings', userId )
						
					end )
					:mapDataP( function( _, rating )
					
						rating.date = nil
						return 'data', rating
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { rating = 5 } )
		
end

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

-- @mark Mix of un- / authenticated user ratings / reviews

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

function LrmLibraryReviewTest.testUnauthenticatedAssetRating( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
		
		:waitFor( function()
		
			catalog:setUserIsAuthenticated( true )

			return LrmLibraryReviewModelImp.setAssetRating( fakeModel, 1, { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			catalog:setUserIsAuthenticated( false )
			
			return LrmLibraryReviewModelImp.setAssetRating( fakeModel, 2, { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			catalog:setUserIsAuthenticated( true )
			
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue, localOverlay )
					
						local newRating = KSTableUtils.derefOpt( docValue, 'ratings', userId )
						local oldRating = KSTableUtils.derefOpt( docValue, 'ratings', WFOzSyncConstants.kGlobalDocumentId )
						
						return 'data', newRating, oldRating
						
					end )
					:mapDataP( function( _, rating, oldRating )
					
						rating.date = nil
						oldRating.date = nil
						
						return 'data', oldRating, rating
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { rating = 2 }, { rating = 1 } )
		
end

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

function LrmLibraryReviewTest.testUnauthenticatedAssetReview( test )

	local assetId = KSIdGenerator.uuidInLowercaseHex()
	
	WFAsyncTestCase( test, TEST_TIMEOUT )
		
		:waitFor( function()
		
			catalog:setUserIsAuthenticated( false )
			
			return LrmLibraryReviewModelImp.setAssetFlagStatus( fakeModel, 'pick', { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			catalog:setUserIsAuthenticated( true )
			
			return LrmLibraryReviewModelImp.setAssetFlagStatus( fakeModel, 'rejected', { assetId } ).valueB
			
		end )
		
		:continueWhenValueMatches( { state = true } )
		
		:waitFor( function()
		
			return catalog:ozUserIdP():mapDataP_new( function( userId )
			
				return catalog:docStore():docValueOnceP( 'asset', assetId )
					:mapDataP( function( _, docValue, localOverlay )
					
						local newReview = KSTableUtils.derefOpt( docValue, 'reviews', userId )
						local oldReview = KSTableUtils.derefOpt( docValue, 'reviews', WFOzSyncConstants.kGlobalDocumentId )
						
						return 'data', newReview, oldReview
						
					end )
					:mapDataP( function( _, review, oldReview )
					
						review.date = nil
						oldReview.date = nil
						
						return 'data', review, oldReview
						
					end )
					
			end )
				
		end )
		
		:continueWhenValueMatches( 'data', { flag = 'rejected' }, { flag = 'pick' } )
		
end
		
--------------------------------------------------------------------------------

return WFRxTestCase.wrapSuite( 'LrmLibraryReviewTest', LrmLibraryReviewTest )
