feat(core): create investigation project structure
This commit is contained in:
parent
d5324f9573
commit
e5f3479f71
10 changed files with 1197 additions and 2 deletions
16
Makefile
16
Makefile
|
|
@ -32,6 +32,7 @@ TARGET = labfy-investigation
|
||||||
TEST_NODE = tests/test_investigation_node
|
TEST_NODE = tests/test_investigation_node
|
||||||
TEST_TREE_MODEL = tests/test_investigation_tree_model
|
TEST_TREE_MODEL = tests/test_investigation_tree_model
|
||||||
TEST_TREE_BUILDER = tests/test_investigation_tree_builder
|
TEST_TREE_BUILDER = tests/test_investigation_tree_builder
|
||||||
|
TEST_PROJECT = tests/test_investigation_project
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
|
|
@ -57,11 +58,21 @@ $(TEST_TREE_BUILDER): \
|
||||||
$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) \
|
$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) \
|
||||||
$(shell $(PKG_CONFIG) --libs gio-2.0)
|
$(shell $(PKG_CONFIG) --libs gio-2.0)
|
||||||
|
|
||||||
test: $(TEST_NODE) $(TEST_TREE_MODEL) $(TEST_TREE_BUILDER)
|
$(TEST_PROJECT): \
|
||||||
|
tests/test_investigation_project.c \
|
||||||
|
src/core/investigation_project.c
|
||||||
|
$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS)
|
||||||
|
|
||||||
|
test: \
|
||||||
|
$(TEST_NODE) \
|
||||||
|
$(TEST_TREE_MODEL) \
|
||||||
|
$(TEST_TREE_BUILDER) \
|
||||||
|
$(TEST_PROJECT)
|
||||||
@echo "Exécution des tests..."
|
@echo "Exécution des tests..."
|
||||||
@./$(TEST_NODE)
|
@./$(TEST_NODE)
|
||||||
@./$(TEST_TREE_MODEL)
|
@./$(TEST_TREE_MODEL)
|
||||||
@./$(TEST_TREE_BUILDER)
|
@./$(TEST_TREE_BUILDER)
|
||||||
|
@./$(TEST_PROJECT)
|
||||||
@echo "Tous les tests sont valides."
|
@echo "Tous les tests sont valides."
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
|
|
@ -74,6 +85,7 @@ clean:
|
||||||
rm -f $(OBJ) $(TARGET) \
|
rm -f $(OBJ) $(TARGET) \
|
||||||
$(TEST_NODE) \
|
$(TEST_NODE) \
|
||||||
$(TEST_TREE_MODEL) \
|
$(TEST_TREE_MODEL) \
|
||||||
$(TEST_TREE_BUILDER)
|
$(TEST_TREE_BUILDER) \
|
||||||
|
@./$(TEST_PROJECT)
|
||||||
|
|
||||||
.PHONY: clean run test
|
.PHONY: clean run test
|
||||||
|
|
|
||||||
257
docs/tickets/closed/TICKET-020.md
Normal file
257
docs/tickets/closed/TICKET-020.md
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
# Ticket #020
|
||||||
|
|
||||||
|
## Titre
|
||||||
|
|
||||||
|
Créer une nouvelle enquête.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Ajouter la capacité de créer automatiquement une nouvelle enquête dans un dossier choisi par l'utilisateur.
|
||||||
|
|
||||||
|
La création doit produire une arborescence standard et préparer l'emplacement de la future base SQLite.
|
||||||
|
|
||||||
|
Ce ticket ne crée pas encore le schéma SQL complet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```text
|
||||||
|
Application
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
InvestigationProject
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
FileSystem
|
||||||
|
```
|
||||||
|
|
||||||
|
Le module `InvestigationProject` devient le point d'entrée métier pour la création d'une enquête.
|
||||||
|
|
||||||
|
La GUI ne doit jamais créer directement les dossiers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Responsabilités
|
||||||
|
|
||||||
|
### InvestigationProject
|
||||||
|
|
||||||
|
Le module doit :
|
||||||
|
|
||||||
|
- recevoir le chemin du dossier parent ;
|
||||||
|
- recevoir le nom de la nouvelle enquête ;
|
||||||
|
- créer le dossier racine de l'enquête ;
|
||||||
|
- créer l'arborescence standard ;
|
||||||
|
- créer le dossier `00_BaseDeDonnees` ;
|
||||||
|
- créer un fichier SQLite vide nommé `Enquete.sqlite` ;
|
||||||
|
- nettoyer ce qui a été créé en cas d'échec partiel ;
|
||||||
|
- retourner le chemin complet de l'enquête créée.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Arborescence à créer
|
||||||
|
|
||||||
|
```text
|
||||||
|
NomEnquete/
|
||||||
|
├── 00_BaseDeDonnees/
|
||||||
|
│ └── Enquete.sqlite
|
||||||
|
├── 01_Preuves_Originales/
|
||||||
|
│ ├── Captures_Ecran/
|
||||||
|
│ ├── Conversations/
|
||||||
|
│ ├── Documents/
|
||||||
|
│ ├── Emails/
|
||||||
|
│ ├── Photos/
|
||||||
|
│ └── Videos/
|
||||||
|
├── 02_Preuves_Traitees/
|
||||||
|
│ ├── Annotations/
|
||||||
|
│ ├── Extractions/
|
||||||
|
│ ├── OCR/
|
||||||
|
│ └── Redactions/
|
||||||
|
├── 03_Chronologie/
|
||||||
|
├── 04_Entites/
|
||||||
|
│ ├── Adresses_Email/
|
||||||
|
│ ├── Comptes_Bancaires/
|
||||||
|
│ ├── Comptes_Facebook/
|
||||||
|
│ ├── Comptes_Instagram/
|
||||||
|
│ ├── Documents_Identite/
|
||||||
|
│ ├── IBAN/
|
||||||
|
│ ├── Personnes/
|
||||||
|
│ ├── Pseudonymes/
|
||||||
|
│ ├── Telephones/
|
||||||
|
│ └── Autres/
|
||||||
|
├── 05_Rapports/
|
||||||
|
├── 06_Exports/
|
||||||
|
├── 07_Notes/
|
||||||
|
├── 08_Sources/
|
||||||
|
└── 09_Hash/
|
||||||
|
```
|
||||||
|
|
||||||
|
Les noms de dossiers ne doivent pas contenir d'accents.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Interface publique attendue
|
||||||
|
|
||||||
|
Créer :
|
||||||
|
|
||||||
|
```text
|
||||||
|
include/core/investigation_project.h
|
||||||
|
src/core/investigation_project.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Avec :
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *investigation_project_create(
|
||||||
|
const char *parent_directory,
|
||||||
|
const char *investigation_name
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contrat de propriété
|
||||||
|
|
||||||
|
En cas de succès, la fonction retourne une nouvelle chaîne allouée contenant le chemin complet du dossier d'enquête.
|
||||||
|
|
||||||
|
Le code appelant devient propriétaire de cette chaîne et doit la libérer avec :
|
||||||
|
|
||||||
|
```c
|
||||||
|
g_free(investigation_path);
|
||||||
|
```
|
||||||
|
|
||||||
|
En cas d'échec, la fonction retourne :
|
||||||
|
|
||||||
|
```c
|
||||||
|
NULL
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Règles de validation
|
||||||
|
|
||||||
|
La fonction doit refuser :
|
||||||
|
|
||||||
|
- `parent_directory == NULL` ;
|
||||||
|
- un chemin parent vide ;
|
||||||
|
- `investigation_name == NULL` ;
|
||||||
|
- un nom vide ;
|
||||||
|
- un dossier parent inexistant ;
|
||||||
|
- un chemin parent qui n'est pas un dossier ;
|
||||||
|
- un dossier d'enquête qui existe déjà ;
|
||||||
|
- un nom contenant `/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gestion des erreurs
|
||||||
|
|
||||||
|
Si une étape échoue après la création partielle :
|
||||||
|
|
||||||
|
- tous les fichiers créés par la fonction doivent être supprimés ;
|
||||||
|
- tous les dossiers créés par la fonction doivent être supprimés ;
|
||||||
|
- aucun dossier partiel ne doit rester sur le disque ;
|
||||||
|
- la fonction retourne `NULL`.
|
||||||
|
|
||||||
|
La fonction ne doit jamais supprimer un dossier qui existait avant son appel.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Création de `Enquete.sqlite`
|
||||||
|
|
||||||
|
Pour ce ticket, le fichier doit seulement être créé.
|
||||||
|
|
||||||
|
Le schéma SQLite sera initialisé dans le ticket #022.
|
||||||
|
|
||||||
|
Le fichier attendu est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
00_BaseDeDonnees/Enquete.sqlite
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hors périmètre
|
||||||
|
|
||||||
|
Ce ticket ne doit pas :
|
||||||
|
|
||||||
|
- créer les tables SQLite ;
|
||||||
|
- générer un UUID ;
|
||||||
|
- créer les métadonnées ;
|
||||||
|
- importer une enquête existante ;
|
||||||
|
- modifier l'interface GTK ;
|
||||||
|
- ouvrir automatiquement l'enquête créée ;
|
||||||
|
- créer un rapport ;
|
||||||
|
- copier des preuves.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dépendances
|
||||||
|
|
||||||
|
- C17 ;
|
||||||
|
- GLib ;
|
||||||
|
- GIO autorisé.
|
||||||
|
|
||||||
|
Aucune dépendance GTK ou SQLite requise dans ce ticket.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contraintes techniques
|
||||||
|
|
||||||
|
- structure modulaire ;
|
||||||
|
- aucun état global ;
|
||||||
|
- aucune logique de création dans `Application` ;
|
||||||
|
- aucune logique de création dans les widgets ;
|
||||||
|
- documentation Doxygen ;
|
||||||
|
- compilation sans warning ;
|
||||||
|
- nettoyage complet en cas d'erreur ;
|
||||||
|
- noms de fonctions préfixés par `investigation_project_`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
Créer :
|
||||||
|
|
||||||
|
```text
|
||||||
|
tests/test_investigation_project.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Le test doit :
|
||||||
|
|
||||||
|
- créer un dossier temporaire ;
|
||||||
|
- créer une enquête valide ;
|
||||||
|
- vérifier chaque dossier attendu ;
|
||||||
|
- vérifier la présence de `Enquete.sqlite` ;
|
||||||
|
- vérifier que la fonction retourne le bon chemin ;
|
||||||
|
- vérifier le refus des paramètres `NULL` ;
|
||||||
|
- vérifier le refus des chaînes vides ;
|
||||||
|
- vérifier le refus d'un nom contenant `/` ;
|
||||||
|
- vérifier le refus si le dossier existe déjà ;
|
||||||
|
- supprimer complètement l'enquête de test ;
|
||||||
|
- vérifier qu'aucun résidu ne reste.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Critères d'acceptation
|
||||||
|
|
||||||
|
- [ ] Le projet compile sans warning.
|
||||||
|
- [ ] `make test` reste valide.
|
||||||
|
- [ ] Une enquête complète peut être créée.
|
||||||
|
- [ ] Tous les dossiers attendus existent.
|
||||||
|
- [ ] `Enquete.sqlite` existe.
|
||||||
|
- [ ] Aucun dossier partiel ne reste en cas d'échec.
|
||||||
|
- [ ] Un dossier existant n'est jamais écrasé.
|
||||||
|
- [ ] Le chemin retourné est correct.
|
||||||
|
- [ ] Aucune dépendance GTK.
|
||||||
|
- [ ] Aucun code SQLite métier.
|
||||||
|
- [ ] Le nouveau test est intégré à `make test`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit attendu
|
||||||
|
|
||||||
|
```text
|
||||||
|
feat(core): create investigation project structure
|
||||||
|
```
|
||||||
39
include/core/investigation_project.h
Normal file
39
include/core/investigation_project.h
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file investigation_project.h
|
||||||
|
* @brief Interface publique de gestion d'un projet d'enquête.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LABFY_INVESTIGATION_INVESTIGATION_PROJECT_H
|
||||||
|
#define LABFY_INVESTIGATION_INVESTIGATION_PROJECT_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Crée une nouvelle enquête dans un dossier parent.
|
||||||
|
*
|
||||||
|
* La fonction crée :
|
||||||
|
*
|
||||||
|
* - le dossier racine de l'enquête ;
|
||||||
|
* - l'arborescence standard ;
|
||||||
|
* - le fichier vide 00_BaseDeDonnees/Enquete.sqlite.
|
||||||
|
*
|
||||||
|
* Le dossier parent doit déjà exister.
|
||||||
|
*
|
||||||
|
* Le nom de l'enquête ne doit pas être vide et ne doit pas contenir
|
||||||
|
* de séparateur de chemin.
|
||||||
|
*
|
||||||
|
* En cas d'échec, les éléments créés pendant l'appel sont supprimés.
|
||||||
|
* Aucun dossier existant avant l'appel ne doit être supprimé.
|
||||||
|
*
|
||||||
|
* La chaîne retournée appartient au code appelant et doit être libérée
|
||||||
|
* avec g_free().
|
||||||
|
*
|
||||||
|
* @param parent_directory Chemin du dossier parent.
|
||||||
|
* @param investigation_name Nom de la nouvelle enquête.
|
||||||
|
*
|
||||||
|
* @return Le chemin complet de l'enquête créée, ou NULL en cas d'échec.
|
||||||
|
*/
|
||||||
|
char *investigation_project_create(
|
||||||
|
const char *parent_directory,
|
||||||
|
const char *investigation_name
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
Binary file not shown.
424
src/core/investigation_project.c
Normal file
424
src/core/investigation_project.c
Normal file
|
|
@ -0,0 +1,424 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file investigation_project.c
|
||||||
|
* @brief Création et gestion de la structure d'un projet d'enquête.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "core/investigation_project.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Liste des dossiers relatifs composant une enquête.
|
||||||
|
*
|
||||||
|
* L'ordre est important : les dossiers parents doivent apparaître avant
|
||||||
|
* leurs sous-dossiers.
|
||||||
|
*/
|
||||||
|
static const char *const investigation_project_directories[] =
|
||||||
|
{
|
||||||
|
"00_BaseDeDonnees",
|
||||||
|
|
||||||
|
"01_Preuves_Originales",
|
||||||
|
"01_Preuves_Originales/Captures_Ecran",
|
||||||
|
"01_Preuves_Originales/Conversations",
|
||||||
|
"01_Preuves_Originales/Documents",
|
||||||
|
"01_Preuves_Originales/Emails",
|
||||||
|
"01_Preuves_Originales/Photos",
|
||||||
|
"01_Preuves_Originales/Videos",
|
||||||
|
|
||||||
|
"02_Preuves_Traitees",
|
||||||
|
"02_Preuves_Traitees/Annotations",
|
||||||
|
"02_Preuves_Traitees/Extractions",
|
||||||
|
"02_Preuves_Traitees/OCR",
|
||||||
|
"02_Preuves_Traitees/Redactions",
|
||||||
|
|
||||||
|
"03_Chronologie",
|
||||||
|
|
||||||
|
"04_Entites",
|
||||||
|
"04_Entites/Adresses_Email",
|
||||||
|
"04_Entites/Comptes_Bancaires",
|
||||||
|
"04_Entites/Comptes_Facebook",
|
||||||
|
"04_Entites/Comptes_Instagram",
|
||||||
|
"04_Entites/Documents_Identite",
|
||||||
|
"04_Entites/IBAN",
|
||||||
|
"04_Entites/Personnes",
|
||||||
|
"04_Entites/Pseudonymes",
|
||||||
|
"04_Entites/Telephones",
|
||||||
|
"04_Entites/Autres",
|
||||||
|
|
||||||
|
"05_Rapports",
|
||||||
|
"06_Exports",
|
||||||
|
"07_Notes",
|
||||||
|
"08_Sources",
|
||||||
|
"09_Hash"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Nombre de dossiers présents dans la table de création.
|
||||||
|
*/
|
||||||
|
#define INVESTIGATION_PROJECT_DIRECTORY_COUNT \
|
||||||
|
G_N_ELEMENTS(investigation_project_directories)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie que les paramètres nécessaires à la création sont valides.
|
||||||
|
*
|
||||||
|
* @param parent_directory Dossier dans lequel créer l'enquête.
|
||||||
|
* @param investigation_name Nom de la nouvelle enquête.
|
||||||
|
*
|
||||||
|
* @return TRUE si les paramètres sont valides, sinon FALSE.
|
||||||
|
*/
|
||||||
|
static gboolean investigation_project_validate_create_parameters(
|
||||||
|
const char *parent_directory,
|
||||||
|
const char *investigation_name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (parent_directory == NULL ||
|
||||||
|
parent_directory[0] == '\0')
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (investigation_name == NULL ||
|
||||||
|
investigation_name[0] == '\0')
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le nom doit représenter un seul composant de chemin.
|
||||||
|
*
|
||||||
|
* On refuse par exemple :
|
||||||
|
*
|
||||||
|
* Enquetes/Test
|
||||||
|
*/
|
||||||
|
if (strchr(investigation_name, G_DIR_SEPARATOR) != NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_file_test(
|
||||||
|
parent_directory,
|
||||||
|
G_FILE_TEST_EXISTS
|
||||||
|
))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_file_test(
|
||||||
|
parent_directory,
|
||||||
|
G_FILE_TEST_IS_DIR
|
||||||
|
))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Supprime les fichiers et dossiers créés pendant une tentative.
|
||||||
|
*
|
||||||
|
* Les chemins sont parcourus dans l'ordre inverse afin de supprimer :
|
||||||
|
*
|
||||||
|
* 1. les fichiers ;
|
||||||
|
* 2. les sous-dossiers ;
|
||||||
|
* 3. le dossier racine.
|
||||||
|
*
|
||||||
|
* Cette fonction ne reçoit que des chemins créés par le module pendant
|
||||||
|
* l'appel courant.
|
||||||
|
*
|
||||||
|
* @param created_paths Tableau contenant les chemins créés.
|
||||||
|
*/
|
||||||
|
static void investigation_project_cleanup_created_paths(
|
||||||
|
GPtrArray *created_paths
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (created_paths == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (gsize index = created_paths->len; index > 0; --index)
|
||||||
|
{
|
||||||
|
const char *path = NULL;
|
||||||
|
|
||||||
|
path = g_ptr_array_index(
|
||||||
|
created_paths,
|
||||||
|
index - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_file_test(path, G_FILE_TEST_IS_DIR))
|
||||||
|
{
|
||||||
|
if (g_rmdir(path) != 0)
|
||||||
|
{
|
||||||
|
g_warning(
|
||||||
|
"Impossible de supprimer le dossier temporaire '%s' : %s",
|
||||||
|
path,
|
||||||
|
g_strerror(errno)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_file_test(path, G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
if (g_remove(path) != 0)
|
||||||
|
{
|
||||||
|
g_warning(
|
||||||
|
"Impossible de supprimer le fichier temporaire '%s' : %s",
|
||||||
|
path,
|
||||||
|
g_strerror(errno)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Crée un dossier et mémorise son chemin pour un éventuel nettoyage.
|
||||||
|
*
|
||||||
|
* La fonction prend possession de directory_path uniquement si la création
|
||||||
|
* réussit et que le chemin est ajouté au tableau.
|
||||||
|
*
|
||||||
|
* @param directory_path Chemin alloué du dossier à créer.
|
||||||
|
* @param created_paths Tableau des éléments créés.
|
||||||
|
*
|
||||||
|
* @return TRUE si le dossier a été créé, sinon FALSE.
|
||||||
|
*/
|
||||||
|
static gboolean investigation_project_create_directory(
|
||||||
|
char *directory_path,
|
||||||
|
GPtrArray *created_paths
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (directory_path == NULL || created_paths == NULL)
|
||||||
|
{
|
||||||
|
g_free(directory_path);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_mkdir(directory_path, 0700) != 0)
|
||||||
|
{
|
||||||
|
g_warning(
|
||||||
|
"Impossible de créer le dossier '%s' : %s",
|
||||||
|
directory_path,
|
||||||
|
g_strerror(errno)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(directory_path);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le tableau devient propriétaire de directory_path.
|
||||||
|
*/
|
||||||
|
g_ptr_array_add(
|
||||||
|
created_paths,
|
||||||
|
directory_path
|
||||||
|
);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *investigation_project_create(
|
||||||
|
const char *parent_directory,
|
||||||
|
const char *investigation_name
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char *investigation_path = NULL;
|
||||||
|
char *directory_path = NULL;
|
||||||
|
char *database_path = NULL;
|
||||||
|
|
||||||
|
GPtrArray *created_paths = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!investigation_project_validate_create_parameters(
|
||||||
|
parent_directory,
|
||||||
|
investigation_name
|
||||||
|
))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
investigation_path = g_build_filename(
|
||||||
|
parent_directory,
|
||||||
|
investigation_name,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (investigation_path == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Une enquête existante ne doit jamais être écrasée.
|
||||||
|
*/
|
||||||
|
if (g_file_test(
|
||||||
|
investigation_path,
|
||||||
|
G_FILE_TEST_EXISTS
|
||||||
|
))
|
||||||
|
{
|
||||||
|
g_free(investigation_path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le tableau conserve tous les chemins créés.
|
||||||
|
*
|
||||||
|
* Ses chaînes seront libérées automatiquement par g_ptr_array_free().
|
||||||
|
*/
|
||||||
|
created_paths = g_ptr_array_new_with_free_func(
|
||||||
|
g_free
|
||||||
|
);
|
||||||
|
|
||||||
|
if (created_paths == NULL)
|
||||||
|
{
|
||||||
|
g_free(investigation_path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On crée d'abord le dossier racine.
|
||||||
|
*
|
||||||
|
* Une copie est placée dans created_paths, car investigation_path
|
||||||
|
* doit être retourné au code appelant en cas de succès.
|
||||||
|
*/
|
||||||
|
directory_path = g_strdup(investigation_path);
|
||||||
|
|
||||||
|
if (!investigation_project_create_directory(
|
||||||
|
directory_path,
|
||||||
|
created_paths
|
||||||
|
))
|
||||||
|
{
|
||||||
|
g_ptr_array_free(created_paths, TRUE);
|
||||||
|
g_free(investigation_path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Création de toute l'arborescence déclarée dans la table.
|
||||||
|
*/
|
||||||
|
for (gsize index = 0;
|
||||||
|
index < INVESTIGATION_PROJECT_DIRECTORY_COUNT;
|
||||||
|
++index)
|
||||||
|
{
|
||||||
|
directory_path = g_build_filename(
|
||||||
|
investigation_path,
|
||||||
|
investigation_project_directories[index],
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!investigation_project_create_directory(
|
||||||
|
directory_path,
|
||||||
|
created_paths
|
||||||
|
))
|
||||||
|
{
|
||||||
|
investigation_project_cleanup_created_paths(
|
||||||
|
created_paths
|
||||||
|
);
|
||||||
|
|
||||||
|
g_ptr_array_free(
|
||||||
|
created_paths,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(investigation_path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
database_path = g_build_filename(
|
||||||
|
investigation_path,
|
||||||
|
"00_BaseDeDonnees",
|
||||||
|
"Enquete.sqlite",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (database_path == NULL)
|
||||||
|
{
|
||||||
|
investigation_project_cleanup_created_paths(
|
||||||
|
created_paths
|
||||||
|
);
|
||||||
|
|
||||||
|
g_ptr_array_free(
|
||||||
|
created_paths,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(investigation_path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pour ce ticket, on crée seulement un fichier vide.
|
||||||
|
*
|
||||||
|
* Le schéma SQLite sera ajouté dans un prochain ticket.
|
||||||
|
*/
|
||||||
|
if (!g_file_set_contents(
|
||||||
|
database_path,
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
&error
|
||||||
|
))
|
||||||
|
{
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_warning(
|
||||||
|
"Impossible de créer '%s' : %s",
|
||||||
|
database_path,
|
||||||
|
error->message
|
||||||
|
);
|
||||||
|
|
||||||
|
g_clear_error(&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(database_path);
|
||||||
|
|
||||||
|
investigation_project_cleanup_created_paths(
|
||||||
|
created_paths
|
||||||
|
);
|
||||||
|
|
||||||
|
g_ptr_array_free(
|
||||||
|
created_paths,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(investigation_path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le fichier doit également être supprimé avant ses dossiers
|
||||||
|
* si une évolution future ajoute une étape pouvant encore échouer.
|
||||||
|
*
|
||||||
|
* Le tableau devient propriétaire de database_path.
|
||||||
|
*/
|
||||||
|
g_ptr_array_add(
|
||||||
|
created_paths,
|
||||||
|
database_path
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tout est créé avec succès.
|
||||||
|
*
|
||||||
|
* On libère seulement le tableau et ses copies de chemins.
|
||||||
|
* Les fichiers et dossiers restent sur le disque.
|
||||||
|
*/
|
||||||
|
g_ptr_array_free(
|
||||||
|
created_paths,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
|
|
||||||
|
return investigation_path;
|
||||||
|
}
|
||||||
BIN
tests/test_investigation_node
Executable file
BIN
tests/test_investigation_node
Executable file
Binary file not shown.
BIN
tests/test_investigation_project
Executable file
BIN
tests/test_investigation_project
Executable file
Binary file not shown.
463
tests/test_investigation_project.c
Normal file
463
tests/test_investigation_project.c
Normal file
|
|
@ -0,0 +1,463 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file test_investigation_project.c
|
||||||
|
* @brief Tests d'intégration du module InvestigationProject.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "core/investigation_project.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Liste des dossiers attendus dans une enquête.
|
||||||
|
*
|
||||||
|
* Cette liste doit rester cohérente avec la structure créée par
|
||||||
|
* investigation_project_create().
|
||||||
|
*/
|
||||||
|
static const char *const expected_directories[] =
|
||||||
|
{
|
||||||
|
"00_BaseDeDonnees",
|
||||||
|
|
||||||
|
"01_Preuves_Originales",
|
||||||
|
"01_Preuves_Originales/Captures_Ecran",
|
||||||
|
"01_Preuves_Originales/Conversations",
|
||||||
|
"01_Preuves_Originales/Documents",
|
||||||
|
"01_Preuves_Originales/Emails",
|
||||||
|
"01_Preuves_Originales/Photos",
|
||||||
|
"01_Preuves_Originales/Videos",
|
||||||
|
|
||||||
|
"02_Preuves_Traitees",
|
||||||
|
"02_Preuves_Traitees/Annotations",
|
||||||
|
"02_Preuves_Traitees/Extractions",
|
||||||
|
"02_Preuves_Traitees/OCR",
|
||||||
|
"02_Preuves_Traitees/Redactions",
|
||||||
|
|
||||||
|
"03_Chronologie",
|
||||||
|
|
||||||
|
"04_Entites",
|
||||||
|
"04_Entites/Adresses_Email",
|
||||||
|
"04_Entites/Comptes_Bancaires",
|
||||||
|
"04_Entites/Comptes_Facebook",
|
||||||
|
"04_Entites/Comptes_Instagram",
|
||||||
|
"04_Entites/Documents_Identite",
|
||||||
|
"04_Entites/IBAN",
|
||||||
|
"04_Entites/Personnes",
|
||||||
|
"04_Entites/Pseudonymes",
|
||||||
|
"04_Entites/Telephones",
|
||||||
|
"04_Entites/Autres",
|
||||||
|
|
||||||
|
"05_Rapports",
|
||||||
|
"06_Exports",
|
||||||
|
"07_Notes",
|
||||||
|
"08_Sources",
|
||||||
|
"09_Hash"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EXPECTED_DIRECTORY_COUNT \
|
||||||
|
G_N_ELEMENTS(expected_directories)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Supprime récursivement un fichier ou un dossier de test.
|
||||||
|
*
|
||||||
|
* Cette fonction est réservée au nettoyage des répertoires temporaires créés
|
||||||
|
* par les tests.
|
||||||
|
*
|
||||||
|
* @param path Chemin à supprimer.
|
||||||
|
*
|
||||||
|
* @return TRUE si le chemin a été supprimé ou n'existait pas, sinon FALSE.
|
||||||
|
*/
|
||||||
|
static gboolean test_remove_path_recursively(
|
||||||
|
const char *path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GDir *directory = NULL;
|
||||||
|
const char *entry_name = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_file_test(path, G_FILE_TEST_EXISTS))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_file_test(path, G_FILE_TEST_IS_DIR))
|
||||||
|
{
|
||||||
|
return g_remove(path) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
directory = g_dir_open(
|
||||||
|
path,
|
||||||
|
0,
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
if (directory == NULL)
|
||||||
|
{
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_printerr(
|
||||||
|
"Impossible d'ouvrir '%s' pendant le nettoyage : %s\n",
|
||||||
|
path,
|
||||||
|
error->message
|
||||||
|
);
|
||||||
|
|
||||||
|
g_clear_error(&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((entry_name = g_dir_read_name(directory)) != NULL)
|
||||||
|
{
|
||||||
|
char *entry_path = NULL;
|
||||||
|
gboolean removal_success = FALSE;
|
||||||
|
|
||||||
|
entry_path = g_build_filename(
|
||||||
|
path,
|
||||||
|
entry_name,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(entry_path != NULL);
|
||||||
|
|
||||||
|
removal_success = test_remove_path_recursively(
|
||||||
|
entry_path
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(entry_path);
|
||||||
|
|
||||||
|
if (!removal_success)
|
||||||
|
{
|
||||||
|
g_dir_close(directory);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dir_close(directory);
|
||||||
|
|
||||||
|
return g_rmdir(path) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie qu'un chemin désigne un dossier existant.
|
||||||
|
*/
|
||||||
|
static void test_assert_directory_exists(
|
||||||
|
const char *root_path,
|
||||||
|
const char *relative_path
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char *directory_path = NULL;
|
||||||
|
|
||||||
|
assert(root_path != NULL);
|
||||||
|
assert(relative_path != NULL);
|
||||||
|
|
||||||
|
directory_path = g_build_filename(
|
||||||
|
root_path,
|
||||||
|
relative_path,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(directory_path != NULL);
|
||||||
|
assert(
|
||||||
|
g_file_test(
|
||||||
|
directory_path,
|
||||||
|
G_FILE_TEST_IS_DIR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(directory_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie la création complète d'une enquête.
|
||||||
|
*/
|
||||||
|
static void test_create_valid_investigation(void)
|
||||||
|
{
|
||||||
|
char *temporary_parent = NULL;
|
||||||
|
char *investigation_path = NULL;
|
||||||
|
char *expected_path = NULL;
|
||||||
|
char *database_path = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
temporary_parent = g_dir_make_tmp(
|
||||||
|
"labfy-investigation-project-test-XXXXXX",
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(temporary_parent != NULL);
|
||||||
|
assert(error == NULL);
|
||||||
|
|
||||||
|
investigation_path = investigation_project_create(
|
||||||
|
temporary_parent,
|
||||||
|
"Enquete_Test"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(investigation_path != NULL);
|
||||||
|
|
||||||
|
expected_path = g_build_filename(
|
||||||
|
temporary_parent,
|
||||||
|
"Enquete_Test",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(expected_path != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le chemin retourné doit être exactement celui de la nouvelle enquête.
|
||||||
|
*/
|
||||||
|
assert(strcmp(investigation_path, expected_path) == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Le dossier racine doit exister.
|
||||||
|
*/
|
||||||
|
assert(
|
||||||
|
g_file_test(
|
||||||
|
investigation_path,
|
||||||
|
G_FILE_TEST_IS_DIR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vérification de tous les dossiers attendus.
|
||||||
|
*/
|
||||||
|
for (gsize index = 0;
|
||||||
|
index < EXPECTED_DIRECTORY_COUNT;
|
||||||
|
++index)
|
||||||
|
{
|
||||||
|
test_assert_directory_exists(
|
||||||
|
investigation_path,
|
||||||
|
expected_directories[index]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
database_path = g_build_filename(
|
||||||
|
investigation_path,
|
||||||
|
"00_BaseDeDonnees",
|
||||||
|
"Enquete.sqlite",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(database_path != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enquete.sqlite doit exister et être un fichier régulier.
|
||||||
|
*/
|
||||||
|
assert(
|
||||||
|
g_file_test(
|
||||||
|
database_path,
|
||||||
|
G_FILE_TEST_EXISTS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
g_file_test(
|
||||||
|
database_path,
|
||||||
|
G_FILE_TEST_IS_REGULAR
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Une deuxième création au même endroit doit être refusée.
|
||||||
|
*/
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
temporary_parent,
|
||||||
|
"Enquete_Test"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nettoyage complet.
|
||||||
|
*/
|
||||||
|
assert(
|
||||||
|
test_remove_path_recursively(
|
||||||
|
temporary_parent
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!g_file_test(
|
||||||
|
temporary_parent,
|
||||||
|
G_FILE_TEST_EXISTS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(database_path);
|
||||||
|
g_free(expected_path);
|
||||||
|
g_free(investigation_path);
|
||||||
|
g_free(temporary_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie les paramètres NULL et les chaînes vides.
|
||||||
|
*/
|
||||||
|
static void test_invalid_parameters(void)
|
||||||
|
{
|
||||||
|
char *temporary_parent = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
temporary_parent = g_dir_make_tmp(
|
||||||
|
"labfy-investigation-invalid-test-XXXXXX",
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(temporary_parent != NULL);
|
||||||
|
assert(error == NULL);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
NULL,
|
||||||
|
"Enquete"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
"",
|
||||||
|
"Enquete"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
temporary_parent,
|
||||||
|
NULL
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
temporary_parent,
|
||||||
|
""
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
test_remove_path_recursively(
|
||||||
|
temporary_parent
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(temporary_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie le refus d'un nom contenant un séparateur de chemin.
|
||||||
|
*/
|
||||||
|
static void test_invalid_investigation_name(void)
|
||||||
|
{
|
||||||
|
char *temporary_parent = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
temporary_parent = g_dir_make_tmp(
|
||||||
|
"labfy-investigation-name-test-XXXXXX",
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(temporary_parent != NULL);
|
||||||
|
assert(error == NULL);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
temporary_parent,
|
||||||
|
"Enquetes/Test"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
test_remove_path_recursively(
|
||||||
|
temporary_parent
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(temporary_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie le refus d'un dossier parent inexistant.
|
||||||
|
*/
|
||||||
|
static void test_missing_parent_directory(void)
|
||||||
|
{
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
"/tmp/labfy-parent-directory-that-does-not-exist",
|
||||||
|
"Enquete"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vérifie le refus d'un chemin parent représentant un fichier.
|
||||||
|
*/
|
||||||
|
static void test_parent_is_file(void)
|
||||||
|
{
|
||||||
|
char *temporary_directory = NULL;
|
||||||
|
char *temporary_file = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
temporary_directory = g_dir_make_tmp(
|
||||||
|
"labfy-investigation-parent-file-test-XXXXXX",
|
||||||
|
&error
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(temporary_directory != NULL);
|
||||||
|
assert(error == NULL);
|
||||||
|
|
||||||
|
temporary_file = g_build_filename(
|
||||||
|
temporary_directory,
|
||||||
|
"parent.txt",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(temporary_file != NULL);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
g_file_set_contents(
|
||||||
|
temporary_file,
|
||||||
|
"test\n",
|
||||||
|
-1,
|
||||||
|
&error
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(error == NULL);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
investigation_project_create(
|
||||||
|
temporary_file,
|
||||||
|
"Enquete"
|
||||||
|
) == NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
test_remove_path_recursively(
|
||||||
|
temporary_directory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
g_free(temporary_file);
|
||||||
|
g_free(temporary_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_create_valid_investigation();
|
||||||
|
test_invalid_parameters();
|
||||||
|
test_invalid_investigation_name();
|
||||||
|
test_missing_parent_directory();
|
||||||
|
test_parent_is_file();
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"InvestigationProject : tous les tests sont valides.\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
tests/test_investigation_tree_builder
Executable file
BIN
tests/test_investigation_tree_builder
Executable file
Binary file not shown.
BIN
tests/test_investigation_tree_model
Executable file
BIN
tests/test_investigation_tree_model
Executable file
Binary file not shown.
Loading…
Reference in a new issue