Request for querying users.
        /// <summary>
        /// Gets users of specified criteria that are associated with Data Objects within specified collection.
        /// <remarks>The collection_id/collection_key parameter means that one can use either one of them - collection_id or collection_key.</remarks>
        /// </summary>
        /// <param name="request">User query request object.</param>
        /// <returns>List of User objects.</returns>
        public Task<List<User>> Get(UserQueryRequest request)
        {
            if(request.ProjectId == null)
                throw new ArgumentNullException();

            if (request.CollectionId == null && request.CollectionKey == null)
                throw new ArgumentNullException();

            var folders = request.Folders == null ? new List<string>() : new List<string>(request.Folders);
            if (folders.Count + (request.Folder != null ? 1 : 0) >
                DataObjectSyncanoClient.MaxVauluesPerRequest)
                throw new ArgumentException();
            if (request.Folder != null)
                folders.Add(request.Folder);

            return _syncanoClient.PostAsync<List<User>>("user.get",
                new
                {
                    project_id = request.ProjectId,
                    collection_id = request.CollectionId,
                    collection_key = request.CollectionKey,
                    state = request.State.ToString(),
                    folders = folders.ToArray(),
                    filter = request.Filter == null ? null : request.Filter.ToString()
                }, "user");
        }
        public async Task Count_WithImageContentFilter_GetsCountOfUsers(UserSyncanoClient client)
        {
            //given
            var dataRequest = new DataObjectDefinitionRequest();
            dataRequest.ProjectId = TestData.ProjectId;
            dataRequest.CollectionId = TestData.CollectionId;
            dataRequest.ImageBase64 = TestData.ImageToBase64("smallSampleImage.png");
            await _dataClient.New(dataRequest);

            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;
            request.CollectionId = TestData.CollectionId;
            request.Filter = DataObjectContentFilter.Image;

            //when
            var result = await client.Count(request);

            //then
            result.ShouldEqual(1);

            //cleanup
            var deleteRequest = new DataObjectSimpleQueryRequest();
            deleteRequest.ProjectId = TestData.ProjectId;
            deleteRequest.CollectionId = TestData.CollectionId;

            await _dataClient.Delete(deleteRequest);
        }
        /// <summary>
        /// Count users of specified criteria.
        /// <remarks>The collection_id/collection_key parameter means that one can use either one of them - collection_id or collection_key.</remarks>
        /// </summary>
        /// <param name="request">User query request object.</param>
        /// <returns>Count of users with specified criteria.</returns>
        public Task<int> Count(UserQueryRequest request)
        {
            if (request.ProjectId == null)
                throw new ArgumentNullException();

            if (request.CollectionId != null && request.CollectionKey != null)
                throw new ArgumentException();

            var folders = request.Folders == null ? new List<string>() : new List<string>(request.Folders);
            if (folders.Count + (request.Folder != null ? 1 : 0) >
                MaxLimit)
                throw new ArgumentException();
            if (request.Folder != null)
                folders.Add(request.Folder);

            return _syncanoClient.PostAsync<int>("user.count",
                new
                {
                    project_id = request.ProjectId,
                    collection_id = request.CollectionId,
                    collection_key = request.CollectionKey,
                    state = request.State.ToString(),
                    folders = folders.ToArray(),
                    filter = request.Filter == null ? null : request.Filter.ToString()
                }, "count");
        }
        public async Task Count_WithFolderListName_GetsCountOfUsers(UserSyncanoClient client)
        {
            //given
            var dataRequest = new DataObjectDefinitionRequest();
            dataRequest.ProjectId = TestData.ProjectId;
            dataRequest.CollectionId = TestData.CollectionId;
            dataRequest.Folder = TestData.FolderName;
            await _dataClient.New(dataRequest);

            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;
            request.CollectionId = TestData.CollectionId;
            request.Folders = new List<string> { TestData.FolderName };

            //when
            var result = await client.Count(request);

            //then
            result.ShouldEqual(1);

            //cleanup
            var deleteRequest = new DataObjectSimpleQueryRequest();
            deleteRequest.ProjectId = TestData.ProjectId;
            deleteRequest.CollectionId = TestData.CollectionId;

            await _dataClient.Delete(deleteRequest);
        }
        public async Task Count_WithPendingState_GetsCountOfUsers(UserSyncanoClient client)
        {
            //given
            var dataRequest = new DataObjectDefinitionRequest();
            dataRequest.ProjectId = TestData.ProjectId;
            dataRequest.CollectionId = TestData.CollectionId;
            dataRequest.State = DataObjectState.Pending;
            await _dataClient.New(dataRequest);

            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;
            request.CollectionId = TestData.CollectionId;
            request.State = DataObjectState.Pending;

            //when
            var result = await client.Count(request);

            //then
            result.ShouldEqual(1);

            //cleanup
            var deleteRequest = new DataObjectSimpleQueryRequest();
            deleteRequest.ProjectId = TestData.ProjectId;
            deleteRequest.CollectionId = TestData.CollectionId;

            await _dataClient.Delete(deleteRequest);
        }
        public async Task Get_WithNullCollectionIdAndCollectionKey_ThrowsException(UserSyncanoClient client)
        {
            //given
            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;

            try
            {
                //when
                await client.Get(request);
                throw new Exception("Get should throw an exception.");
            }
            catch (Exception e)
            {
                //then
                e.ShouldBeType<ArgumentNullException>();
            }
        }
        public async Task Get_WithInvalidCollectionId_ThrowsException(UserSyncanoClient client)
        {
            //given
            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;
            request.CollectionId = "abcde";

            try
            {
                //when
                await client.Get(request);
                throw new Exception("Get should throw an exception.");
            }
            catch (Exception e)
            {
                //then
                e.ShouldBeType<SyncanoException>();
            }
        }
        public async Task Get_WithTextContentFilter_GetsListOfUsers(UserSyncanoClient client)
        {
            //given
            var dataRequest = new DataObjectDefinitionRequest();
            dataRequest.ProjectId = TestData.ProjectId;
            dataRequest.CollectionId = TestData.CollectionId;
            dataRequest.Text = "sample text content";
            await _dataClient.New(dataRequest);

            var request = new UserQueryRequest();
            request.ProjectId = TestData.ProjectId;
            request.CollectionId = TestData.CollectionId;
            request.Filter = DataObjectContentFilter.Text;

            //when
            var result = await client.Get(request);

            //then
            result.ShouldNotBeNull();
            result.Count.ShouldEqual(1);

            //cleanup
            var deleteRequest = new DataObjectSimpleQueryRequest();
            deleteRequest.ProjectId = TestData.ProjectId;
            deleteRequest.CollectionId = TestData.CollectionId;

            await _dataClient.Delete(deleteRequest);
        }