public async Task RequestGenericSingle()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.NestedSingleResult);

            HttpCommand command = new HttpCommand(mockDB.Db)
            {
                EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking
            };

            var result = await command.RequestGenericSingleResult <Person, DocumentInheritedCommandResult <Person> >();

            Assert.Equal(result.BaseResult.Code, 200);
            Assert.Equal(result.BaseResult.Error, false);

            Assert.Equal(result.Result.Age, 27);
            Assert.Equal(result.Result.Fullname, "raoof hojat");
            Assert.Equal(result.Result.Height, 172);

            var info = mockDB.Db.FindDocumentInfo(result.Result);

            Assert.Equal(info.Id, "Person/KEY");
            Assert.Equal(info.Key, "KEY");
            Assert.Equal(info.Rev, "REV");
            Assert.True(JObject.DeepEquals(info.Document, JObject.Parse(JsonSample.SingleResult)));
        }
        /// <summary>
        /// Fetches an existing edge
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The document handle or key of document</param>
        /// <param name="baseResult"></param>
        /// <returns>T</returns>
        public async Task <T> GetAsync <T>(string id, string ifMatchRev = null, Action <BaseResult> baseResult = null)
        {
            var documentHandle = id.IndexOf("/") == -1 ? $"{collection}/{id}" : id;

            var command = new HttpCommand(this.db)
            {
                Api     = CommandApi.Graph,
                Method  = HttpMethod.Get,
                Command = $"{graphName}/edge/{documentHandle}",
                EnableChangeTracking = db.Setting.DisableChangeTracking == false,
                Headers = new Dictionary <string, string>()
            };

            if (string.IsNullOrEmpty(ifMatchRev) == false)
            {
                command.Headers.Add("If-Match", ifMatchRev);
            }

            var result = await command.RequestGenericSingleResult <T, EdgeInheritedCommandResult <T> >(throwForServerErrors : false).ConfigureAwait(false);

            if (db.Setting.Document.ThrowIfDocumentDoesNotExists ||
                (result.BaseResult.HasError() && result.BaseResult.ErrorNum != 1202))
            {
                new BaseResultAnalyzer(db).Throw(result.BaseResult);
            }

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }

            return(result.Result);
        }
        /// <summary>
        /// Fetches an existing edge
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The document handle or key of document</param>
        /// <param name="baseResult"></param>
        /// <returns>T</returns>
        public async Task <T> GetAsync <T>(string id, Action <BaseResult> baseResult = null)
        {
            var documentHandle = id.IndexOf("/") == -1 ? $"{collection}/{id}" : id;

            var command = new HttpCommand(this.db)
            {
                Api     = CommandApi.Graph,
                Method  = HttpMethod.Get,
                Command = $"{graphName}/edge/{documentHandle}",
                EnableChangeTracking = !db.Setting.DisableChangeTracking
            };

            var defaultThrowForServerErrors = db.Setting.ThrowForServerErrors;

            db.Setting.ThrowForServerErrors = false;

            var result = await command.RequestGenericSingleResult <T, EdgeInheritedCommandResult <T> >().ConfigureAwait(false);

            db.Setting.ThrowForServerErrors = defaultThrowForServerErrors;

            if (db.Setting.Document.ThrowIfDocumentDoesNotExists ||
                (result.BaseResult.Error && result.BaseResult.ErrorNum != 1202))
            {
                new BaseResultAnalyzer(db).Throw(result.BaseResult);
            }

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }

            return(result.Result);
        }
        public async Task RequestGenericSingle_BadRequest()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.Error, statusCode: HttpStatusCode.NotFound);

            HttpCommand command = new HttpCommand(mockDB.Db)
            {
                EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking
            };

            await Assert.ThrowsAsync <ArangoServerException>(() => command.RequestGenericSingleResult <Person, DocumentInheritedCommandResult <Person> >());
        }
        /// <summary>
        /// Retrieves information about the current database
        /// </summary>
        /// <returns>DatabaseInformation</returns>
        public async Task<DatabaseInformation> CurrentDatabaseInformationAsync(Action<BaseResult> baseResult=null)
        {
            var command = new HttpCommand(this)
            {
                Api = CommandApi.Database,
                Method = HttpMethod.Get,
                Command = "current"
            };

            var result = await command.RequestGenericSingleResult<DatabaseInformation, InheritedCommandResult<DatabaseInformation>>().ConfigureAwait(false);

            if(baseResult!=null)
                baseResult(result.BaseResult);

            return result.Result;
        }
        /// <summary>
        /// Deletes a database
        /// </summary>
        /// <param name="name">Name of the database</param>
        /// <returns></returns>
        public async Task DropDatabaseAsync(string name, Action <BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api             = CommandApi.Database,
                Method          = HttpMethod.Delete,
                IsSystemCommand = true,
                Command         = name
            };

            var result = await command.RequestGenericSingleResult <bool, InheritedCommandResult <bool> >().ConfigureAwait(false);

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }
        }
        /// <summary>
        /// Retrieves information about the current database
        /// </summary>
        /// <returns>DatabaseInformation</returns>
        public async Task <DatabaseInformation> CurrentDatabaseInformationAsync(Action <BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api     = CommandApi.Database,
                Method  = HttpMethod.Get,
                Command = "current"
            };

            var result = await command.RequestGenericSingleResult <DatabaseInformation, InheritedCommandResult <DatabaseInformation> >().ConfigureAwait(false);

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }

            return(result.Result);
        }
        public async Task RequestGenericSingle_BadRequest_DontThrow()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.Error, statusCode: HttpStatusCode.NotFound);

            mockDB.Db.Setting.ThrowForServerErrors = false;

            HttpCommand command = new HttpCommand(mockDB.Db)
            {
                EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking
            };

            var result = await command.RequestGenericSingleResult <Person, DocumentInheritedCommandResult <Person> >();

            Assert.Null(result.Result);
            Assert.Equal(result.BaseResult.Code, 400);
            Assert.Equal(result.BaseResult.Error, true);
            Assert.Equal(result.BaseResult.ErrorMessage, "ERROR");
        }
        public async Task <TResult> ExecuteTransactionAsync <TResult>(TransactionData data, Action <BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api    = CommandApi.Transaction,
                Method = HttpMethod.Post
            };

            if (data.Action != null)
            {
                data.Action = data.Action.Replace("\r\n", " ");
            }

            var result = await command.RequestGenericSingleResult <TResult, InheritedCommandResult <TResult> >(data).ConfigureAwait(false);

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }

            return(result.Result);
        }
        /// <summary>
        /// Creates a database
        /// </summary>
        /// <param name="name">Name of the database</param>
        /// <param name="users">list of database user</param>
        /// <returns></returns>
        public async Task CreateDatabaseAsync(string name, List <DatabaseUser> users = null, Action <BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api             = CommandApi.Database,
                Method          = HttpMethod.Post,
                IsSystemCommand = true
            };

            var data = new CreateDatabaseData
            {
                Name  = name,
                Users = users
            };

            var result = await command.RequestGenericSingleResult <bool, InheritedCommandResult <bool> >(data).ConfigureAwait(false);

            if (baseResult != null)
            {
                baseResult(result.BaseResult);
            }
        }
        public async Task RequestGenericSingle_WithoutChangeTracking()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.NestedSingleResult);

            mockDB.Db.Setting.DisableChangeTracking = true;

            HttpCommand command = new HttpCommand(mockDB.Db)
            {
                EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking
            };

            var result = await command.RequestGenericSingleResult <Person, DocumentInheritedCommandResult <Person> >();

            Assert.Equal(result.BaseResult.Code, 200);
            Assert.Equal(result.BaseResult.Error, false);

            Assert.Equal(result.Result.Age, 27);
            Assert.Equal(result.Result.Fullname, "raoof hojat");
            Assert.Equal(result.Result.Height, 172);

            Assert.Throws <Exception>(() => mockDB.Db.FindDocumentInfo(result.Result));
        }
        public async Task RequestGenericSingle()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.NestedSingleResult);

            HttpCommand command = new HttpCommand(mockDB.Db) { EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking };

            var result = await command.RequestGenericSingleResult<Person, DocumentInheritedCommandResult<Person>>();

            Assert.Equal(result.BaseResult.Code, 200);
            Assert.Equal(result.BaseResult.Error, false);

            Assert.Equal(result.Result.Age, 27);
            Assert.Equal(result.Result.Fullname, "raoof hojat");
            Assert.Equal(result.Result.Height, 172);

            var info = mockDB.Db.FindDocumentInfo(result.Result);
            Assert.Equal(info.Id, "Person/KEY");
            Assert.Equal(info.Key, "KEY");
            Assert.Equal(info.Rev, "REV");
            Assert.True(JObject.DeepEquals(info.Document, JObject.Parse(JsonSample.SingleResult)));
        }
        public async Task RequestGenericSingle_WithoutChangeTracking()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.NestedSingleResult);

            mockDB.Db.Setting.DisableChangeTracking = true;

            HttpCommand command = new HttpCommand(mockDB.Db) { EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking };

            var result = await command.RequestGenericSingleResult<Person, DocumentInheritedCommandResult<Person>>();

            Assert.Equal(result.BaseResult.Code, 200);
            Assert.Equal(result.BaseResult.Error, false);

            Assert.Equal(result.Result.Age, 27);
            Assert.Equal(result.Result.Fullname, "raoof hojat");
            Assert.Equal(result.Result.Height, 172);

            Assert.Throws<Exception>(() => mockDB.Db.FindDocumentInfo(result.Result));
        }
        /// <summary>
        /// Deletes a database
        /// </summary>
        /// <param name="name">Name of the database</param>
        /// <returns></returns>
        public async Task DropDatabaseAsync(string name, Action<BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api = CommandApi.Database,
                Method = HttpMethod.Delete,
                IsSystemCommand = true,
                Command = name
            };

            var result = await command.RequestGenericSingleResult<bool, InheritedCommandResult<bool>>().ConfigureAwait(false);

            if (baseResult != null)
                baseResult(result.BaseResult);
        }
        /// <summary>
        /// Creates a database
        /// </summary>
        /// <param name="name">Name of the database</param>
        /// <param name="users">list of database user</param>
        /// <returns></returns>
        public async Task CreateDatabaseAsync(string name, List<DatabaseUser> users = null, Action<BaseResult> baseResult = null)
        {
            var command = new HttpCommand(this)
            {
                Api = CommandApi.Database,
                Method = HttpMethod.Post,
                IsSystemCommand = true
            };

            var data = new CreateDatabaseData
            {
                Name = name,
                Users = users
            };

            var result = await command.RequestGenericSingleResult<bool, InheritedCommandResult<bool>>(data).ConfigureAwait(false);

            if (baseResult != null)
                baseResult(result.BaseResult);
        }
        public async Task RequestGenericSingle_WithoutChangeTracking_BadRequest_DontThrow()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.Error, statusCode: HttpStatusCode.NotFound);

            mockDB.Db.Setting.DisableChangeTracking = true;
            mockDB.Db.Setting.ThrowForServerErrors = false;

            HttpCommand command = new HttpCommand(mockDB.Db) { EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking };

            var result = await command.RequestGenericSingleResult<Person, DocumentInheritedCommandResult<Person>>();

            Assert.Null(result.Result);
            Assert.Equal(result.BaseResult.Code, 400);
            Assert.Equal(result.BaseResult.Error, true);
            Assert.Equal(result.BaseResult.ErrorMessage, "ERROR");
        }
        public async Task RequestGenericSingle_WithoutChangeTracking_BadRequest()
        {
            var mockDB = new ArangoDatabaseMock().WithChangeTracking();

            mockDB.SendCommand(JsonSample.Error, statusCode: HttpStatusCode.NotFound);

            mockDB.Db.Setting.DisableChangeTracking = true;

            HttpCommand command = new HttpCommand(mockDB.Db) { EnableChangeTracking = !mockDB.Db.Setting.DisableChangeTracking };

            await Assert.ThrowsAsync<ArangoServerException>(() => command.RequestGenericSingleResult<Person, DocumentInheritedCommandResult<Person>>());
        }