Release v0.1.5.4 prepare for release

This commit is contained in:
2025-08-29 12:08:10 +02:00
parent a173c99015
commit 47b36588d3
371 changed files with 84993 additions and 30 deletions

View File

@ -9,6 +9,16 @@ add_executable(test_basic test_basic.cpp)
# Link with the already-defined privatebinapi target from the root project
target_link_libraries(test_basic PRIVATE privatebinapi)
# Ensure nlohmann_json include directories are available to the test target
target_link_libraries(test_basic PRIVATE nlohmann_json::nlohmann_json)
target_link_libraries(test_basic PRIVATE cryptopp::cryptopp)
# Add internal sources for direct testing of C++ components not exported by the DLL
target_sources(test_basic PRIVATE
${CMAKE_SOURCE_DIR}/src/json_parser.cpp
${CMAKE_SOURCE_DIR}/src/http_client.cpp
)
# Ensure the DLL is available next to the test executable on Windows
if(WIN32)
add_dependencies(test_basic privatebinapi)
@ -17,6 +27,8 @@ if(WIN32)
$<TARGET_FILE:privatebinapi>
$<TARGET_FILE_DIR:test_basic>
)
# Link WinHTTP for direct HttpClient usage in tests
target_link_libraries(test_basic PRIVATE winhttp)
endif()
# Include directories

View File

@ -3,9 +3,13 @@
// Enable by setting environment variable PRIVATEBIN_IT=1
#include "privatebinapi.h"
#include "json_parser.h"
#include "http_client.h"
#include <iostream>
#include <string>
#include <vector>
#include <cassert>
#include <fstream>
#include <cstdlib>
static bool extract_paste_id_and_key(const std::string& full_url, std::string& paste_id, std::string& key) {
@ -21,16 +25,62 @@ static bool extract_paste_id_and_key(const std::string& full_url, std::string& p
}
int main() {
// --------------------- Lightweight unit coverage section ---------------------
{
std::cout << "[test] unit: JsonParser create/parse roundtrip..." << std::endl;
std::vector<unsigned char> ct = {'A','B','C'};
std::vector<unsigned char> tag; // empty optional
std::vector<unsigned char> iv = {'I','V'};
std::vector<unsigned char> salt = {'S','A','L','T'};
auto j = JsonParser::create_paste_json(ct, tag, iv, salt, "5min", "plaintext", false, false);
std::vector<unsigned char> out_ct, out_tag, out_iv, out_salt;
std::string out_exp;
(void)JsonParser::parse_paste_json(j, out_ct, out_tag, out_iv, out_salt, out_exp);
int status = 0; std::string msg, pid, url, del;
(void)JsonParser::parse_response(std::string("{\"status\":0,\"id\":\"x\",\"url\":\"u\",\"deletetoken\":\"d\"}"), status, msg, pid, url, del);
}
{
std::cout << "[test] unit: HttpClient GET to example.com..." << std::endl;
HttpClient c;
std::string resp;
(void)c.get("https://example.com/", resp); // ignore success, just exercise code path
}
{
std::cout << "[test] unit: privatebinapi create/get/delete error-paths..." << std::endl;
const char* server = "https://127.0.0.1:9/"; // closed port to force network error
const char* content = "unit-test-content";
char* out_url = nullptr;
char* del_token = nullptr;
int rc = create_paste(server, content, nullptr, "5min", "plaintext", 0, 0, &out_url, &del_token);
(void)rc; // expect non-zero due to network; crypto/JSON path still exercised
char* out_content = nullptr;
rc = get_paste(server, "deadbeef", "ABCDEFG", &out_content);
(void)rc;
rc = delete_paste(server, "deadbeef", "tok");
(void)rc;
if (out_url) free_string(out_url);
if (del_token) free_string(del_token);
if (out_content) free_string(out_content);
}
// --------------------- Optional integration section ---------------------
char* it = nullptr;
size_t len = 0;
_dupenv_s(&it, &len, "PRIVATEBIN_IT");
if (!it || std::string(it) == "0") {
std::cout << "[test] PRIVATEBIN_IT not set; skipping integration test." << std::endl;
free(it);
return 0; // treat as success when integration testing is disabled
return 0; // success
}
const char* server = "https://privatebin.medisoftware.org/";
// Allow overriding server via env, fallback to public test instance
char* srv = nullptr; size_t srvlen = 0; _dupenv_s(&srv, &srvlen, "PRIVATEBIN_SERVER");
const char* server = (srv && *srv) ? srv : "https://privatebin.medisoftware.org/";
const char* password = nullptr; // no password
const char* expiration = "5min"; // short-lived
const int burn_after_reading = 0;
@ -224,6 +274,76 @@ std::cout << x << std::endl;
free_string(markdown_delete_token);
free_string(markdown_fetched);
std::cout << "[test] All format tests passed successfully!" << std::endl;
// Test 4: File upload via API
{
std::cout << "[test] 4. Testing file upload..." << std::endl;
// Create temporary file
const char* tmpName = "test_upload_tmp.txt";
{
std::ofstream ofs(tmpName, std::ios::binary);
ofs << "File-Upload via privatebinapi test\n0123456789";
}
char* fu_url = nullptr;
char* fu_del = nullptr;
int frc = upload_file(server, tmpName, nullptr, "5min", 0, 0, &fu_url, &fu_del);
if (frc != 0 || !fu_url || !fu_del) {
std::cerr << "[test][ERROR] upload_file failed, rc=" << frc << std::endl;
if (fu_url) free_string(fu_url);
if (fu_del) free_string(fu_del);
if (srv) free(srv);
free(it);
return 1;
}
std::string full_url2 = fu_url;
std::string paste_id2; std::string key2;
const bool ok2 = extract_paste_id_and_key(full_url2, paste_id2, key2);
if (!ok2) {
std::cerr << "[test][ERROR] failed to parse file paste id/key from URL: " << full_url2 << std::endl;
free_string(fu_url);
free_string(fu_del);
if (srv) free(srv);
free(it);
return 1;
}
char* fetched2 = nullptr;
frc = get_paste(server, paste_id2.c_str(), key2.c_str(), &fetched2);
if (frc != 0 || !fetched2) {
std::cerr << "[test][ERROR] get_paste (file) failed, rc=" << frc << std::endl;
free_string(fu_url);
free_string(fu_del);
if (srv) free(srv);
free(it);
return 1;
}
std::string fetched2_str = fetched2;
// Basic content check
if (fetched2_str.find("File-Upload via privatebinapi test") == std::string::npos) {
std::cerr << "[test][ERROR] fetched file content mismatch" << std::endl;
free_string(fu_url);
free_string(fu_del);
free_string(fetched2);
if (srv) free(srv);
free(it);
return 1;
}
// Cleanup on server
frc = delete_paste(server, paste_id2.c_str(), fu_del);
if (frc != 0) {
std::cerr << "[test][WARN] delete_paste(file) returned rc=" << frc << std::endl;
}
free_string(fu_url);
free_string(fu_del);
free_string(fetched2);
// Remove local tmp
std::remove(tmpName);
}
std::cout << "[test] All format & file tests passed successfully!" << std::endl;
if (srv) free(srv);
return 0;
}