373 lines
12 KiB
C
373 lines
12 KiB
C
/*
|
|
* NIP-21 URI Scheme Test Suite
|
|
* Tests nostr: URI parsing and construction functionality
|
|
* Following TESTS POLICY: Shows expected vs actual values
|
|
*/
|
|
|
|
#define _GNU_SOURCE // For strdup on Linux
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include "../nostr_core/nip021.h"
|
|
#include "../nostr_core/nostr_common.h"
|
|
#include "../nostr_core/utils.h"
|
|
|
|
// Ensure strdup is declared
|
|
#ifndef strdup
|
|
extern char *strdup(const char *s);
|
|
#endif
|
|
|
|
// Test counter for tracking progress
|
|
static int test_count = 0;
|
|
static int passed_tests = 0;
|
|
|
|
void print_test_header(const char* test_name) {
|
|
test_count++;
|
|
printf("\n=== TEST %d: %s ===\n", test_count, test_name);
|
|
}
|
|
|
|
void print_test_result(int passed, const char* test_name) {
|
|
if (passed) {
|
|
passed_tests++;
|
|
printf("✅ PASS: %s\n", test_name);
|
|
} else {
|
|
printf("❌ FAIL: %s\n", test_name);
|
|
}
|
|
}
|
|
|
|
// Test 1: Parse note URI
|
|
int test_parse_note_uri(void) {
|
|
print_test_header("Parse note: URI");
|
|
|
|
// First build a valid note URI, then parse it
|
|
unsigned char event_id[32];
|
|
nostr_hex_to_bytes("f1e582c90f071c0110cc5bcac2dcc6d8c32250e3cc26fcbe93470d918f2ffaf0", event_id, 32);
|
|
|
|
char built_uri[200];
|
|
int build_result = nostr_build_uri_note(event_id, built_uri, sizeof(built_uri));
|
|
if (build_result != NOSTR_SUCCESS) {
|
|
printf("Failed to build URI for testing: %d (%s)\n", build_result, nostr_strerror(build_result));
|
|
return 0;
|
|
}
|
|
|
|
printf("Input URI: %s\n", built_uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(built_uri, &result);
|
|
|
|
printf("Expected: NOSTR_SUCCESS (0)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
if (parse_result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Expected type: NOSTR_URI_NOTE\n");
|
|
printf("Actual type: %d\n", result.type);
|
|
|
|
if (result.type != NOSTR_URI_NOTE) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Expected event ID to be set\n");
|
|
printf("Event ID present: %s\n", result.data.event_id[0] ? "yes" : "no");
|
|
|
|
// Verify the parsed event ID matches the original
|
|
int event_id_match = (memcmp(result.data.event_id, event_id, 32) == 0);
|
|
printf("Event ID matches original: %s\n", event_id_match ? "yes" : "no");
|
|
|
|
return (result.type == NOSTR_URI_NOTE && event_id_match);
|
|
}
|
|
|
|
// Test 2: Parse nprofile URI
|
|
int test_parse_nprofile_uri(void) {
|
|
print_test_header("Parse nprofile: URI");
|
|
|
|
// First build a valid nprofile URI, then parse it
|
|
unsigned char pubkey[32];
|
|
nostr_hex_to_bytes("aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4", pubkey, 32);
|
|
const char* relays[] = {"wss://relay.example.com"};
|
|
|
|
char built_uri[300];
|
|
int build_result = nostr_build_uri_nprofile(pubkey, relays, 1, built_uri, sizeof(built_uri));
|
|
if (build_result != NOSTR_SUCCESS) {
|
|
printf("Failed to build URI for testing: %d (%s)\n", build_result, nostr_strerror(build_result));
|
|
return 0;
|
|
}
|
|
|
|
printf("Input URI: %s\n", built_uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(built_uri, &result);
|
|
|
|
printf("Expected: NOSTR_SUCCESS (0)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
if (parse_result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Expected type: NOSTR_URI_NPROFILE\n");
|
|
printf("Actual type: %d\n", result.type);
|
|
|
|
if (result.type != NOSTR_URI_NPROFILE) {
|
|
return 0;
|
|
}
|
|
|
|
// Verify the parsed pubkey matches the original
|
|
int pubkey_match = (memcmp(result.data.nprofile.pubkey, pubkey, 32) == 0);
|
|
printf("Pubkey matches original: %s\n", pubkey_match ? "yes" : "no");
|
|
|
|
// Verify relay count
|
|
printf("Expected relay count: 1\n");
|
|
printf("Actual relay count: %d\n", result.data.nprofile.relay_count);
|
|
|
|
return (result.type == NOSTR_URI_NPROFILE && pubkey_match && result.data.nprofile.relay_count == 1);
|
|
}
|
|
|
|
// Test 3: Parse nevent URI
|
|
int test_parse_nevent_uri(void) {
|
|
print_test_header("Parse nevent: URI");
|
|
|
|
// First build a valid nevent URI, then parse it
|
|
unsigned char event_id[32];
|
|
nostr_hex_to_bytes("f1e582c90f071c0110cc5bcac2dcc6d8c32250e3cc26fcbe93470d918f2ffaf0", event_id, 32);
|
|
const char* relays[] = {"wss://relay.example.com"};
|
|
|
|
char built_uri[400];
|
|
int build_result = nostr_build_uri_nevent(event_id, relays, 1, NULL, 1, 1234567890, built_uri, sizeof(built_uri));
|
|
if (build_result != NOSTR_SUCCESS) {
|
|
printf("Failed to build URI for testing: %d (%s)\n", build_result, nostr_strerror(build_result));
|
|
return 0;
|
|
}
|
|
|
|
printf("Input URI: %s\n", built_uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(built_uri, &result);
|
|
|
|
printf("Expected: NOSTR_SUCCESS (0)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
if (parse_result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Expected type: NOSTR_URI_NEVENT\n");
|
|
printf("Actual type: %d\n", result.type);
|
|
|
|
if (result.type != NOSTR_URI_NEVENT) {
|
|
return 0;
|
|
}
|
|
|
|
// Verify the parsed event ID matches the original
|
|
int event_id_match = (memcmp(result.data.nevent.event_id, event_id, 32) == 0);
|
|
printf("Event ID matches original: %s\n", event_id_match ? "yes" : "no");
|
|
|
|
// Verify kind
|
|
printf("Expected kind: 1\n");
|
|
printf("Actual kind: %d\n", result.data.nevent.kind ? *result.data.nevent.kind : -1);
|
|
|
|
// Verify relay count
|
|
printf("Expected relay count: 1\n");
|
|
printf("Actual relay count: %d\n", result.data.nevent.relay_count);
|
|
|
|
return (result.type == NOSTR_URI_NEVENT && event_id_match && result.data.nevent.relay_count == 1);
|
|
}
|
|
|
|
// Test 4: Parse naddr URI
|
|
int test_parse_naddr_uri(void) {
|
|
print_test_header("Parse naddr: URI");
|
|
|
|
// First build a valid naddr URI, then parse it
|
|
const char* identifier = "draft";
|
|
unsigned char pubkey[32];
|
|
nostr_hex_to_bytes("aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4", pubkey, 32);
|
|
const char* relays[] = {"wss://relay.example.com"};
|
|
|
|
char built_uri[400];
|
|
int build_result = nostr_build_uri_naddr(identifier, pubkey, 30023, relays, 1, built_uri, sizeof(built_uri));
|
|
if (build_result != NOSTR_SUCCESS) {
|
|
printf("Failed to build URI for testing: %d (%s)\n", build_result, nostr_strerror(build_result));
|
|
return 0;
|
|
}
|
|
|
|
printf("Input URI: %s\n", built_uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(built_uri, &result);
|
|
|
|
printf("Expected: NOSTR_SUCCESS (0)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
if (parse_result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Expected type: NOSTR_URI_NADDR\n");
|
|
printf("Actual type: %d\n", result.type);
|
|
|
|
if (result.type != NOSTR_URI_NADDR) {
|
|
return 0;
|
|
}
|
|
|
|
// Verify the parsed identifier matches the original
|
|
int identifier_match = (strcmp(result.data.naddr.identifier, identifier) == 0);
|
|
printf("Identifier matches original: %s\n", identifier_match ? "yes" : "no");
|
|
|
|
// Verify kind
|
|
printf("Expected kind: 30023\n");
|
|
printf("Actual kind: %d\n", result.data.naddr.kind);
|
|
|
|
// Verify relay count
|
|
printf("Expected relay count: 1\n");
|
|
printf("Actual relay count: %d\n", result.data.naddr.relay_count);
|
|
|
|
return (result.type == NOSTR_URI_NADDR && identifier_match && result.data.naddr.relay_count == 1);
|
|
}
|
|
|
|
// Test 5: Invalid URI (wrong prefix)
|
|
int test_invalid_uri_prefix(void) {
|
|
print_test_header("Invalid URI - Wrong Prefix");
|
|
|
|
const char* uri = "bitcoin:note1example";
|
|
printf("Input URI: %s\n", uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(uri, &result);
|
|
|
|
printf("Expected: NOSTR_ERROR_INVALID_INPUT (-1)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
return (parse_result == NOSTR_ERROR_INVALID_INPUT);
|
|
}
|
|
|
|
// Test 6: Invalid URI (missing colon)
|
|
int test_invalid_uri_no_colon(void) {
|
|
print_test_header("Invalid URI - No Colon");
|
|
|
|
const char* uri = "nostrnote1example";
|
|
printf("Input URI: %s\n", uri);
|
|
|
|
nostr_uri_result_t result;
|
|
int parse_result = nostr_parse_uri(uri, &result);
|
|
|
|
printf("Expected: NOSTR_ERROR_INVALID_INPUT (-1)\n");
|
|
printf("Actual: %d (%s)\n", parse_result, nostr_strerror(parse_result));
|
|
|
|
return (parse_result == NOSTR_ERROR_INVALID_INPUT);
|
|
}
|
|
|
|
// Test 7: Build note URI
|
|
int test_build_note_uri(void) {
|
|
print_test_header("Build note: URI");
|
|
|
|
unsigned char event_id[32];
|
|
nostr_hex_to_bytes("f1e582c90f071c0110cc5bcac2dcc6d8c32250e3cc26fcbe93470d918f2ffaf0", event_id, 32);
|
|
printf("Input event ID: f1e582c90f071c0110cc5bcac2dcc6d8c32250e3cc26fcbe93470d918f2ffaf0\n");
|
|
|
|
char uri[200];
|
|
int result = nostr_build_uri_note(event_id, uri, sizeof(uri));
|
|
printf("Build result: %d (%s)\n", result, nostr_strerror(result));
|
|
|
|
if (result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Built URI: %s\n", uri);
|
|
int success = (strncmp(uri, "nostr:note1", 11) == 0);
|
|
printf("Expected: URI starts with 'nostr:note1'\n");
|
|
printf("Actual: %s\n", success ? "yes" : "no");
|
|
|
|
return success;
|
|
}
|
|
|
|
// Test 8: Build nprofile URI
|
|
int test_build_nprofile_uri(void) {
|
|
print_test_header("Build nprofile: URI");
|
|
|
|
unsigned char pubkey[32];
|
|
nostr_hex_to_bytes("aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4", pubkey, 32);
|
|
const char* relays[] = {"wss://relay.example.com", "wss://relay2.example.com"};
|
|
printf("Input pubkey: aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4\n");
|
|
|
|
char uri[300];
|
|
int result = nostr_build_uri_nprofile(pubkey, relays, 2, uri, sizeof(uri));
|
|
printf("Build result: %d (%s)\n", result, nostr_strerror(result));
|
|
|
|
if (result != NOSTR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
printf("Built URI: %s\n", uri);
|
|
int success = (strncmp(uri, "nostr:nprofile1", 14) == 0);
|
|
printf("Expected: URI starts with 'nostr:nprofile1'\n");
|
|
printf("Actual: %s\n", success ? "yes" : "no");
|
|
|
|
return success;
|
|
}
|
|
|
|
int main(void) {
|
|
printf("=== NIP-21 URI Scheme Test Suite ===\n");
|
|
printf("Following TESTS POLICY: Shows expected vs actual values\n");
|
|
|
|
// Initialize crypto library
|
|
if (nostr_init() != NOSTR_SUCCESS) {
|
|
printf("❌ Failed to initialize nostr library\n");
|
|
return 1;
|
|
}
|
|
|
|
int all_passed = 1;
|
|
int test_result;
|
|
|
|
// Valid URI parsing tests
|
|
test_result = test_parse_note_uri();
|
|
print_test_result(test_result, "Parse note: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
test_result = test_parse_nprofile_uri();
|
|
print_test_result(test_result, "Parse nprofile: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
test_result = test_parse_nevent_uri();
|
|
print_test_result(test_result, "Parse nevent: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
test_result = test_parse_naddr_uri();
|
|
print_test_result(test_result, "Parse naddr: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
// Invalid URI tests
|
|
test_result = test_invalid_uri_prefix();
|
|
print_test_result(test_result, "Invalid URI - Wrong Prefix");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
test_result = test_invalid_uri_no_colon();
|
|
print_test_result(test_result, "Invalid URI - No Colon");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
// URI building tests
|
|
test_result = test_build_note_uri();
|
|
print_test_result(test_result, "Build note: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
test_result = test_build_nprofile_uri();
|
|
print_test_result(test_result, "Build nprofile: URI");
|
|
if (!test_result) all_passed = 0;
|
|
|
|
// Summary
|
|
printf("\n=== TEST SUMMARY ===\n");
|
|
printf("Total tests: %d\n", test_count);
|
|
printf("Passed: %d\n", passed_tests);
|
|
printf("Failed: %d\n", test_count - passed_tests);
|
|
|
|
if (all_passed) {
|
|
printf("🎉 ALL TESTS PASSED! NIP-21 URI scheme implementation is working correctly.\n");
|
|
} else {
|
|
printf("❌ SOME TESTS FAILED. Please review the output above.\n");
|
|
}
|
|
|
|
nostr_cleanup();
|
|
return all_passed ? 0 : 1;
|
|
} |