#include "../rapi/rc_api_common.h"
#include "rc_api_runtime.h" /* for rc_fetch_image */
#include "../rc_compat.h"
#include "../test_framework.h"
#define IMAGEREQUEST_URL "https://media.retroachievements.org"
static void _assert_json_parse_response(rc_api_response_t* response, rc_json_field_t* field, const char* json, int expected_result) {
int result;
rc_api_server_response_t server_response;
rc_json_field_t fields[] = {
RC_JSON_NEW_FIELD("Success"),
RC_JSON_NEW_FIELD("Error"),
RC_JSON_NEW_FIELD("Test")
};
rc_buffer_init(&response->buffer);
memset(&server_response, 0, sizeof(server_response));
server_response.body = json;
server_response.body_length = strlen(json);
result = rc_json_parse_server_response(response, &server_response, fields, sizeof(fields)/sizeof(fields[0]));
ASSERT_NUM_EQUALS(result, expected_result);
ASSERT_NUM_EQUALS(response->succeeded, 1);
ASSERT_PTR_NULL(response->error_message);
memcpy(field, &fields[2], sizeof(fields[2]));
}
#define assert_json_parse_response(response, field, json, expected_result) ASSERT_HELPER(_assert_json_parse_response(response, field, json, expected_result), "assert_json_parse_operand")
static void _assert_field_value(rc_json_field_t* field, const char* expected_value) {
char buffer[256];
ASSERT_PTR_NOT_NULL(field->value_start);
ASSERT_PTR_NOT_NULL(field->value_end);
ASSERT_NUM_LESS(field->value_end - field->value_start, sizeof(buffer));
memcpy(buffer, field->value_start, field->value_end - field->value_start);
buffer[field->value_end - field->value_start] = '\0';
ASSERT_STR_EQUALS(buffer, expected_value);
}
#define assert_field_value(field, expected_value) ASSERT_HELPER(_assert_field_value(field, expected_value), "assert_field_value")
static void test_json_parse_response_empty() {
rc_api_response_t response;
rc_json_field_t field;
assert_json_parse_response(&response, &field, "{}", RC_OK);
ASSERT_STR_EQUALS(field.name, "Test");
ASSERT_PTR_NULL(field.value_start);
ASSERT_PTR_NULL(field.value_end);
}
static void test_json_parse_response_field(const char* json, const char* value) {
rc_api_response_t response;
rc_json_field_t field;
assert_json_parse_response(&response, &field, json, RC_OK);
ASSERT_STR_EQUALS(field.name, "Test");
assert_field_value(&field, value);
}
static void test_json_parse_response_non_json() {
int result;
rc_api_server_response_t server_response;
rc_api_response_t response;
const char* error_message = "This is an error.";
rc_json_field_t fields[] = {
RC_JSON_NEW_FIELD("Success"),
RC_JSON_NEW_FIELD("Error"),
RC_JSON_NEW_FIELD("Test")
};
rc_buffer_init(&response.buffer);
memset(&server_response, 0, sizeof(server_response));
server_response.body = error_message;
server_response.body_length = strlen(error_message);
result = rc_json_parse_server_response(&response, &server_response, fields, sizeof(fields) / sizeof(fields[0]));
ASSERT_NUM_EQUALS(result, RC_INVALID_JSON);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "This is an error.");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_parse_response_non_json_bounded() {
int result;
rc_api_server_response_t server_response;
rc_api_response_t response;
const char* error_message = "This is an error.\r\n
Should not be seen";
rc_json_field_t fields[] = {
RC_JSON_NEW_FIELD("Success"),
RC_JSON_NEW_FIELD("Error"),
RC_JSON_NEW_FIELD("Test")
};
rc_buffer_init(&response.buffer);
memset(&server_response, 0, sizeof(server_response));
server_response.body = error_message;
server_response.body_length = 16; /* "This is an error" (no period, newline, etc) */
result = rc_json_parse_server_response(&response, &server_response, fields, sizeof(fields) / sizeof(fields[0]));
ASSERT_NUM_EQUALS(result, RC_INVALID_JSON);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "This is an error");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_parse_response_error_from_server() {
int result;
rc_api_server_response_t server_response;
rc_api_response_t response;
const char* json;
rc_json_field_t fields[] = {
RC_JSON_NEW_FIELD("Success"),
RC_JSON_NEW_FIELD("Error"),
RC_JSON_NEW_FIELD("Test")
};
rc_buffer_init(&response.buffer);
json = "{\"Success\":false,\"Error\":\"Oops\"}";
memset(&server_response, 0, sizeof(server_response));
server_response.body = json;
server_response.body_length = strlen(json);
result = rc_json_parse_server_response(&response, &server_response, fields, sizeof(fields)/sizeof(fields[0]));
ASSERT_NUM_EQUALS(result, RC_OK);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Oops");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_parse_response_incorrect_size() {
int result;
rc_api_server_response_t server_response;
rc_api_response_t response;
const char* json;
rc_json_field_t fields[] = {
RC_JSON_NEW_FIELD("Success"),
RC_JSON_NEW_FIELD("Error"),
RC_JSON_NEW_FIELD("Test")
};
rc_buffer_init(&response.buffer);
json = "{\"Success\":false,\"Error\":\"Oops\"}";
memset(&server_response, 0, sizeof(server_response));
server_response.body = json;
server_response.body_length = strlen(json) - 1;
result = rc_json_parse_server_response(&response, &server_response, fields, sizeof(fields) / sizeof(fields[0]));
ASSERT_NUM_EQUALS(result, RC_INVALID_JSON);
/* the error message was found before the parser failed */
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Oops");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_string(const char* escaped, const char* expected) {
rc_api_response_t response;
rc_json_field_t field;
char buffer[256];
const char *value = NULL;
snprintf(buffer, sizeof(buffer), "{\"Test\":\"%s\"}", escaped);
assert_json_parse_response(&response, &field, buffer, RC_OK);
ASSERT_TRUE(rc_json_get_string(&value, &response.buffer, &field, "Test"));
ASSERT_PTR_NOT_NULL(value);
ASSERT_STR_EQUALS(value, expected);
}
static void test_json_get_optional_string() {
rc_api_response_t response;
rc_json_field_t field;
const char *value = NULL;
assert_json_parse_response(&response, &field, "{\"Test\":\"Value\"}", RC_OK);
rc_json_get_optional_string(&value, &response, &field, "Test", "Default");
ASSERT_PTR_NOT_NULL(value);
ASSERT_STR_EQUALS(value, "Value");
assert_json_parse_response(&response, &field, "{\"Test2\":\"Value\"}", RC_OK);
rc_json_get_optional_string(&value, &response, &field, "Test", "Default");
ASSERT_PTR_NOT_NULL(value);
ASSERT_STR_EQUALS(value, "Default");
}
static void test_json_get_required_string() {
rc_api_response_t response;
rc_json_field_t field;
const char *value = NULL;
assert_json_parse_response(&response, &field, "{\"Test\":\"Value\"}", RC_OK);
ASSERT_TRUE(rc_json_get_required_string(&value, &response, &field, "Test"));
ASSERT_PTR_NOT_NULL(value);
ASSERT_STR_EQUALS(value, "Value");
ASSERT_PTR_NULL(response.error_message);
ASSERT_NUM_EQUALS(response.succeeded, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":\"Value\"}", RC_OK);
ASSERT_FALSE(rc_json_get_required_string(&value, &response, &field, "Test"));
ASSERT_PTR_NULL(value);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Test not found in response");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_num(const char* input, int expected) {
rc_api_response_t response;
rc_json_field_t field;
char buffer[64];
int value = 0;
snprintf(buffer, sizeof(buffer), "{\"Test\":%s}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
if (expected) {
ASSERT_TRUE(rc_json_get_num(&value, &field, "Test"));
}
else {
ASSERT_FALSE(rc_json_get_num(&value, &field, "Test"));
}
ASSERT_NUM_EQUALS(value, expected);
}
static void test_json_get_optional_num() {
rc_api_response_t response;
rc_json_field_t field;
int value = 0;
assert_json_parse_response(&response, &field, "{\"Test\":12345678}", RC_OK);
rc_json_get_optional_num(&value, &field, "Test", 9999);
ASSERT_NUM_EQUALS(value, 12345678);
assert_json_parse_response(&response, &field, "{\"Test2\":12345678}", RC_OK);
rc_json_get_optional_num(&value, &field, "Test", 9999);
ASSERT_NUM_EQUALS(value, 9999);
}
static void test_json_get_required_num() {
rc_api_response_t response;
rc_json_field_t field;
int value = 0;
assert_json_parse_response(&response, &field, "{\"Test\":12345678}", RC_OK);
ASSERT_TRUE(rc_json_get_required_num(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 12345678);
ASSERT_PTR_NULL(response.error_message);
ASSERT_NUM_EQUALS(response.succeeded, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":12345678}", RC_OK);
ASSERT_FALSE(rc_json_get_required_num(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 0);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Test not found in response");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_unum(const char* input, uint32_t expected) {
rc_api_response_t response;
rc_json_field_t field;
char buffer[64];
uint32_t value = 0;
snprintf(buffer, sizeof(buffer), "{\"Test\":%s}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
if (expected) {
ASSERT_TRUE(rc_json_get_unum(&value, &field, "Test"));
}
else {
ASSERT_FALSE(rc_json_get_unum(&value, &field, "Test"));
}
ASSERT_NUM_EQUALS(value, expected);
}
static void test_json_get_optional_unum() {
rc_api_response_t response;
rc_json_field_t field;
uint32_t value = 0;
assert_json_parse_response(&response, &field, "{\"Test\":12345678}", RC_OK);
rc_json_get_optional_unum(&value, &field, "Test", 9999);
ASSERT_NUM_EQUALS(value, 12345678);
assert_json_parse_response(&response, &field, "{\"Test2\":12345678}", RC_OK);
rc_json_get_optional_unum(&value, &field, "Test", 9999);
ASSERT_NUM_EQUALS(value, 9999);
}
static void test_json_get_required_unum() {
rc_api_response_t response;
rc_json_field_t field;
uint32_t value = 0;
assert_json_parse_response(&response, &field, "{\"Test\":12345678}", RC_OK);
ASSERT_TRUE(rc_json_get_required_unum(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 12345678);
ASSERT_PTR_NULL(response.error_message);
ASSERT_NUM_EQUALS(response.succeeded, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":12345678}", RC_OK);
ASSERT_FALSE(rc_json_get_required_unum(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 0);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Test not found in response");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_float(const char* input, float expected)
{
rc_api_response_t response;
rc_json_field_t field;
char buffer[64];
float value = 0.0;
snprintf(buffer, sizeof(buffer), "{\"Test\":%s}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
if (expected)
{
ASSERT_TRUE(rc_json_get_float(&value, &field, "Test"));
}
else
{
ASSERT_FALSE(rc_json_get_float(&value, &field, "Test"));
}
ASSERT_FLOAT_EQUALS(value, expected);
}
static void test_json_get_optional_float()
{
rc_api_response_t response;
rc_json_field_t field;
float value = 0.0;
assert_json_parse_response(&response, &field, "{\"Test\":1.5}", RC_OK);
rc_json_get_optional_float(&value, &field, "Test", 9999);
ASSERT_FLOAT_EQUALS(value, 1.5);
assert_json_parse_response(&response, &field, "{\"Test2\":1.5}", RC_OK);
rc_json_get_optional_float(&value, &field, "Test", 2.5);
ASSERT_FLOAT_EQUALS(value, 2.5);
}
static void test_json_get_required_float()
{
rc_api_response_t response;
rc_json_field_t field;
float value = 0.0;
assert_json_parse_response(&response, &field, "{\"Test\":1.5}", RC_OK);
ASSERT_TRUE(rc_json_get_required_float(&value, &response, &field, "Test"));
ASSERT_FLOAT_EQUALS(value, 1.5f);
ASSERT_PTR_NULL(response.error_message);
ASSERT_NUM_EQUALS(response.succeeded, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":1.5}", RC_OK);
ASSERT_FALSE(rc_json_get_required_float(&value, &response, &field, "Test"));
ASSERT_FLOAT_EQUALS(value, 0.0f);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Test not found in response");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_bool(const char* input, int expected) {
rc_api_response_t response;
rc_json_field_t field;
char buffer[64];
int value = 2;
snprintf(buffer, sizeof(buffer), "{\"Test\":%s}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
if (expected != -1) {
ASSERT_TRUE(rc_json_get_bool(&value, &field, "Test"));
ASSERT_NUM_EQUALS(value, expected);
}
else {
ASSERT_FALSE(rc_json_get_bool(&value, &field, "Test"));
ASSERT_NUM_EQUALS(value, 0);
}
}
static void test_json_get_optional_bool() {
rc_api_response_t response;
rc_json_field_t field;
int value = 3;
assert_json_parse_response(&response, &field, "{\"Test\":true}", RC_OK);
rc_json_get_optional_bool(&value, &field, "Test", 2);
ASSERT_NUM_EQUALS(value, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":true}", RC_OK);
rc_json_get_optional_bool(&value, &field, "Test", 2);
ASSERT_NUM_EQUALS(value, 2);
}
static void test_json_get_required_bool() {
rc_api_response_t response;
rc_json_field_t field;
int value = 3;
assert_json_parse_response(&response, &field, "{\"Test\":true}", RC_OK);
ASSERT_TRUE(rc_json_get_required_bool(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 1);
ASSERT_PTR_NULL(response.error_message);
ASSERT_NUM_EQUALS(response.succeeded, 1);
assert_json_parse_response(&response, &field, "{\"Test2\":True}", RC_OK);
ASSERT_FALSE(rc_json_get_required_bool(&value, &response, &field, "Test"));
ASSERT_NUM_EQUALS(value, 0);
ASSERT_PTR_NOT_NULL(response.error_message);
ASSERT_STR_EQUALS(response.error_message, "Test not found in response");
ASSERT_NUM_EQUALS(response.succeeded, 0);
}
static void test_json_get_datetime(const char* input, int expected) {
rc_api_response_t response;
rc_json_field_t field;
char buffer[64];
time_t value = 2;
snprintf(buffer, sizeof(buffer), "{\"Test\":\"%s\"}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
if (expected != -1) {
ASSERT_TRUE(rc_json_get_datetime(&value, &field, "Test"));
ASSERT_NUM_EQUALS(value, (time_t)expected);
}
else {
ASSERT_FALSE(rc_json_get_datetime(&value, &field, "Test"));
ASSERT_NUM_EQUALS(value, 0);
}
}
static void test_json_get_unum_array(const char* input, uint32_t expected_count, int expected_result) {
rc_api_response_t response;
rc_json_field_t field;
int result;
uint32_t count = 0xFFFFFFFF;
uint32_t*values;
char buffer[128];
snprintf(buffer, sizeof(buffer), "{\"Test\":%s}", input);
assert_json_parse_response(&response, &field, buffer, RC_OK);
result = rc_json_get_required_unum_array(&values, &count, &response, &field, "Test");
ASSERT_NUM_EQUALS(result, expected_result);
ASSERT_NUM_EQUALS(count, expected_count);
rc_buffer_destroy(&response.buffer);
}
static void test_json_get_unum_array_trailing_comma() {
rc_api_response_t response;
rc_json_field_t field;
assert_json_parse_response(&response, &field, "{\"Test\":[1,2,3,]}", RC_INVALID_JSON);
}
static void test_url_build_dorequest_url_default_host() {
rc_api_request_t request;
rc_api_fetch_image_request_t api_params;
rc_api_url_build_dorequest_url(&request);
ASSERT_STR_EQUALS(request.url, "https://retroachievements.org/dorequest.php");
rc_api_destroy_request(&request);
api_params.image_type = RC_IMAGE_TYPE_ACHIEVEMENT;
api_params.image_name = "12345";
rc_api_init_fetch_image_request(&request, &api_params);
ASSERT_STR_EQUALS(request.url, "https://media.retroachievements.org/Badge/12345.png");
rc_api_destroy_request(&request);
}
static void test_url_build_dorequest_url_default_host_nonssl() {
rc_api_request_t request;
rc_api_fetch_image_request_t api_params;
rc_api_set_host("http://retroachievements.org");
rc_api_url_build_dorequest_url(&request);
ASSERT_STR_EQUALS(request.url, "http://retroachievements.org/dorequest.php");
rc_api_destroy_request(&request);
api_params.image_type = RC_IMAGE_TYPE_ACHIEVEMENT;
api_params.image_name = "12345";
rc_api_init_fetch_image_request(&request, &api_params);
ASSERT_STR_EQUALS(request.url, "http://media.retroachievements.org/Badge/12345.png");
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
static void test_url_build_dorequest_url_custom_host() {
rc_api_request_t request;
rc_api_fetch_image_request_t api_params;
rc_api_set_host("http://localhost");
rc_api_url_build_dorequest_url(&request);
ASSERT_STR_EQUALS(request.url, "http://localhost/dorequest.php");
rc_api_destroy_request(&request);
api_params.image_type = RC_IMAGE_TYPE_ACHIEVEMENT;
api_params.image_name = "12345";
rc_api_init_fetch_image_request(&request, &api_params);
ASSERT_STR_EQUALS(request.url, "http://localhost/Badge/12345.png");
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
static void test_url_build_dorequest_url_custom_host_no_protocol() {
rc_api_request_t request;
rc_api_fetch_image_request_t api_params;
rc_api_set_host("my.host");
rc_api_url_build_dorequest_url(&request);
ASSERT_STR_EQUALS(request.url, "http://my.host/dorequest.php");
rc_api_destroy_request(&request);
api_params.image_type = RC_IMAGE_TYPE_ACHIEVEMENT;
api_params.image_name = "12345";
rc_api_init_fetch_image_request(&request, &api_params);
ASSERT_STR_EQUALS(request.url, "http://my.host/Badge/12345.png");
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
static void test_url_builder_append_encoded_str(const char* input, const char* expected) {
rc_api_url_builder_t builder;
rc_buffer_t buffer;
const char* output;
rc_buffer_init(&buffer);
rc_url_builder_init(&builder, &buffer, 128);
rc_url_builder_append_encoded_str(&builder, input);
output = rc_url_builder_finalize(&builder);
ASSERT_STR_EQUALS(output, expected);
rc_buffer_destroy(&buffer);
}
static void test_url_builder_append_str_param() {
rc_api_url_builder_t builder;
rc_buffer_t buffer;
const char* output;
rc_buffer_init(&buffer);
rc_url_builder_init(&builder, &buffer, 64);
rc_url_builder_append_str_param(&builder, "a", "Apple");
rc_url_builder_append_str_param(&builder, "b", "Banana");
rc_url_builder_append_str_param(&builder, "t", "Test 1");
output = rc_url_builder_finalize(&builder);
ASSERT_STR_EQUALS(output, "a=Apple&b=Banana&t=Test+1");
rc_buffer_destroy(&buffer);
}
static void test_url_builder_append_unum_param() {
rc_api_url_builder_t builder;
rc_buffer_t buffer;
const char* output;
rc_buffer_init(&buffer);
rc_url_builder_init(&builder, &buffer, 32);
rc_url_builder_append_unum_param(&builder, "a", 0);
rc_url_builder_append_unum_param(&builder, "b", 123456);
rc_url_builder_append_unum_param(&builder, "t", (unsigned)-1);
output = rc_url_builder_finalize(&builder);
ASSERT_STR_EQUALS(output, "a=0&b=123456&t=4294967295");
rc_buffer_destroy(&buffer);
}
static void test_url_builder_append_num_param() {
rc_api_url_builder_t builder;
rc_buffer_t buffer;
const char* output;
rc_buffer_init(&buffer);
rc_url_builder_init(&builder, &buffer, 32);
rc_url_builder_append_num_param(&builder, "a", 0);
rc_url_builder_append_num_param(&builder, "b", 123456);
rc_url_builder_append_num_param(&builder, "t", -1);
output = rc_url_builder_finalize(&builder);
ASSERT_STR_EQUALS(output, "a=0&b=123456&t=-1");
rc_buffer_destroy(&buffer);
}
static void test_init_fetch_image_request_game() {
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "0123324";
fetch_image_request.image_type = RC_IMAGE_TYPE_GAME;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, IMAGEREQUEST_URL "/Images/0123324.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
}
static void test_init_fetch_image_request_achievement() {
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "135764";
fetch_image_request.image_type = RC_IMAGE_TYPE_ACHIEVEMENT;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, IMAGEREQUEST_URL "/Badge/135764.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
}
static void test_init_fetch_image_request_achievement_locked() {
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "135764";
fetch_image_request.image_type = RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, IMAGEREQUEST_URL "/Badge/135764_lock.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
}
static void test_init_fetch_image_request_user() {
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "Username";
fetch_image_request.image_type = RC_IMAGE_TYPE_USER;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, IMAGEREQUEST_URL "/UserPic/Username.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
}
static void test_init_fetch_image_request_unknown() {
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "12345";
fetch_image_request.image_type = -1;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_INVALID_STATE);
rc_api_destroy_request(&request);
}
static void test_init_fetch_image_request_custom_host()
{
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
rc_api_set_host("http://localhost");
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "0123324";
fetch_image_request.image_type = RC_IMAGE_TYPE_GAME;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, "http://localhost/Images/0123324.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
static void test_init_fetch_image_request_explicit_default_host()
{
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
rc_api_set_host("https://retroachievements.org");
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "0123324";
fetch_image_request.image_type = RC_IMAGE_TYPE_GAME;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, "https://media.retroachievements.org/Images/0123324.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
static void test_init_fetch_image_request_explicit_nonssl_host()
{
rc_api_fetch_image_request_t fetch_image_request;
rc_api_request_t request;
rc_api_set_host("http://retroachievements.org");
memset(&fetch_image_request, 0, sizeof(fetch_image_request));
fetch_image_request.image_name = "0123324";
fetch_image_request.image_type = RC_IMAGE_TYPE_GAME;
ASSERT_NUM_EQUALS(rc_api_init_fetch_image_request(&request, &fetch_image_request), RC_OK);
ASSERT_STR_EQUALS(request.url, "http://media.retroachievements.org/Images/0123324.png");
ASSERT_PTR_NULL(request.post_data);
rc_api_destroy_request(&request);
rc_api_set_host(NULL);
}
void test_rapi_common(void) {
TEST_SUITE_BEGIN();
/* rc_json_parse_response */
TEST(test_json_parse_response_empty);
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":\"Test\"}", "\"Test\""); /* string */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":\"Te\\\"st\"}", "\"Te\\\"st\""); /* escaped string */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":12345678}", "12345678"); /* integer */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":+12345678}", "+12345678"); /* positive integer */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":-12345678}", "-12345678"); /* negatvie integer */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":1234.5678}", "1234.5678"); /* decimal */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":+1234.5678}", "+1234.5678"); /* positive decimal */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":-1234.5678}", "-1234.5678"); /* negatvie decimal */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":[1,2,3]}", "[1,2,3]"); /* array */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":{\"Foo\":1}}", "{\"Foo\":1}"); /* object */
TEST_PARAMS2(test_json_parse_response_field, "{\"Test\":null}", "null"); /* null */
TEST_PARAMS2(test_json_parse_response_field, "{ \"Test\" : 0 }", "0"); /* ignore whitespace */
TEST_PARAMS2(test_json_parse_response_field, "{ \"Other\" : 1, \"Test\" : 2 }", "2"); /* preceding field */
TEST_PARAMS2(test_json_parse_response_field, "{ \"Test\" : 1, \"Other\" : 2 }", "1"); /* trailing field */
TEST(test_json_parse_response_non_json);
TEST(test_json_parse_response_non_json_bounded);
TEST(test_json_parse_response_error_from_server);
TEST(test_json_parse_response_incorrect_size);
/* rc_json_get_string */
TEST_PARAMS2(test_json_get_string, "", "");
TEST_PARAMS2(test_json_get_string, "Banana", "Banana");
TEST_PARAMS2(test_json_get_string, "A \\\"Quoted\\\" String", "A \"Quoted\" String");
TEST_PARAMS2(test_json_get_string, "This\\r\\nThat", "This\r\nThat");
TEST_PARAMS2(test_json_get_string, "This\\/That", "This/That");
TEST_PARAMS2(test_json_get_string, "\\u0065", "e");
TEST_PARAMS2(test_json_get_string, "\\u00a9", "\xc2\xa9");
TEST_PARAMS2(test_json_get_string, "\\u2260", "\xe2\x89\xa0");
TEST_PARAMS2(test_json_get_string, "\\ud83d\\udeb6", "\xf0\x9f\x9a\xb6"); /* surrogate pair */
TEST_PARAMS2(test_json_get_string, "\\ud83d", "\xef\xbf\xbd"); /* surrogate lead with no tail */
TEST_PARAMS2(test_json_get_string, "\\udeb6", "\xef\xbf\xbd"); /* surrogate tail with no lead */
TEST(test_json_get_optional_string);
TEST(test_json_get_required_string);
/* rc_json_get_num */
TEST_PARAMS2(test_json_get_num, "Banana", 0);
TEST_PARAMS2(test_json_get_num, "True", 0);
TEST_PARAMS2(test_json_get_num, "2468", 2468);
TEST_PARAMS2(test_json_get_num, "+55", 55);
TEST_PARAMS2(test_json_get_num, "-16", -16);
TEST_PARAMS2(test_json_get_num, "3.14159", 3);
TEST(test_json_get_optional_num);
TEST(test_json_get_required_num);
/* rc_json_get_unum */
TEST_PARAMS2(test_json_get_unum, "Banana", 0);
TEST_PARAMS2(test_json_get_unum, "True", 0);
TEST_PARAMS2(test_json_get_unum, "2468", 2468);
TEST_PARAMS2(test_json_get_unum, "+55", 0);
TEST_PARAMS2(test_json_get_unum, "-16", 0);
TEST_PARAMS2(test_json_get_unum, "3.14159", 3);
TEST(test_json_get_optional_unum);
TEST(test_json_get_required_unum);
/* rc_json_get_num */
TEST_PARAMS2(test_json_get_float, "Banana", 0.0f);
TEST_PARAMS2(test_json_get_float, "True", 0.0f);
TEST_PARAMS2(test_json_get_float, "2468", 2468.0f);
TEST_PARAMS2(test_json_get_float, "+55", 55.0f);
TEST_PARAMS2(test_json_get_float, "-16", -16.0f);
TEST_PARAMS2(test_json_get_float, "3.14159", 3.14159f);
TEST_PARAMS2(test_json_get_float, "-6.7", -6.7f);
TEST(test_json_get_optional_float);
TEST(test_json_get_required_float);
/* rc_json_get_bool */
TEST_PARAMS2(test_json_get_bool, "true", 1);
TEST_PARAMS2(test_json_get_bool, "false", 0);
TEST_PARAMS2(test_json_get_bool, "TRUE", 1);
TEST_PARAMS2(test_json_get_bool, "True", 1);
TEST_PARAMS2(test_json_get_bool, "Banana", -1);
TEST_PARAMS2(test_json_get_bool, "1", 1);
TEST_PARAMS2(test_json_get_bool, "0", 0);
TEST(test_json_get_optional_bool);
TEST(test_json_get_required_bool);
/* rc_json_get_datetime */
TEST_PARAMS2(test_json_get_datetime, "", -1);
TEST_PARAMS2(test_json_get_datetime, "2015-01-01 08:15:00", 1420100100);
TEST_PARAMS2(test_json_get_datetime, "2016-02-29 20:01:47", 1456776107);
/* rc_json_get_unum_array */
TEST_PARAMS3(test_json_get_unum_array, "[]", 0, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "1", 0, RC_MISSING_VALUE);
TEST_PARAMS3(test_json_get_unum_array, "[1]", 1, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "[ 1 ]", 1, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "[1,2,3,4]", 4, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "[ 1 , 2 ]", 2, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "[1,1,1]", 3, RC_OK);
TEST_PARAMS3(test_json_get_unum_array, "[A,B,C]", 3, RC_MISSING_VALUE);
TEST(test_json_get_unum_array_trailing_comma);
/* rc_api_url_build_dorequest_url / rc_api_set_host */
TEST(test_url_build_dorequest_url_default_host);
TEST(test_url_build_dorequest_url_default_host_nonssl);
TEST(test_url_build_dorequest_url_custom_host);
TEST(test_url_build_dorequest_url_custom_host_no_protocol);
/* rc_api_url_builder_append_encoded_str */
TEST_PARAMS2(test_url_builder_append_encoded_str, "", "");
TEST_PARAMS2(test_url_builder_append_encoded_str, "Apple", "Apple");
TEST_PARAMS2(test_url_builder_append_encoded_str, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~");
TEST_PARAMS2(test_url_builder_append_encoded_str, "Test 1", "Test+1");
TEST_PARAMS2(test_url_builder_append_encoded_str, "Test+1", "Test%2b1");
TEST_PARAMS2(test_url_builder_append_encoded_str, "Test%1", "Test%251");
TEST_PARAMS2(test_url_builder_append_encoded_str, "%Test%", "%25Test%25");
TEST_PARAMS2(test_url_builder_append_encoded_str, "%%", "%25%25");
/* rc_api_url_builder_append_param */
TEST(test_url_builder_append_str_param);
TEST(test_url_builder_append_num_param);
TEST(test_url_builder_append_unum_param);
/* fetch_image */
TEST(test_init_fetch_image_request_game);
TEST(test_init_fetch_image_request_achievement);
TEST(test_init_fetch_image_request_achievement_locked);
TEST(test_init_fetch_image_request_user);
TEST(test_init_fetch_image_request_unknown);
TEST(test_init_fetch_image_request_custom_host);
TEST(test_init_fetch_image_request_explicit_default_host);
TEST(test_init_fetch_image_request_explicit_nonssl_host);
TEST_SUITE_END();
}