feat: add entity type DAO
This commit is contained in:
parent
59d05b6683
commit
95839efba6
4 changed files with 1233 additions and 1 deletions
17
Makefile
17
Makefile
|
|
@ -42,6 +42,7 @@ EVIDENCE_INTEGRITY_VERIFIER_TEST_CFLAGS := \
|
|||
$(TEST_CFLAGS) \
|
||||
-Wpedantic
|
||||
ENTITY_RECORD_TEST_CFLAGS := $(TEST_CFLAGS) -Wpedantic
|
||||
ENTITY_TYPE_DAO_TEST_CFLAGS := $(TEST_CFLAGS) -Wpedantic
|
||||
|
||||
SRC := $(shell find src -name "*.c")
|
||||
|
||||
|
|
@ -84,6 +85,7 @@ TEST_EVIDENCE_CATEGORY_ITEM := tests/test_evidence_category_item
|
|||
TEST_EVIDENCE_CATEGORY_MODEL := tests/test_evidence_category_model
|
||||
TEST_EVIDENCE_INTEGRITY_TASK := tests/test_evidence_integrity_task
|
||||
TEST_ENTITY_RECORD := tests/test_entity_record
|
||||
TEST_ENTITY_TYPE_DAO := tests/test_entity_type_dao
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
|
|
@ -375,6 +377,17 @@ $(TEST_ENTITY_RECORD): \
|
|||
src/models/entity_record.c
|
||||
$(CC) $(ENTITY_RECORD_TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS)
|
||||
|
||||
$(TEST_ENTITY_TYPE_DAO): \
|
||||
tests/test_entity_type_dao.c \
|
||||
src/dao/entity_type_dao.c \
|
||||
src/models/entity_type.c \
|
||||
src/database/database.c \
|
||||
src/database/schema.c \
|
||||
src/database/statement.c \
|
||||
src/database/transaction.c \
|
||||
src/database/error.c
|
||||
$(CC) $(ENTITY_TYPE_DAO_TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) -lsqlite3
|
||||
|
||||
test: \
|
||||
$(TEST_NODE) \
|
||||
$(TEST_TREE_MODEL) \
|
||||
|
|
@ -410,7 +423,8 @@ test: \
|
|||
$(TEST_EVIDENCE_IMPORT_TASK) \
|
||||
$(TEST_EVIDENCE_IMPORT_DIALOG) \
|
||||
$(TEST_EVIDENCE_INTEGRITY_TASK) \
|
||||
$(TEST_ENTITY_RECORD)
|
||||
$(TEST_ENTITY_RECORD) \
|
||||
$(TEST_ENTITY_TYPE_DAO)
|
||||
@echo "Exécution des tests..."
|
||||
@./$(TEST_NODE)
|
||||
@./$(TEST_TREE_MODEL)
|
||||
|
|
@ -447,6 +461,7 @@ test: \
|
|||
@$(TEST_EVIDENCE_IMPORT_DIALOG)
|
||||
@$(TEST_EVIDENCE_INTEGRITY_TASK)
|
||||
@$(TEST_ENTITY_RECORD)
|
||||
@$(TEST_ENTITY_TYPE_DAO)
|
||||
@echo "Tous les tests sont valides."
|
||||
|
||||
%.o: %.c
|
||||
|
|
|
|||
121
include/dao/entity_type_dao.h
Normal file
121
include/dao/entity_type_dao.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/******************************************************************************
|
||||
* @file entity_type_dao.h
|
||||
* @brief Lecture des types d'entité depuis SQLite.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LABFY_INVESTIGATION_ENTITY_TYPE_DAO_H
|
||||
#define LABFY_INVESTIGATION_ENTITY_TYPE_DAO_H
|
||||
|
||||
#include "database/database.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* @brief DAO opaque donnant accès aux types d'entité.
|
||||
*
|
||||
* Le DAO emprunte la connexion Database reçue lors de sa création.
|
||||
*/
|
||||
typedef struct EntityTypeDao EntityTypeDao;
|
||||
|
||||
/**
|
||||
* @brief Catégories d'erreurs produites par EntityTypeDao.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* Un argument public est invalide.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_INVALID_ARGUMENT,
|
||||
|
||||
/**
|
||||
* L'allocation d'une ressource a échoué.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_MEMORY,
|
||||
|
||||
/**
|
||||
* La requête SQLite n'a pas pu être préparée.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_PREPARE,
|
||||
|
||||
/**
|
||||
* Une ligne SQLite n'a pas pu être lue.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_READ,
|
||||
|
||||
/**
|
||||
* Une ligne SQLite ne peut pas produire un EntityType valide.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_MODEL,
|
||||
|
||||
/**
|
||||
* La table ou le schéma attendu est absent ou invalide.
|
||||
*/
|
||||
ENTITY_TYPE_DAO_ERROR_SCHEMA
|
||||
} EntityTypeDaoError;
|
||||
|
||||
/**
|
||||
* @brief Domaine d'erreur du DAO des types d'entité.
|
||||
*/
|
||||
#define ENTITY_TYPE_DAO_ERROR \
|
||||
entity_type_dao_error_quark()
|
||||
|
||||
/**
|
||||
* @brief Retourne le domaine d'erreur du DAO.
|
||||
*
|
||||
* @return Quark GLib associé à EntityTypeDao.
|
||||
*/
|
||||
GQuark entity_type_dao_error_quark(void);
|
||||
|
||||
/**
|
||||
* @brief Crée un DAO utilisant une connexion Database existante.
|
||||
*
|
||||
* La connexion est empruntée et doit rester valide pendant toute
|
||||
* la durée de vie du DAO.
|
||||
*
|
||||
* @param database Connexion SQLite ouverte.
|
||||
* @param error Emplacement facultatif recevant une erreur.
|
||||
*
|
||||
* @return Nouveau DAO, ou NULL en cas d'échec.
|
||||
*/
|
||||
EntityTypeDao *entity_type_dao_new(
|
||||
Database *database,
|
||||
GError **error
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Libère le DAO.
|
||||
*
|
||||
* La connexion Database empruntée n'est pas fermée.
|
||||
* Cette fonction accepte NULL.
|
||||
*
|
||||
* @param entity_type_dao DAO à libérer.
|
||||
*/
|
||||
void entity_type_dao_free(
|
||||
EntityTypeDao *entity_type_dao
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Charge tous les types d'entité.
|
||||
*
|
||||
* Les types sont triés par identifiant numérique croissant.
|
||||
*
|
||||
* Le tableau retourné appartient à l'appelant et utilise
|
||||
* entity_type_free() comme fonction de destruction.
|
||||
*
|
||||
* Une table vide produit un tableau vide, sans erreur.
|
||||
*
|
||||
* @param entity_type_dao DAO valide.
|
||||
* @param error Emplacement facultatif recevant une erreur.
|
||||
*
|
||||
* @return Nouveau GPtrArray, ou NULL en cas d'échec.
|
||||
*/
|
||||
GPtrArray *entity_type_dao_list_all(
|
||||
EntityTypeDao *entity_type_dao,
|
||||
GError **error
|
||||
);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
518
src/dao/entity_type_dao.c
Normal file
518
src/dao/entity_type_dao.c
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
/******************************************************************************
|
||||
* @file entity_type_dao.c
|
||||
* @brief Lecture des types d'entité depuis SQLite.
|
||||
******************************************************************************/
|
||||
|
||||
#include "dao/entity_type_dao.h"
|
||||
|
||||
#include "database/error.h"
|
||||
#include "database/statement.h"
|
||||
#include "models/entity_type.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Requête listant les types d'entité.
|
||||
*/
|
||||
static const char *const entity_type_dao_list_all_sql =
|
||||
"SELECT "
|
||||
" id, "
|
||||
" code, "
|
||||
" label, "
|
||||
" description "
|
||||
"FROM types_entite "
|
||||
"ORDER BY id ASC;";
|
||||
|
||||
/**
|
||||
* @struct EntityTypeDao
|
||||
* @brief Représentation interne du DAO.
|
||||
*/
|
||||
struct EntityTypeDao
|
||||
{
|
||||
Database *database;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Libère un EntityType contenu dans un GPtrArray.
|
||||
*/
|
||||
static void entity_type_dao_destroy_type(
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
EntityType *entity_type =
|
||||
user_data;
|
||||
|
||||
entity_type_free(
|
||||
entity_type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Détermine si un message SQLite indique un schéma incompatible.
|
||||
*/
|
||||
static gboolean entity_type_dao_is_schema_error(
|
||||
const char *database_message
|
||||
)
|
||||
{
|
||||
if (database_message == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return g_strstr_len(
|
||||
database_message,
|
||||
-1,
|
||||
"no such table"
|
||||
) != NULL ||
|
||||
g_strstr_len(
|
||||
database_message,
|
||||
-1,
|
||||
"no such column"
|
||||
) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enregistre une erreur de préparation SQL.
|
||||
*/
|
||||
static void entity_type_dao_set_prepare_error(
|
||||
EntityTypeDao *entity_type_dao,
|
||||
GError **error
|
||||
)
|
||||
{
|
||||
const char *database_message =
|
||||
NULL;
|
||||
|
||||
EntityTypeDaoError error_code =
|
||||
ENTITY_TYPE_DAO_ERROR_PREPARE;
|
||||
|
||||
if (error == NULL ||
|
||||
*error != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity_type_dao != NULL)
|
||||
{
|
||||
database_message =
|
||||
database_error_get_message(
|
||||
entity_type_dao->database
|
||||
);
|
||||
}
|
||||
|
||||
if (entity_type_dao_is_schema_error(
|
||||
database_message
|
||||
))
|
||||
{
|
||||
error_code =
|
||||
ENTITY_TYPE_DAO_ERROR_SCHEMA;
|
||||
}
|
||||
|
||||
g_set_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
error_code,
|
||||
"Impossible de préparer la lecture "
|
||||
"des types d'entité : %s",
|
||||
database_message != NULL
|
||||
? database_message
|
||||
: "erreur Database inconnue"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enregistre une erreur de lecture SQLite.
|
||||
*/
|
||||
static void entity_type_dao_set_read_error(
|
||||
EntityTypeDao *entity_type_dao,
|
||||
GError **error,
|
||||
const char *context
|
||||
)
|
||||
{
|
||||
const char *database_message =
|
||||
NULL;
|
||||
|
||||
if (error == NULL ||
|
||||
*error != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (entity_type_dao != NULL)
|
||||
{
|
||||
database_message =
|
||||
database_error_get_message(
|
||||
entity_type_dao->database
|
||||
);
|
||||
}
|
||||
|
||||
g_set_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_READ,
|
||||
"%s : %s",
|
||||
context != NULL
|
||||
? context
|
||||
: "Impossible de lire un type d'entité",
|
||||
database_message != NULL
|
||||
? database_message
|
||||
: "donnée SQLite invalide"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construit un EntityType depuis la ligne SQLite courante.
|
||||
*/
|
||||
static EntityType *entity_type_dao_read_current_row(
|
||||
EntityTypeDao *entity_type_dao,
|
||||
DatabaseStatement *statement,
|
||||
GError **error
|
||||
)
|
||||
{
|
||||
EntityType *entity_type =
|
||||
NULL;
|
||||
|
||||
int64_t identifier =
|
||||
0;
|
||||
|
||||
char *code =
|
||||
NULL;
|
||||
|
||||
char *label =
|
||||
NULL;
|
||||
|
||||
char *description =
|
||||
NULL;
|
||||
|
||||
GError *model_error =
|
||||
NULL;
|
||||
|
||||
if (entity_type_dao == NULL ||
|
||||
statement == NULL)
|
||||
{
|
||||
g_set_error_literal(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_INVALID_ARGUMENT,
|
||||
"La ligne du type d'entité ne peut pas être lue."
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!database_statement_column_int64(
|
||||
statement,
|
||||
0,
|
||||
&identifier
|
||||
))
|
||||
{
|
||||
entity_type_dao_set_read_error(
|
||||
entity_type_dao,
|
||||
error,
|
||||
"Impossible de lire l'identifiant du type d'entité"
|
||||
);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!database_statement_column_text(
|
||||
statement,
|
||||
1,
|
||||
&code
|
||||
))
|
||||
{
|
||||
entity_type_dao_set_read_error(
|
||||
entity_type_dao,
|
||||
error,
|
||||
"Impossible de lire le code du type d'entité"
|
||||
);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!database_statement_column_text(
|
||||
statement,
|
||||
2,
|
||||
&label
|
||||
))
|
||||
{
|
||||
entity_type_dao_set_read_error(
|
||||
entity_type_dao,
|
||||
error,
|
||||
"Impossible de lire le libellé du type d'entité"
|
||||
);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!database_statement_column_text(
|
||||
statement,
|
||||
3,
|
||||
&description
|
||||
))
|
||||
{
|
||||
entity_type_dao_set_read_error(
|
||||
entity_type_dao,
|
||||
error,
|
||||
"Impossible de lire la description du type d'entité"
|
||||
);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
entity_type =
|
||||
entity_type_new(
|
||||
(gint64) identifier,
|
||||
code,
|
||||
label,
|
||||
description,
|
||||
&model_error
|
||||
);
|
||||
|
||||
if (entity_type == NULL)
|
||||
{
|
||||
g_set_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_MODEL,
|
||||
"Le type d'entité lu depuis SQLite est invalide : %s",
|
||||
model_error != NULL
|
||||
? model_error->message
|
||||
: "erreur de modèle inconnue"
|
||||
);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
g_clear_error(
|
||||
&model_error
|
||||
);
|
||||
|
||||
g_free(
|
||||
description
|
||||
);
|
||||
|
||||
g_free(
|
||||
label
|
||||
);
|
||||
|
||||
g_free(
|
||||
code
|
||||
);
|
||||
|
||||
return entity_type;
|
||||
}
|
||||
|
||||
GQuark entity_type_dao_error_quark(void)
|
||||
{
|
||||
return g_quark_from_static_string(
|
||||
"entity-type-dao-error-quark"
|
||||
);
|
||||
}
|
||||
|
||||
EntityTypeDao *entity_type_dao_new(
|
||||
Database *database,
|
||||
GError **error
|
||||
)
|
||||
{
|
||||
EntityTypeDao *entity_type_dao =
|
||||
NULL;
|
||||
|
||||
g_return_val_if_fail(
|
||||
error == NULL || *error == NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (database == NULL)
|
||||
{
|
||||
g_set_error_literal(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_INVALID_ARGUMENT,
|
||||
"La connexion Database est obligatoire."
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entity_type_dao =
|
||||
g_try_new0(
|
||||
EntityTypeDao,
|
||||
1
|
||||
);
|
||||
|
||||
if (entity_type_dao == NULL)
|
||||
{
|
||||
g_set_error_literal(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_MEMORY,
|
||||
"Impossible d'allouer le DAO des types d'entité."
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* La connexion reste possédée par la session ou le code appelant.
|
||||
*/
|
||||
entity_type_dao->database =
|
||||
database;
|
||||
|
||||
return entity_type_dao;
|
||||
}
|
||||
|
||||
void entity_type_dao_free(
|
||||
EntityTypeDao *entity_type_dao
|
||||
)
|
||||
{
|
||||
if (entity_type_dao == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Database est empruntée et ne doit pas être fermée ici.
|
||||
*/
|
||||
entity_type_dao->database =
|
||||
NULL;
|
||||
|
||||
g_free(
|
||||
entity_type_dao
|
||||
);
|
||||
}
|
||||
|
||||
GPtrArray *entity_type_dao_list_all(
|
||||
EntityTypeDao *entity_type_dao,
|
||||
GError **error
|
||||
)
|
||||
{
|
||||
DatabaseStatement *statement =
|
||||
NULL;
|
||||
|
||||
GPtrArray *entity_types =
|
||||
NULL;
|
||||
|
||||
DatabaseStatementStepResult step_result =
|
||||
DATABASE_STATEMENT_STEP_ERROR;
|
||||
|
||||
gboolean success =
|
||||
FALSE;
|
||||
|
||||
g_return_val_if_fail(
|
||||
error == NULL || *error == NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (entity_type_dao == NULL ||
|
||||
entity_type_dao->database == NULL)
|
||||
{
|
||||
g_set_error_literal(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_INVALID_ARGUMENT,
|
||||
"Le DAO des types d'entité est invalide."
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entity_types =
|
||||
g_ptr_array_new_with_free_func(
|
||||
entity_type_dao_destroy_type
|
||||
);
|
||||
|
||||
if (entity_types == NULL)
|
||||
{
|
||||
g_set_error_literal(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_MEMORY,
|
||||
"Impossible d'allouer la liste des types d'entité."
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
statement =
|
||||
database_statement_prepare(
|
||||
entity_type_dao->database,
|
||||
entity_type_dao_list_all_sql
|
||||
);
|
||||
|
||||
if (statement == NULL)
|
||||
{
|
||||
entity_type_dao_set_prepare_error(
|
||||
entity_type_dao,
|
||||
error
|
||||
);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
EntityType *entity_type =
|
||||
NULL;
|
||||
|
||||
step_result =
|
||||
database_statement_step(
|
||||
statement
|
||||
);
|
||||
|
||||
if (step_result ==
|
||||
DATABASE_STATEMENT_STEP_DONE)
|
||||
{
|
||||
success =
|
||||
TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (step_result ==
|
||||
DATABASE_STATEMENT_STEP_ERROR)
|
||||
{
|
||||
entity_type_dao_set_read_error(
|
||||
entity_type_dao,
|
||||
error,
|
||||
"Impossible de parcourir les types d'entité"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
entity_type =
|
||||
entity_type_dao_read_current_row(
|
||||
entity_type_dao,
|
||||
statement,
|
||||
error
|
||||
);
|
||||
|
||||
if (entity_type == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
g_ptr_array_add(
|
||||
entity_types,
|
||||
entity_type
|
||||
);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
database_statement_finalize(
|
||||
statement
|
||||
);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
g_ptr_array_unref(
|
||||
entity_types
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return entity_types;
|
||||
}
|
||||
578
tests/test_entity_type_dao.c
Normal file
578
tests/test_entity_type_dao.c
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
/******************************************************************************
|
||||
* @file test_entity_type_dao.c
|
||||
* @brief Tests du DAO des types d'entité.
|
||||
******************************************************************************/
|
||||
|
||||
#include "dao/entity_type_dao.h"
|
||||
|
||||
#include "database/database.h"
|
||||
#include "database/statement.h"
|
||||
#include "models/entity_type.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
/**
|
||||
* @brief Ressources utilisées par un test EntityTypeDao.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *temporary_directory;
|
||||
char *database_path;
|
||||
|
||||
Database *database;
|
||||
EntityTypeDao *entity_type_dao;
|
||||
} TestEntityTypeDaoFixture;
|
||||
|
||||
/**
|
||||
* @brief Exécute une requête SQL ne retournant aucune ligne.
|
||||
*/
|
||||
static void test_entity_type_dao_execute_sql(
|
||||
Database *database,
|
||||
const char *sql
|
||||
)
|
||||
{
|
||||
DatabaseStatement *statement =
|
||||
NULL;
|
||||
|
||||
g_assert_nonnull(
|
||||
database
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
sql
|
||||
);
|
||||
|
||||
statement =
|
||||
database_statement_prepare(
|
||||
database,
|
||||
sql
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
statement
|
||||
);
|
||||
|
||||
g_assert_cmpint(
|
||||
database_statement_step(
|
||||
statement
|
||||
),
|
||||
==,
|
||||
DATABASE_STATEMENT_STEP_DONE
|
||||
);
|
||||
|
||||
database_statement_finalize(
|
||||
statement
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Crée une base temporaire contenant le schéma de l'application.
|
||||
*/
|
||||
static TestEntityTypeDaoFixture
|
||||
test_entity_type_dao_fixture_create(void)
|
||||
{
|
||||
TestEntityTypeDaoFixture fixture =
|
||||
{0};
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
fixture.temporary_directory =
|
||||
g_dir_make_tmp(
|
||||
"labfy-entity-type-dao-test-XXXXXX",
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_no_error(
|
||||
error
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
fixture.temporary_directory
|
||||
);
|
||||
|
||||
fixture.database_path =
|
||||
g_build_filename(
|
||||
fixture.temporary_directory,
|
||||
"Enquete.sqlite",
|
||||
NULL
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
fixture.database_path
|
||||
);
|
||||
|
||||
g_assert_true(
|
||||
database_initialize(
|
||||
fixture.database_path,
|
||||
"Enquete_EntityTypeDao",
|
||||
fixture.temporary_directory
|
||||
)
|
||||
);
|
||||
|
||||
fixture.database =
|
||||
database_open(
|
||||
fixture.database_path
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
fixture.database
|
||||
);
|
||||
|
||||
fixture.entity_type_dao =
|
||||
entity_type_dao_new(
|
||||
fixture.database,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_no_error(
|
||||
error
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
fixture.entity_type_dao
|
||||
);
|
||||
|
||||
return fixture;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Libère la fixture et supprime la base temporaire.
|
||||
*/
|
||||
static void test_entity_type_dao_fixture_clear(
|
||||
TestEntityTypeDaoFixture *fixture
|
||||
)
|
||||
{
|
||||
g_assert_nonnull(
|
||||
fixture
|
||||
);
|
||||
|
||||
entity_type_dao_free(
|
||||
fixture->entity_type_dao
|
||||
);
|
||||
|
||||
database_close(
|
||||
fixture->database
|
||||
);
|
||||
|
||||
g_assert_cmpint(
|
||||
g_remove(
|
||||
fixture->database_path
|
||||
),
|
||||
==,
|
||||
0
|
||||
);
|
||||
|
||||
g_assert_cmpint(
|
||||
g_rmdir(
|
||||
fixture->temporary_directory
|
||||
),
|
||||
==,
|
||||
0
|
||||
);
|
||||
|
||||
g_free(
|
||||
fixture->database_path
|
||||
);
|
||||
|
||||
g_free(
|
||||
fixture->temporary_directory
|
||||
);
|
||||
|
||||
fixture->entity_type_dao =
|
||||
NULL;
|
||||
|
||||
fixture->database =
|
||||
NULL;
|
||||
|
||||
fixture->database_path =
|
||||
NULL;
|
||||
|
||||
fixture->temporary_directory =
|
||||
NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vérifie le refus d'une connexion absente.
|
||||
*/
|
||||
static void test_entity_type_dao_new_invalid_database(void)
|
||||
{
|
||||
EntityTypeDao *entity_type_dao =
|
||||
NULL;
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
entity_type_dao =
|
||||
entity_type_dao_new(
|
||||
NULL,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_null(
|
||||
entity_type_dao
|
||||
);
|
||||
|
||||
g_assert_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_INVALID_ARGUMENT
|
||||
);
|
||||
|
||||
g_clear_error(
|
||||
&error
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vérifie le chargement du catalogue initial.
|
||||
*/
|
||||
static void test_entity_type_dao_list_all(void)
|
||||
{
|
||||
static const char *const expected_codes[] =
|
||||
{
|
||||
"email_address",
|
||||
"bank_account",
|
||||
"facebook_account",
|
||||
"instagram_account",
|
||||
"identity_document",
|
||||
"iban",
|
||||
"person",
|
||||
"pseudonym",
|
||||
"phone_number",
|
||||
"website",
|
||||
"domain_name",
|
||||
"ip_address",
|
||||
"organization",
|
||||
"other"
|
||||
};
|
||||
|
||||
static const char *const expected_labels[] =
|
||||
{
|
||||
"Adresse email",
|
||||
"Compte bancaire",
|
||||
"Compte Facebook",
|
||||
"Compte Instagram",
|
||||
"Document d'identité",
|
||||
"IBAN",
|
||||
"Personne",
|
||||
"Pseudonyme",
|
||||
"Numéro de téléphone",
|
||||
"Site web",
|
||||
"Nom de domaine",
|
||||
"Adresse IP",
|
||||
"Organisation",
|
||||
"Autre"
|
||||
};
|
||||
|
||||
TestEntityTypeDaoFixture fixture =
|
||||
test_entity_type_dao_fixture_create();
|
||||
|
||||
GPtrArray *entity_types =
|
||||
NULL;
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
guint index =
|
||||
0;
|
||||
|
||||
entity_types =
|
||||
entity_type_dao_list_all(
|
||||
fixture.entity_type_dao,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_no_error(
|
||||
error
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
entity_types
|
||||
);
|
||||
|
||||
g_assert_cmpuint(
|
||||
entity_types->len,
|
||||
==,
|
||||
G_N_ELEMENTS(
|
||||
expected_codes
|
||||
)
|
||||
);
|
||||
|
||||
for (index = 0;
|
||||
index < entity_types->len;
|
||||
index++)
|
||||
{
|
||||
const EntityType *entity_type =
|
||||
NULL;
|
||||
|
||||
entity_type =
|
||||
g_ptr_array_index(
|
||||
entity_types,
|
||||
index
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
entity_type
|
||||
);
|
||||
|
||||
/*
|
||||
* La requête utilise ORDER BY id ASC.
|
||||
*/
|
||||
g_assert_cmpint(
|
||||
entity_type_get_identifier(
|
||||
entity_type
|
||||
),
|
||||
==,
|
||||
(gint64) index + 1
|
||||
);
|
||||
|
||||
g_assert_cmpstr(
|
||||
entity_type_get_code(
|
||||
entity_type
|
||||
),
|
||||
==,
|
||||
expected_codes[index]
|
||||
);
|
||||
|
||||
g_assert_cmpstr(
|
||||
entity_type_get_label(
|
||||
entity_type
|
||||
),
|
||||
==,
|
||||
expected_labels[index]
|
||||
);
|
||||
|
||||
/*
|
||||
* Le catalogue V1 ne renseigne aucune description.
|
||||
*/
|
||||
g_assert_null(
|
||||
entity_type_get_description(
|
||||
entity_type
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
g_ptr_array_unref(
|
||||
entity_types
|
||||
);
|
||||
|
||||
test_entity_type_dao_fixture_clear(
|
||||
&fixture
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vérifie qu'une table vide retourne un tableau vide.
|
||||
*/
|
||||
static void test_entity_type_dao_list_empty(void)
|
||||
{
|
||||
TestEntityTypeDaoFixture fixture =
|
||||
test_entity_type_dao_fixture_create();
|
||||
|
||||
GPtrArray *entity_types =
|
||||
NULL;
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
test_entity_type_dao_execute_sql(
|
||||
fixture.database,
|
||||
"DELETE FROM types_entite;"
|
||||
);
|
||||
|
||||
entity_types =
|
||||
entity_type_dao_list_all(
|
||||
fixture.entity_type_dao,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_no_error(
|
||||
error
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
entity_types
|
||||
);
|
||||
|
||||
g_assert_cmpuint(
|
||||
entity_types->len,
|
||||
==,
|
||||
0
|
||||
);
|
||||
|
||||
g_ptr_array_unref(
|
||||
entity_types
|
||||
);
|
||||
|
||||
test_entity_type_dao_fixture_clear(
|
||||
&fixture
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vérifie le signalement d'une table absente.
|
||||
*/
|
||||
static void test_entity_type_dao_missing_table(void)
|
||||
{
|
||||
Database *database =
|
||||
NULL;
|
||||
|
||||
EntityTypeDao *entity_type_dao =
|
||||
NULL;
|
||||
|
||||
GPtrArray *entity_types =
|
||||
NULL;
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
database =
|
||||
database_open(
|
||||
":memory:"
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
database
|
||||
);
|
||||
|
||||
entity_type_dao =
|
||||
entity_type_dao_new(
|
||||
database,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_no_error(
|
||||
error
|
||||
);
|
||||
|
||||
g_assert_nonnull(
|
||||
entity_type_dao
|
||||
);
|
||||
|
||||
g_test_expect_message(
|
||||
NULL,
|
||||
G_LOG_LEVEL_WARNING,
|
||||
"*Impossible de préparer la requête SQL*"
|
||||
);
|
||||
|
||||
entity_types =
|
||||
entity_type_dao_list_all(
|
||||
entity_type_dao,
|
||||
&error
|
||||
);
|
||||
|
||||
g_test_assert_expected_messages();
|
||||
|
||||
g_assert_null(
|
||||
entity_types
|
||||
);
|
||||
|
||||
g_assert_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_SCHEMA
|
||||
);
|
||||
|
||||
g_clear_error(
|
||||
&error
|
||||
);
|
||||
|
||||
entity_type_dao_free(
|
||||
entity_type_dao
|
||||
);
|
||||
|
||||
database_close(
|
||||
database
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Vérifie le refus d'une ligne produisant un modèle invalide.
|
||||
*/
|
||||
static void test_entity_type_dao_invalid_model(void)
|
||||
{
|
||||
TestEntityTypeDaoFixture fixture =
|
||||
test_entity_type_dao_fixture_create();
|
||||
|
||||
GPtrArray *entity_types =
|
||||
NULL;
|
||||
|
||||
GError *error =
|
||||
NULL;
|
||||
|
||||
/*
|
||||
* Le schéma interdit NULL mais autorise actuellement
|
||||
* une chaîne uniquement composée d'espaces.
|
||||
*/
|
||||
test_entity_type_dao_execute_sql(
|
||||
fixture.database,
|
||||
"UPDATE types_entite "
|
||||
"SET code = ' ' "
|
||||
"WHERE id = 1;"
|
||||
);
|
||||
|
||||
entity_types =
|
||||
entity_type_dao_list_all(
|
||||
fixture.entity_type_dao,
|
||||
&error
|
||||
);
|
||||
|
||||
g_assert_null(
|
||||
entity_types
|
||||
);
|
||||
|
||||
g_assert_error(
|
||||
error,
|
||||
ENTITY_TYPE_DAO_ERROR,
|
||||
ENTITY_TYPE_DAO_ERROR_MODEL
|
||||
);
|
||||
|
||||
g_clear_error(
|
||||
&error
|
||||
);
|
||||
|
||||
test_entity_type_dao_fixture_clear(
|
||||
&fixture
|
||||
);
|
||||
}
|
||||
|
||||
int main(
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
g_test_init(
|
||||
&argc,
|
||||
&argv,
|
||||
NULL
|
||||
);
|
||||
|
||||
g_test_add_func(
|
||||
"/entity-type-dao/new-invalid-database",
|
||||
test_entity_type_dao_new_invalid_database
|
||||
);
|
||||
|
||||
g_test_add_func(
|
||||
"/entity-type-dao/list-all",
|
||||
test_entity_type_dao_list_all
|
||||
);
|
||||
|
||||
g_test_add_func(
|
||||
"/entity-type-dao/list-empty",
|
||||
test_entity_type_dao_list_empty
|
||||
);
|
||||
|
||||
g_test_add_func(
|
||||
"/entity-type-dao/missing-table",
|
||||
test_entity_type_dao_missing_table
|
||||
);
|
||||
|
||||
g_test_add_func(
|
||||
"/entity-type-dao/invalid-model",
|
||||
test_entity_type_dao_invalid_model
|
||||
);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
Loading…
Reference in a new issue