feat(osint): add compatible action catalog
This commit is contained in:
parent
bc70257e0a
commit
947f9550dc
6 changed files with 438 additions and 6 deletions
16
Makefile
16
Makefile
|
|
@ -114,6 +114,7 @@ TEST_INVESTIGATION_GRAPH_LOADER := tests/test_investigation_graph_loader
|
|||
TEST_INVESTIGATION_GRAPH_LOAD_TASK := tests/test_investigation_graph_load_task
|
||||
TEST_GRAPH_NODE_POSITION_DAO := tests/test_graph_node_position_dao
|
||||
TEST_OSINT_SELECTION_CONTEXT := tests/test_osint_selection_context
|
||||
TEST_OSINT_ACTION_CATALOG := tests/test_osint_action_catalog
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
|
|
@ -536,6 +537,14 @@ $(TEST_OSINT_SELECTION_CONTEXT): \
|
|||
src/models/relation_record.c
|
||||
$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS)
|
||||
|
||||
$(TEST_OSINT_ACTION_CATALOG): \
|
||||
tests/test_osint_action_catalog.c \
|
||||
src/models/osint_action_catalog.c \
|
||||
src/models/osint_selection_context.c \
|
||||
src/models/entity_record.c \
|
||||
src/models/relation_record.c
|
||||
$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS)
|
||||
|
||||
$(TEST_INVESTIGATION_GRAPH_LOAD_TASK): \
|
||||
tests/test_investigation_graph_load_task.c \
|
||||
src/core/investigation_graph_load_task.c \
|
||||
|
|
@ -604,7 +613,8 @@ test: \
|
|||
$(TEST_INVESTIGATION_GRAPH_LOADER) \
|
||||
$(TEST_INVESTIGATION_GRAPH_LOAD_TASK) \
|
||||
$(TEST_GRAPH_NODE_POSITION_DAO) \
|
||||
$(TEST_OSINT_SELECTION_CONTEXT)
|
||||
$(TEST_OSINT_SELECTION_CONTEXT) \
|
||||
$(TEST_OSINT_ACTION_CATALOG)
|
||||
@echo "Exécution des tests..."
|
||||
@./$(TEST_NODE)
|
||||
@./$(TEST_TREE_MODEL)
|
||||
|
|
@ -653,6 +663,7 @@ test: \
|
|||
@$(TEST_INVESTIGATION_GRAPH_LOAD_TASK)
|
||||
@$(TEST_GRAPH_NODE_POSITION_DAO)
|
||||
@$(TEST_OSINT_SELECTION_CONTEXT)
|
||||
@$(TEST_OSINT_ACTION_CATALOG)
|
||||
@echo "Tous les tests sont valides."
|
||||
|
||||
%.o: %.c
|
||||
|
|
@ -707,7 +718,8 @@ clean:
|
|||
$(TEST_INVESTIGATION_GRAPH_LOADER) \
|
||||
$(TEST_INVESTIGATION_GRAPH_LOAD_TASK) \
|
||||
$(TEST_GRAPH_NODE_POSITION_DAO) \
|
||||
$(TEST_OSINT_SELECTION_CONTEXT)
|
||||
$(TEST_OSINT_SELECTION_CONTEXT) \
|
||||
$(TEST_OSINT_ACTION_CATALOG)
|
||||
|
||||
-include $(DEP)
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ Le socle actuel comprend notamment :
|
|||
- catalogue initial d’outils ;
|
||||
- détection de présence et de version ;
|
||||
- menu OSINT contextuel préparé pour les entités et relations du graphe ;
|
||||
- contexte de sélection OSINT indépendant de GTK et validé par des tests.
|
||||
- contexte de sélection OSINT indépendant de GTK et validé par des tests ;
|
||||
- catalogue déterministe des actions compatibles avec la sélection OSINT.
|
||||
|
||||
Les outils actuellement présents dans le catalogue initial sont :
|
||||
|
||||
|
|
|
|||
73
include/models/osint_action_catalog.h
Normal file
73
include/models/osint_action_catalog.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/******************************************************************************
|
||||
* @file osint_action_catalog.h
|
||||
* @brief Catalogue des actions compatibles avec une sélection OSINT.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LABFY_INVESTIGATION_OSINT_ACTION_CATALOG_H
|
||||
#define LABFY_INVESTIGATION_OSINT_ACTION_CATALOG_H
|
||||
|
||||
#include "models/osint_selection_context.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/** @brief Description opaque d'une action OSINT. */
|
||||
typedef struct OsintAction OsintAction;
|
||||
|
||||
/** @brief Catalogue opaque possédant ses actions. */
|
||||
typedef struct OsintActionCatalog OsintActionCatalog;
|
||||
|
||||
/**
|
||||
* @brief Crée le catalogue initial déterministe.
|
||||
*
|
||||
* @return Nouveau catalogue, ou NULL en cas d'échec.
|
||||
*/
|
||||
OsintActionCatalog *osint_action_catalog_new_defaults(void);
|
||||
|
||||
/**
|
||||
* @brief Libère un catalogue et toutes ses actions.
|
||||
*
|
||||
* @param catalog Catalogue à libérer, ou NULL.
|
||||
*/
|
||||
void osint_action_catalog_free(OsintActionCatalog *catalog);
|
||||
|
||||
/**
|
||||
* @brief Liste les actions compatibles avec un contexte.
|
||||
*
|
||||
* Le tableau appartient à l'appelant. Ses actions sont empruntées au catalogue
|
||||
* et triées par libellé croissant.
|
||||
*
|
||||
* @param catalog Catalogue à consulter.
|
||||
* @param context Contexte de sélection à comparer.
|
||||
*
|
||||
* @return Nouveau tableau, éventuellement vide, ou NULL si un argument est invalide.
|
||||
*/
|
||||
GPtrArray *osint_action_catalog_list_compatible(
|
||||
const OsintActionCatalog *catalog,
|
||||
const OsintSelectionContext *context
|
||||
);
|
||||
|
||||
/** @brief Retourne l'identifiant stable emprunté d'une action. */
|
||||
const char *osint_action_get_identifier(const OsintAction *action);
|
||||
|
||||
/** @brief Retourne le libellé emprunté d'une action. */
|
||||
const char *osint_action_get_label(const OsintAction *action);
|
||||
|
||||
/** @brief Retourne la description empruntée d'une action. */
|
||||
const char *osint_action_get_description(const OsintAction *action);
|
||||
|
||||
/** @brief Retourne l'identifiant de l'outil externe requis, ou NULL. */
|
||||
const char *osint_action_get_required_tool_identifier(
|
||||
const OsintAction *action
|
||||
);
|
||||
|
||||
/** @brief Indique si l'action peut actuellement être déclenchée. */
|
||||
gboolean osint_action_is_available(const OsintAction *action);
|
||||
|
||||
/** @brief Retourne l'explication d'indisponibilité, ou NULL. */
|
||||
const char *osint_action_get_unavailable_reason(const OsintAction *action);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
155
src/models/osint_action_catalog.c
Normal file
155
src/models/osint_action_catalog.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/******************************************************************************
|
||||
* @file osint_action_catalog.c
|
||||
* @brief Implémentation du catalogue des actions OSINT.
|
||||
******************************************************************************/
|
||||
|
||||
#include "models/osint_action_catalog.h"
|
||||
|
||||
struct OsintAction
|
||||
{
|
||||
char *identifier;
|
||||
char *label;
|
||||
char *description;
|
||||
OsintSelectionContextKind target_kind;
|
||||
char *compatible_type;
|
||||
char *required_tool_identifier;
|
||||
gboolean available;
|
||||
char *unavailable_reason;
|
||||
};
|
||||
|
||||
struct OsintActionCatalog
|
||||
{
|
||||
GPtrArray *actions;
|
||||
};
|
||||
|
||||
/** @brief Libère une action possédée par le catalogue. */
|
||||
static void osint_action_free(gpointer data)
|
||||
{
|
||||
OsintAction *action = data;
|
||||
if (action == NULL) return;
|
||||
g_free(action->unavailable_reason);
|
||||
g_free(action->compatible_type);
|
||||
g_free(action->required_tool_identifier);
|
||||
g_free(action->description);
|
||||
g_free(action->label);
|
||||
g_free(action->identifier);
|
||||
g_free(action);
|
||||
}
|
||||
|
||||
/** @brief Crée une action en copiant toutes ses chaînes. */
|
||||
static OsintAction *osint_action_new(
|
||||
const char *identifier,
|
||||
const char *label,
|
||||
const char *description,
|
||||
OsintSelectionContextKind target_kind,
|
||||
const char *compatible_type,
|
||||
const char *required_tool_identifier,
|
||||
gboolean available,
|
||||
const char *unavailable_reason
|
||||
)
|
||||
{
|
||||
OsintAction *action = g_try_new0(OsintAction, 1);
|
||||
if (action == NULL) return NULL;
|
||||
action->identifier = g_strdup(identifier);
|
||||
action->label = g_strdup(label);
|
||||
action->description = g_strdup(description);
|
||||
action->target_kind = target_kind;
|
||||
action->compatible_type = g_strdup(compatible_type);
|
||||
action->required_tool_identifier = g_strdup(required_tool_identifier);
|
||||
action->available = available;
|
||||
action->unavailable_reason = g_strdup(unavailable_reason);
|
||||
if (action->identifier == NULL || action->label == NULL ||
|
||||
action->description == NULL ||
|
||||
(!available && action->unavailable_reason == NULL))
|
||||
{
|
||||
osint_action_free(action);
|
||||
return NULL;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
OsintActionCatalog *osint_action_catalog_new_defaults(void)
|
||||
{
|
||||
OsintActionCatalog *catalog = g_try_new0(OsintActionCatalog, 1);
|
||||
OsintAction *demonstration_action = NULL;
|
||||
OsintAction *dns_action = NULL;
|
||||
if (catalog == NULL) return NULL;
|
||||
catalog->actions = g_ptr_array_new_with_free_func(osint_action_free);
|
||||
demonstration_action = osint_action_new(
|
||||
"selection-preview", "Aperçu de la sélection",
|
||||
"Action locale de démonstration sans exécution externe.",
|
||||
OSINT_SELECTION_CONTEXT_KIND_UNKNOWN, NULL, NULL, TRUE, NULL
|
||||
);
|
||||
dns_action = osint_action_new(
|
||||
"dns-preview", "Résolution DNS",
|
||||
"Préfiguration de l'adaptateur DNS.",
|
||||
OSINT_SELECTION_CONTEXT_KIND_ENTITY, "domain", "dig", FALSE,
|
||||
"L'adaptateur DNS n'est pas encore intégré."
|
||||
);
|
||||
if (catalog->actions == NULL || demonstration_action == NULL ||
|
||||
dns_action == NULL)
|
||||
{
|
||||
osint_action_free(demonstration_action);
|
||||
osint_action_free(dns_action);
|
||||
osint_action_catalog_free(catalog);
|
||||
return NULL;
|
||||
}
|
||||
g_ptr_array_add(catalog->actions, demonstration_action);
|
||||
g_ptr_array_add(catalog->actions, dns_action);
|
||||
return catalog;
|
||||
}
|
||||
|
||||
/** @brief Compare deux actions par libellé. */
|
||||
static gint osint_action_compare(gconstpointer first, gconstpointer second)
|
||||
{
|
||||
const OsintAction *const *a = first;
|
||||
const OsintAction *const *b = second;
|
||||
return g_strcmp0((*a)->label, (*b)->label);
|
||||
}
|
||||
|
||||
GPtrArray *osint_action_catalog_list_compatible(
|
||||
const OsintActionCatalog *catalog,
|
||||
const OsintSelectionContext *context
|
||||
)
|
||||
{
|
||||
GPtrArray *compatible_actions = NULL;
|
||||
guint index = 0;
|
||||
if (catalog == NULL || context == NULL || catalog->actions == NULL)
|
||||
return NULL;
|
||||
compatible_actions = g_ptr_array_new();
|
||||
if (compatible_actions == NULL) return NULL;
|
||||
for (index = 0; index < catalog->actions->len; index++)
|
||||
{
|
||||
OsintAction *action = g_ptr_array_index(catalog->actions, index);
|
||||
gboolean kind_matches = action->target_kind ==
|
||||
OSINT_SELECTION_CONTEXT_KIND_UNKNOWN ||
|
||||
action->target_kind == osint_selection_context_get_kind(context);
|
||||
gboolean type_matches = action->compatible_type == NULL ||
|
||||
g_strcmp0(action->compatible_type,
|
||||
osint_selection_context_get_type(context)) == 0;
|
||||
if (kind_matches && type_matches)
|
||||
g_ptr_array_add(compatible_actions, action);
|
||||
}
|
||||
g_ptr_array_sort(compatible_actions, osint_action_compare);
|
||||
return compatible_actions;
|
||||
}
|
||||
|
||||
void osint_action_catalog_free(OsintActionCatalog *catalog)
|
||||
{
|
||||
if (catalog == NULL) return;
|
||||
g_clear_pointer(&catalog->actions, g_ptr_array_unref);
|
||||
g_free(catalog);
|
||||
}
|
||||
|
||||
const char *osint_action_get_identifier(const OsintAction *action)
|
||||
{ return action != NULL ? action->identifier : NULL; }
|
||||
const char *osint_action_get_label(const OsintAction *action)
|
||||
{ return action != NULL ? action->label : NULL; }
|
||||
const char *osint_action_get_description(const OsintAction *action)
|
||||
{ return action != NULL ? action->description : NULL; }
|
||||
const char *osint_action_get_required_tool_identifier(const OsintAction *action)
|
||||
{ return action != NULL ? action->required_tool_identifier : NULL; }
|
||||
gboolean osint_action_is_available(const OsintAction *action)
|
||||
{ return action != NULL && action->available; }
|
||||
const char *osint_action_get_unavailable_reason(const OsintAction *action)
|
||||
{ return action != NULL ? action->unavailable_reason : NULL; }
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include "models/entity_record.h"
|
||||
#include "models/investigation_graph_model.h"
|
||||
#include "models/osint_selection_context.h"
|
||||
#include "models/osint_action_catalog.h"
|
||||
#include "models/relation_record.h"
|
||||
#include "widgets/entity_details_panel.h"
|
||||
#include "widgets/investigation_graph_view.h"
|
||||
|
|
@ -57,6 +58,7 @@ struct Workspace
|
|||
GtkWidget *osint_tools_popover;
|
||||
GtkWidget *osint_tools_context_label;
|
||||
GtkWidget *osint_tools_status_label;
|
||||
GtkWidget *osint_tools_actions_box;
|
||||
GtkWidget *graph_help_button;
|
||||
GtkWidget *graph_help_popover;
|
||||
|
||||
|
|
@ -120,10 +122,42 @@ struct Workspace
|
|||
const InvestigationGraphLayout *graph_layout;
|
||||
|
||||
OsintSelectionContext *osint_selection_context;
|
||||
OsintActionCatalog *osint_action_catalog;
|
||||
|
||||
WorkspaceGraphState graph_state;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Confirme localement le déclenchement de l'action de démonstration.
|
||||
*/
|
||||
static void workspace_on_osint_demo_action_clicked(
|
||||
GtkButton *button,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
Workspace *workspace = user_data;
|
||||
const char *action_label = g_object_get_data(
|
||||
G_OBJECT(button),
|
||||
"osint-action-label"
|
||||
);
|
||||
char *status_text = NULL;
|
||||
|
||||
if (workspace == NULL || workspace->osint_tools_status_label == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
status_text = g_strdup_printf(
|
||||
"%s : démonstration locale, aucun outil exécuté.",
|
||||
action_label != NULL ? action_label : "Action OSINT"
|
||||
);
|
||||
gtk_label_set_text(
|
||||
GTK_LABEL(workspace->osint_tools_status_label),
|
||||
status_text != NULL ? status_text : "Aucun outil exécuté."
|
||||
);
|
||||
g_free(status_text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Actualise le menu OSINT selon la sélection du graphe.
|
||||
*
|
||||
|
|
@ -144,14 +178,28 @@ static void workspace_update_osint_tools_menu(
|
|||
char *context_text =
|
||||
NULL;
|
||||
|
||||
GPtrArray *compatible_actions =
|
||||
NULL;
|
||||
|
||||
GtkWidget *child =
|
||||
NULL;
|
||||
|
||||
if (workspace == NULL ||
|
||||
workspace->osint_tools_button == NULL ||
|
||||
workspace->osint_tools_context_label == NULL ||
|
||||
workspace->osint_tools_status_label == NULL)
|
||||
workspace->osint_tools_status_label == NULL ||
|
||||
workspace->osint_tools_actions_box == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while ((child = gtk_widget_get_first_child(
|
||||
workspace->osint_tools_actions_box
|
||||
)) != NULL)
|
||||
{
|
||||
gtk_box_remove(GTK_BOX(workspace->osint_tools_actions_box), child);
|
||||
}
|
||||
|
||||
if (osint_selection_context_get_kind(context) ==
|
||||
OSINT_SELECTION_CONTEXT_KIND_ENTITY)
|
||||
{
|
||||
|
|
@ -197,6 +245,56 @@ static void workspace_update_osint_tools_menu(
|
|||
return;
|
||||
}
|
||||
|
||||
compatible_actions = osint_action_catalog_list_compatible(
|
||||
workspace->osint_action_catalog,
|
||||
context
|
||||
);
|
||||
|
||||
for (guint action_index = 0;
|
||||
compatible_actions != NULL &&
|
||||
action_index < compatible_actions->len;
|
||||
action_index++)
|
||||
{
|
||||
const OsintAction *action = g_ptr_array_index(
|
||||
compatible_actions,
|
||||
action_index
|
||||
);
|
||||
GtkWidget *action_button = gtk_button_new_with_label(
|
||||
osint_action_get_label(action)
|
||||
);
|
||||
|
||||
if (action_button == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
action_button,
|
||||
osint_action_is_available(action)
|
||||
);
|
||||
gtk_widget_set_tooltip_text(
|
||||
action_button,
|
||||
osint_action_is_available(action)
|
||||
? osint_action_get_description(action)
|
||||
: osint_action_get_unavailable_reason(action)
|
||||
);
|
||||
g_object_set_data(
|
||||
G_OBJECT(action_button),
|
||||
"osint-action-label",
|
||||
(gpointer) osint_action_get_label(action)
|
||||
);
|
||||
g_signal_connect(
|
||||
action_button,
|
||||
"clicked",
|
||||
G_CALLBACK(workspace_on_osint_demo_action_clicked),
|
||||
workspace
|
||||
);
|
||||
gtk_box_append(
|
||||
GTK_BOX(workspace->osint_tools_actions_box),
|
||||
action_button
|
||||
);
|
||||
}
|
||||
|
||||
context_text =
|
||||
g_strdup_printf(
|
||||
"%s sélectionnée\n%s",
|
||||
|
|
@ -217,12 +315,16 @@ static void workspace_update_osint_tools_menu(
|
|||
GTK_LABEL(
|
||||
workspace->osint_tools_status_label
|
||||
),
|
||||
"Aucun outil OSINT intégré pour le moment."
|
||||
compatible_actions != NULL && compatible_actions->len > 0U
|
||||
? "Actions compatibles avec la sélection."
|
||||
: "Aucune action OSINT compatible."
|
||||
);
|
||||
|
||||
g_free(
|
||||
context_text
|
||||
);
|
||||
|
||||
g_clear_pointer(&compatible_actions, g_ptr_array_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1399,6 +1501,14 @@ Workspace *workspace_new(void)
|
|||
"Les outils compatibles apparaîtront ici."
|
||||
);
|
||||
|
||||
workspace->osint_tools_actions_box = gtk_box_new(
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
6
|
||||
);
|
||||
|
||||
workspace->osint_action_catalog =
|
||||
osint_action_catalog_new_defaults();
|
||||
|
||||
if (workspace->graph_toolbar == NULL ||
|
||||
workspace->reset_graph_layout_button == NULL ||
|
||||
workspace->osint_tools_button == NULL ||
|
||||
|
|
@ -1406,7 +1516,9 @@ Workspace *workspace_new(void)
|
|||
osint_tools_content == NULL ||
|
||||
osint_tools_title == NULL ||
|
||||
workspace->osint_tools_context_label == NULL ||
|
||||
workspace->osint_tools_status_label == NULL)
|
||||
workspace->osint_tools_status_label == NULL ||
|
||||
workspace->osint_tools_actions_box == NULL ||
|
||||
workspace->osint_action_catalog == NULL)
|
||||
{
|
||||
workspace_free(
|
||||
workspace
|
||||
|
|
@ -1549,6 +1661,11 @@ Workspace *workspace_new(void)
|
|||
workspace->osint_tools_context_label
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(osint_tools_content),
|
||||
workspace->osint_tools_actions_box
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
osint_tools_content
|
||||
|
|
@ -2637,6 +2754,11 @@ void workspace_free(Workspace *workspace)
|
|||
osint_selection_context_free
|
||||
);
|
||||
|
||||
g_clear_pointer(
|
||||
&workspace->osint_action_catalog,
|
||||
osint_action_catalog_free
|
||||
);
|
||||
|
||||
investigation_graph_view_set_selection_callback(
|
||||
workspace->graph_view,
|
||||
NULL,
|
||||
|
|
|
|||
69
tests/test_osint_action_catalog.c
Normal file
69
tests/test_osint_action_catalog.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include "models/osint_action_catalog.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
static OsintSelectionContext *create_entity_context(const char *type)
|
||||
{
|
||||
EntityRecord *entity = entity_record_new(
|
||||
"11111111-1111-4111-8111-111111111111", type, "example.org",
|
||||
NULL, NULL, 80, "2026-01-01T00:00:00Z",
|
||||
"2026-01-01T00:00:00Z", ENTITY_STATUS_ACTIVE, NULL
|
||||
);
|
||||
OsintSelectionContext *context =
|
||||
osint_selection_context_new_entity(entity, NULL);
|
||||
entity_record_free(entity);
|
||||
return context;
|
||||
}
|
||||
|
||||
static void test_domain_actions(void)
|
||||
{
|
||||
OsintActionCatalog *catalog = osint_action_catalog_new_defaults();
|
||||
OsintSelectionContext *context = create_entity_context("domain");
|
||||
GPtrArray *actions = osint_action_catalog_list_compatible(catalog, context);
|
||||
|
||||
g_assert_nonnull(actions);
|
||||
g_assert_cmpuint(actions->len, ==, 2U);
|
||||
g_assert_cmpstr(osint_action_get_identifier(g_ptr_array_index(actions, 0)),
|
||||
==, "selection-preview");
|
||||
g_assert_true(osint_action_is_available(g_ptr_array_index(actions, 0)));
|
||||
g_assert_false(osint_action_is_available(g_ptr_array_index(actions, 1)));
|
||||
g_assert_cmpstr(osint_action_get_required_tool_identifier(
|
||||
g_ptr_array_index(actions, 1)), ==, "dig");
|
||||
g_assert_nonnull(osint_action_get_unavailable_reason(
|
||||
g_ptr_array_index(actions, 1)));
|
||||
|
||||
g_ptr_array_unref(actions);
|
||||
osint_selection_context_free(context);
|
||||
osint_action_catalog_free(catalog);
|
||||
}
|
||||
|
||||
static void test_non_domain_actions(void)
|
||||
{
|
||||
OsintActionCatalog *catalog = osint_action_catalog_new_defaults();
|
||||
OsintSelectionContext *context = create_entity_context("person");
|
||||
GPtrArray *actions = osint_action_catalog_list_compatible(catalog, context);
|
||||
g_assert_cmpuint(actions->len, ==, 1U);
|
||||
g_assert_cmpstr(osint_action_get_identifier(g_ptr_array_index(actions, 0)),
|
||||
==, "selection-preview");
|
||||
g_ptr_array_unref(actions);
|
||||
osint_selection_context_free(context);
|
||||
osint_action_catalog_free(catalog);
|
||||
}
|
||||
|
||||
static void test_invalid_arguments(void)
|
||||
{
|
||||
OsintActionCatalog *catalog = osint_action_catalog_new_defaults();
|
||||
g_assert_null(osint_action_catalog_list_compatible(catalog, NULL));
|
||||
g_assert_null(osint_action_catalog_list_compatible(NULL, NULL));
|
||||
osint_action_catalog_free(catalog);
|
||||
osint_action_catalog_free(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func("/osint-action-catalog/domain", test_domain_actions);
|
||||
g_test_add_func("/osint-action-catalog/non-domain", test_non_domain_actions);
|
||||
g_test_add_func("/osint-action-catalog/invalid", test_invalid_arguments);
|
||||
return g_test_run();
|
||||
}
|
||||
Loading…
Reference in a new issue