gemba 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/THIRD_PARTY_NOTICES +37 -2
  3. data/assets/placeholder_boxart.png +0 -0
  4. data/bin/gemba +2 -2
  5. data/ext/gemba/extconf.rb +23 -1
  6. data/ext/gemba/gemba_ext.c +436 -2
  7. data/ext/gemba/gemba_ext.h +2 -0
  8. data/gemba.gemspec +5 -3
  9. data/lib/gemba/achievements/achievement.rb +23 -0
  10. data/lib/gemba/achievements/backend.rb +186 -0
  11. data/lib/gemba/achievements/cache.rb +70 -0
  12. data/lib/gemba/achievements/credentials_presenter.rb +142 -0
  13. data/lib/gemba/achievements/fake_backend.rb +205 -0
  14. data/lib/gemba/achievements/null_backend.rb +11 -0
  15. data/lib/gemba/achievements/offline_backend.rb +168 -0
  16. data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
  17. data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
  18. data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
  19. data/lib/gemba/achievements.rb +19 -0
  20. data/lib/gemba/achievements_window.rb +556 -0
  21. data/lib/gemba/app_controller.rb +1015 -0
  22. data/lib/gemba/bios.rb +54 -0
  23. data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
  24. data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
  25. data/lib/gemba/boxart_fetcher.rb +79 -0
  26. data/lib/gemba/bus_emitter.rb +13 -0
  27. data/lib/gemba/child_window.rb +24 -1
  28. data/lib/gemba/cli/commands/config_cmd.rb +83 -0
  29. data/lib/gemba/cli/commands/decode.rb +154 -0
  30. data/lib/gemba/cli/commands/patch.rb +78 -0
  31. data/lib/gemba/cli/commands/play.rb +78 -0
  32. data/lib/gemba/cli/commands/record.rb +114 -0
  33. data/lib/gemba/cli/commands/replay.rb +161 -0
  34. data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
  35. data/lib/gemba/cli/commands/version.rb +22 -0
  36. data/lib/gemba/cli.rb +52 -364
  37. data/lib/gemba/config.rb +134 -1
  38. data/lib/gemba/data/gb_games.json +1 -0
  39. data/lib/gemba/data/gb_md5.json +1 -0
  40. data/lib/gemba/data/gba_games.json +1 -0
  41. data/lib/gemba/data/gba_md5.json +1 -0
  42. data/lib/gemba/data/gbc_games.json +1 -0
  43. data/lib/gemba/data/gbc_md5.json +1 -0
  44. data/lib/gemba/emulator_frame.rb +1060 -0
  45. data/lib/gemba/event_bus.rb +48 -0
  46. data/lib/gemba/frame_stack.rb +60 -0
  47. data/lib/gemba/game_index.rb +84 -0
  48. data/lib/gemba/game_picker_frame.rb +268 -0
  49. data/lib/gemba/gamepad_map.rb +103 -0
  50. data/lib/gemba/headless.rb +6 -5
  51. data/lib/gemba/headless_player.rb +33 -3
  52. data/lib/gemba/help_window.rb +61 -0
  53. data/lib/gemba/hotkey_map.rb +3 -1
  54. data/lib/gemba/input_recorder.rb +107 -0
  55. data/lib/gemba/input_replayer.rb +119 -0
  56. data/lib/gemba/keyboard_map.rb +90 -0
  57. data/lib/gemba/locales/en.yml +97 -5
  58. data/lib/gemba/locales/ja.yml +97 -5
  59. data/lib/gemba/main_window.rb +56 -0
  60. data/lib/gemba/modal_stack.rb +81 -0
  61. data/lib/gemba/patcher_window.rb +223 -0
  62. data/lib/gemba/platform/gb.rb +21 -0
  63. data/lib/gemba/platform/gba.rb +21 -0
  64. data/lib/gemba/platform/gbc.rb +23 -0
  65. data/lib/gemba/platform.rb +20 -0
  66. data/lib/gemba/platform_open.rb +19 -0
  67. data/lib/gemba/recorder.rb +4 -3
  68. data/lib/gemba/replay_player.rb +691 -0
  69. data/lib/gemba/rom_info.rb +57 -0
  70. data/lib/gemba/rom_info_window.rb +16 -3
  71. data/lib/gemba/rom_library.rb +106 -0
  72. data/lib/gemba/rom_overrides.rb +47 -0
  73. data/lib/gemba/rom_patcher/bps.rb +161 -0
  74. data/lib/gemba/rom_patcher/ips.rb +101 -0
  75. data/lib/gemba/rom_patcher/ups.rb +118 -0
  76. data/lib/gemba/rom_patcher.rb +109 -0
  77. data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
  78. data/lib/gemba/runtime.rb +59 -26
  79. data/lib/gemba/save_state_manager.rb +4 -7
  80. data/lib/gemba/save_state_picker.rb +17 -4
  81. data/lib/gemba/session_logger.rb +64 -0
  82. data/lib/gemba/settings/audio_tab.rb +77 -0
  83. data/lib/gemba/settings/gamepad_tab.rb +351 -0
  84. data/lib/gemba/settings/hotkeys_tab.rb +259 -0
  85. data/lib/gemba/settings/paths.rb +11 -0
  86. data/lib/gemba/settings/recording_tab.rb +83 -0
  87. data/lib/gemba/settings/save_states_tab.rb +91 -0
  88. data/lib/gemba/settings/system_tab.rb +362 -0
  89. data/lib/gemba/settings/video_tab.rb +318 -0
  90. data/lib/gemba/settings_window.rb +162 -1036
  91. data/lib/gemba/version.rb +1 -1
  92. data/lib/gemba/virtual_keyboard.rb +19 -0
  93. data/lib/gemba.rb +2 -12
  94. data/test/achievements_window/test_bulk_sync.rb +218 -0
  95. data/test/achievements_window/test_bus_events.rb +125 -0
  96. data/test/achievements_window/test_close_confirmation.rb +201 -0
  97. data/test/achievements_window/test_initial_state.rb +164 -0
  98. data/test/achievements_window/test_sorting.rb +227 -0
  99. data/test/achievements_window/test_tree_rendering.rb +133 -0
  100. data/test/fixtures/fake_bios.bin +0 -0
  101. data/test/fixtures/pong.gba +0 -0
  102. data/test/fixtures/test.gb +0 -0
  103. data/test/fixtures/test.gbc +0 -0
  104. data/test/fixtures/test_quicksave.ss +0 -0
  105. data/test/screenshots/no_focus.png +0 -0
  106. data/test/shared/teek_test_worker.rb +17 -1
  107. data/test/shared/tk_test_helper.rb +91 -4
  108. data/test/support/achievements_window_helpers.rb +18 -0
  109. data/test/support/fake_core.rb +25 -0
  110. data/test/support/fake_ra_runtime.rb +74 -0
  111. data/test/support/fake_requester.rb +68 -0
  112. data/test/support/player_helpers.rb +20 -5
  113. data/test/test_achievement.rb +32 -0
  114. data/test/{test_player.rb → test_app_controller.rb} +353 -85
  115. data/test/test_bios.rb +123 -0
  116. data/test/test_boxart_fetcher.rb +150 -0
  117. data/test/test_cli.rb +17 -265
  118. data/test/test_cli_config.rb +64 -0
  119. data/test/test_cli_decode.rb +97 -0
  120. data/test/test_cli_patch.rb +58 -0
  121. data/test/test_cli_play.rb +213 -0
  122. data/test/test_cli_ra.rb +175 -0
  123. data/test/test_cli_record.rb +69 -0
  124. data/test/test_cli_replay.rb +72 -0
  125. data/test/test_cli_sync_requester.rb +152 -0
  126. data/test/test_cli_version.rb +27 -0
  127. data/test/test_config.rb +2 -3
  128. data/test/test_config_ra.rb +69 -0
  129. data/test/test_core.rb +62 -1
  130. data/test/test_credentials_presenter.rb +192 -0
  131. data/test/test_event_bus.rb +100 -0
  132. data/test/test_fake_backend_achievements.rb +130 -0
  133. data/test/test_fake_backend_auth.rb +68 -0
  134. data/test/test_game_index.rb +77 -0
  135. data/test/test_game_picker_frame.rb +310 -0
  136. data/test/test_gamepad_map.rb +1 -3
  137. data/test/test_headless_player.rb +17 -3
  138. data/test/test_help_window.rb +82 -0
  139. data/test/test_hotkey_map.rb +22 -1
  140. data/test/test_input_recorder.rb +179 -0
  141. data/test/test_input_replay_determinism.rb +113 -0
  142. data/test/test_input_replayer.rb +162 -0
  143. data/test/test_keyboard_map.rb +1 -3
  144. data/test/test_libretro_backend.rb +41 -0
  145. data/test/test_locale.rb +1 -1
  146. data/test/test_logging.rb +123 -0
  147. data/test/test_null_backend.rb +42 -0
  148. data/test/test_offline_backend.rb +116 -0
  149. data/test/test_overlay_renderer.rb +1 -1
  150. data/test/test_platform.rb +149 -0
  151. data/test/test_ra_backend.rb +313 -0
  152. data/test/test_ra_backend_unlock_gate.rb +56 -0
  153. data/test/test_recorder.rb +0 -3
  154. data/test/test_replay_player.rb +316 -0
  155. data/test/test_rom_info.rb +149 -0
  156. data/test/test_rom_overrides.rb +86 -0
  157. data/test/test_rom_patcher.rb +382 -0
  158. data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
  159. data/test/test_save_state_manager.rb +2 -4
  160. data/test/test_settings_audio.rb +107 -0
  161. data/test/test_settings_hotkeys.rb +83 -66
  162. data/test/test_settings_recording.rb +49 -0
  163. data/test/test_settings_save_states.rb +97 -0
  164. data/test/test_settings_system.rb +133 -0
  165. data/test/test_settings_video.rb +450 -0
  166. data/test/test_settings_window.rb +76 -507
  167. data/test/test_tip_service.rb +6 -6
  168. data/test/test_toast_overlay.rb +1 -1
  169. data/test/test_virtual_events.rb +156 -0
  170. data/test/test_virtual_keyboard.rb +1 -1
  171. data/vendor/rcheevos/CHANGELOG.md +495 -0
  172. data/vendor/rcheevos/LICENSE +21 -0
  173. data/vendor/rcheevos/Package.swift +33 -0
  174. data/vendor/rcheevos/README.md +67 -0
  175. data/vendor/rcheevos/include/module.modulemap +70 -0
  176. data/vendor/rcheevos/include/rc_api_editor.h +296 -0
  177. data/vendor/rcheevos/include/rc_api_info.h +280 -0
  178. data/vendor/rcheevos/include/rc_api_request.h +77 -0
  179. data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
  180. data/vendor/rcheevos/include/rc_api_user.h +262 -0
  181. data/vendor/rcheevos/include/rc_client.h +877 -0
  182. data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
  183. data/vendor/rcheevos/include/rc_consoles.h +138 -0
  184. data/vendor/rcheevos/include/rc_error.h +59 -0
  185. data/vendor/rcheevos/include/rc_export.h +100 -0
  186. data/vendor/rcheevos/include/rc_hash.h +200 -0
  187. data/vendor/rcheevos/include/rc_runtime.h +148 -0
  188. data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
  189. data/vendor/rcheevos/include/rc_util.h +51 -0
  190. data/vendor/rcheevos/include/rcheevos.h +8 -0
  191. data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
  192. data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
  193. data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
  194. data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
  195. data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
  196. data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
  197. data/vendor/rcheevos/src/rc_client.c +6941 -0
  198. data/vendor/rcheevos/src/rc_client_external.c +281 -0
  199. data/vendor/rcheevos/src/rc_client_external.h +177 -0
  200. data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
  201. data/vendor/rcheevos/src/rc_client_internal.h +409 -0
  202. data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
  203. data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
  204. data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
  205. data/vendor/rcheevos/src/rc_compat.c +251 -0
  206. data/vendor/rcheevos/src/rc_compat.h +121 -0
  207. data/vendor/rcheevos/src/rc_libretro.c +915 -0
  208. data/vendor/rcheevos/src/rc_libretro.h +98 -0
  209. data/vendor/rcheevos/src/rc_util.c +199 -0
  210. data/vendor/rcheevos/src/rc_version.c +11 -0
  211. data/vendor/rcheevos/src/rc_version.h +32 -0
  212. data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
  213. data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
  214. data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
  215. data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
  216. data/vendor/rcheevos/src/rcheevos/format.c +330 -0
  217. data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
  218. data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
  219. data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
  220. data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
  221. data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
  222. data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
  223. data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
  224. data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
  225. data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
  226. data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
  227. data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
  228. data/vendor/rcheevos/src/rcheevos/value.c +935 -0
  229. data/vendor/rcheevos/src/rhash/aes.c +480 -0
  230. data/vendor/rcheevos/src/rhash/aes.h +49 -0
  231. data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
  232. data/vendor/rcheevos/src/rhash/hash.c +1402 -0
  233. data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
  234. data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
  235. data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
  236. data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
  237. data/vendor/rcheevos/src/rhash/md5.c +382 -0
  238. data/vendor/rcheevos/src/rhash/md5.h +91 -0
  239. data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
  240. data/vendor/rcheevos/test/libretro.h +205 -0
  241. data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
  242. data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
  243. data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
  244. data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
  245. data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
  246. data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
  247. data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
  248. data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
  249. data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
  250. data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
  251. data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
  252. data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
  253. data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
  254. data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
  255. data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
  256. data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
  257. data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
  258. data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
  259. data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
  260. data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
  261. data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
  262. data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
  263. data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
  264. data/vendor/rcheevos/test/rhash/data.c +657 -0
  265. data/vendor/rcheevos/test/rhash/data.h +32 -0
  266. data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
  267. data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
  268. data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
  269. data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
  270. data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
  271. data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
  272. data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
  273. data/vendor/rcheevos/test/test.c +113 -0
  274. data/vendor/rcheevos/test/test_framework.h +205 -0
  275. data/vendor/rcheevos/test/test_rc_client.c +10509 -0
  276. data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
  277. data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
  278. data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
  279. data/vendor/rcheevos/test/test_types.natvis +9 -0
  280. data/vendor/rcheevos/validator/validator.c +658 -0
  281. data/vendor/rcheevos/validator/validator.vcxproj +152 -0
  282. data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
  283. metadata +274 -11
  284. data/lib/gemba/input_mappings.rb +0 -214
  285. data/lib/gemba/player.rb +0 -1525
@@ -0,0 +1,2213 @@
1
+ #include "rc_api_runtime.h"
2
+
3
+ #include "rc_error.h"
4
+ #include "rc_runtime_types.h"
5
+
6
+ #include "../src/rapi/rc_api_common.h"
7
+ #include "../test_framework.h"
8
+
9
+ #define DOREQUEST_URL "https://retroachievements.org/dorequest.php"
10
+
11
+ static void init_server_response(rc_api_server_response_t* server_response,
12
+ int status_code, const char* body, size_t body_length) {
13
+ memset(server_response, 0, sizeof(*server_response));
14
+ server_response->body = body;
15
+ server_response->body_length = body_length;
16
+ server_response->http_status_code = status_code;
17
+ }
18
+
19
+ /* ----- resolve hash ----- */
20
+
21
+ static void test_init_resolve_hash_request() {
22
+ rc_api_resolve_hash_request_t resolve_hash_request;
23
+ rc_api_request_t request;
24
+
25
+ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request));
26
+ resolve_hash_request.username = "Username"; /* credentials are ignored - turns out server doesn't validate this API */
27
+ resolve_hash_request.api_token = "API_TOKEN";
28
+ resolve_hash_request.game_hash = "ABCDEF0123456789";
29
+
30
+ ASSERT_NUM_EQUALS(rc_api_init_resolve_hash_request(&request, &resolve_hash_request), RC_OK);
31
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
32
+ ASSERT_STR_EQUALS(request.post_data, "r=gameid&m=ABCDEF0123456789");
33
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
34
+
35
+ rc_api_destroy_request(&request);
36
+ }
37
+
38
+ static void test_init_resolve_hash_request_no_credentials() {
39
+ rc_api_resolve_hash_request_t resolve_hash_request;
40
+ rc_api_request_t request;
41
+
42
+ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request));
43
+ resolve_hash_request.game_hash = "ABCDEF0123456789";
44
+
45
+ ASSERT_NUM_EQUALS(rc_api_init_resolve_hash_request(&request, &resolve_hash_request), RC_OK);
46
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
47
+ ASSERT_STR_EQUALS(request.post_data, "r=gameid&m=ABCDEF0123456789");
48
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
49
+
50
+ rc_api_destroy_request(&request);
51
+ }
52
+
53
+ static void test_init_resolve_hash_request_no_hash() {
54
+ rc_api_resolve_hash_request_t resolve_hash_request;
55
+ rc_api_request_t request;
56
+
57
+ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request));
58
+
59
+ ASSERT_NUM_EQUALS(rc_api_init_resolve_hash_request(&request, &resolve_hash_request), RC_INVALID_STATE);
60
+
61
+ rc_api_destroy_request(&request);
62
+ }
63
+
64
+ static void test_init_resolve_hash_request_empty_hash() {
65
+ rc_api_resolve_hash_request_t resolve_hash_request;
66
+ rc_api_request_t request;
67
+
68
+ memset(&resolve_hash_request, 0, sizeof(resolve_hash_request));
69
+ resolve_hash_request.game_hash = "";
70
+
71
+ ASSERT_NUM_EQUALS(rc_api_init_resolve_hash_request(&request, &resolve_hash_request), RC_INVALID_STATE);
72
+
73
+ rc_api_destroy_request(&request);
74
+ }
75
+
76
+ static void test_process_resolve_hash_response_match() {
77
+ rc_api_resolve_hash_response_t resolve_hash_response;
78
+ const char* server_response = "{\"Success\":true,\"GameID\":1446}";
79
+
80
+ memset(&resolve_hash_response, 0, sizeof(resolve_hash_response));
81
+
82
+ ASSERT_NUM_EQUALS(rc_api_process_resolve_hash_response(&resolve_hash_response, server_response), RC_OK);
83
+ ASSERT_NUM_EQUALS(resolve_hash_response.response.succeeded, 1);
84
+ ASSERT_PTR_NULL(resolve_hash_response.response.error_message);
85
+ ASSERT_NUM_EQUALS(resolve_hash_response.game_id, 1446);
86
+
87
+ rc_api_destroy_resolve_hash_response(&resolve_hash_response);
88
+ }
89
+
90
+ static void test_process_resolve_hash_response_no_match() {
91
+ rc_api_resolve_hash_response_t resolve_hash_response;
92
+ const char* server_response = "{\"Success\":true,\"GameID\":0}";
93
+
94
+ memset(&resolve_hash_response, 0, sizeof(resolve_hash_response));
95
+
96
+ ASSERT_NUM_EQUALS(rc_api_process_resolve_hash_response(&resolve_hash_response, server_response), RC_OK);
97
+ ASSERT_NUM_EQUALS(resolve_hash_response.response.succeeded, 1);
98
+ ASSERT_PTR_NULL(resolve_hash_response.response.error_message);
99
+ ASSERT_NUM_EQUALS(resolve_hash_response.game_id, 0);
100
+
101
+ rc_api_destroy_resolve_hash_response(&resolve_hash_response);
102
+ }
103
+
104
+ /* ----- fetch game data ----- */
105
+
106
+ static void test_init_fetch_game_data_request() {
107
+ rc_api_fetch_game_data_request_t fetch_game_data_request;
108
+ rc_api_request_t request;
109
+
110
+ memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request));
111
+ fetch_game_data_request.username = "Username";
112
+ fetch_game_data_request.api_token = "API_TOKEN";
113
+ fetch_game_data_request.game_id = 1234;
114
+
115
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_OK);
116
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
117
+ ASSERT_STR_EQUALS(request.post_data, "r=patch&u=Username&t=API_TOKEN&g=1234");
118
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
119
+
120
+ rc_api_destroy_request(&request);
121
+ }
122
+
123
+ static void test_init_fetch_game_data_request_by_hash() {
124
+ rc_api_fetch_game_data_request_t fetch_game_data_request;
125
+ rc_api_request_t request;
126
+
127
+ memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request));
128
+ fetch_game_data_request.username = "Username";
129
+ fetch_game_data_request.api_token = "API_TOKEN";
130
+ fetch_game_data_request.game_hash = "ABCDEF0123456789";
131
+
132
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_OK);
133
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
134
+ ASSERT_STR_EQUALS(request.post_data, "r=patch&u=Username&t=API_TOKEN&m=ABCDEF0123456789");
135
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
136
+
137
+ rc_api_destroy_request(&request);
138
+ }
139
+
140
+ static void test_init_fetch_game_data_request_by_id_and_hash() {
141
+ rc_api_fetch_game_data_request_t fetch_game_data_request;
142
+ rc_api_request_t request;
143
+
144
+ memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request));
145
+ fetch_game_data_request.username = "Username";
146
+ fetch_game_data_request.api_token = "API_TOKEN";
147
+ fetch_game_data_request.game_id = 1234;
148
+ fetch_game_data_request.game_hash = "ABCDEF0123456789"; /* ignored when game_id provided */
149
+
150
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_OK);
151
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
152
+ ASSERT_STR_EQUALS(request.post_data, "r=patch&u=Username&t=API_TOKEN&g=1234");
153
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
154
+
155
+ rc_api_destroy_request(&request);
156
+ }
157
+
158
+ static void test_init_fetch_game_data_request_no_id() {
159
+ rc_api_fetch_game_data_request_t fetch_game_data_request;
160
+ rc_api_request_t request;
161
+
162
+ memset(&fetch_game_data_request, 0, sizeof(fetch_game_data_request));
163
+ fetch_game_data_request.username = "Username";
164
+ fetch_game_data_request.api_token = "API_TOKEN";
165
+
166
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_data_request(&request, &fetch_game_data_request), RC_INVALID_STATE);
167
+
168
+ rc_api_destroy_request(&request);
169
+ }
170
+
171
+ static void test_process_fetch_game_data_response_empty() {
172
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
173
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
174
+ "\"ID\":177,\"Title\":\"My Game\",\"ConsoleID\":23,\"ImageIcon\":\"/Images/012345.png\","
175
+ "\"Achievements\":[],\"Leaderboards\":[]"
176
+ "}}";
177
+
178
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
179
+
180
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
181
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
182
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
183
+ ASSERT_NUM_EQUALS(fetch_game_data_response.id, 177);
184
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "My Game");
185
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 23);
186
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "012345");
187
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "");
188
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
189
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
190
+
191
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
192
+ }
193
+
194
+ static void test_process_fetch_game_data_response_invalid_credentials() {
195
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
196
+ const char* server_response = "{\"Success\":false,\"Error\":\"Credentials invalid (0)\"}";
197
+
198
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
199
+
200
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
201
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 0);
202
+ ASSERT_STR_EQUALS(fetch_game_data_response.response.error_message, "Credentials invalid (0)");
203
+ ASSERT_NUM_EQUALS(fetch_game_data_response.id, 0);
204
+ ASSERT_PTR_NULL(fetch_game_data_response.title);
205
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 0);
206
+ ASSERT_PTR_NULL(fetch_game_data_response.image_name);
207
+ ASSERT_PTR_NULL(fetch_game_data_response.rich_presence_script);
208
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
209
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
210
+
211
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
212
+ }
213
+
214
+ static void test_process_fetch_game_data_response_not_found() {
215
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
216
+ const char* server_response = "{\"Success\":false,\"Error\":\"Unknown game\",\"Code\":\"not_found\",\"Status\":404}";
217
+
218
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
219
+
220
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_NOT_FOUND);
221
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 0);
222
+ ASSERT_STR_EQUALS(fetch_game_data_response.response.error_message, "Unknown game");
223
+ ASSERT_NUM_EQUALS(fetch_game_data_response.id, 0);
224
+ ASSERT_PTR_NULL(fetch_game_data_response.title);
225
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 0);
226
+ ASSERT_PTR_NULL(fetch_game_data_response.image_name);
227
+ ASSERT_PTR_NULL(fetch_game_data_response.rich_presence_script);
228
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
229
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
230
+
231
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
232
+ }
233
+
234
+ static void test_process_fetch_game_data_response_achievements() {
235
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
236
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
237
+ "\"ID\":20,\"Title\":\"Another Amazing Game\",\"ConsoleID\":19,\"ImageIcon\":\"/Images/112233.png\","
238
+ "\"Achievements\":["
239
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
240
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
241
+ "\"Created\":1367266583,\"Modified\":1376929305},"
242
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
243
+ "\"MemAddr\":\"0=2\",\"Author\":\"User1\",\"BadgeName\":\"00235\","
244
+ "\"Created\":1376970283,\"Modified\":1376970283},"
245
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
246
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\","
247
+ "\"Created\":1376969412,\"Modified\":1376969412},"
248
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":3,\"Points\":10,"
249
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\","
250
+ "\"Created\":1504474554,\"Modified\":1504474554}"
251
+ "],\"Leaderboards\":[]"
252
+ "}}";
253
+ rc_api_achievement_definition_t* achievement;
254
+
255
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
256
+
257
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
258
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
259
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
260
+ ASSERT_NUM_EQUALS(fetch_game_data_response.id, 20);
261
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Another Amazing Game");
262
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 19);
263
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "112233");
264
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "");
265
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 4);
266
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
267
+
268
+ ASSERT_PTR_NOT_NULL(fetch_game_data_response.achievements);
269
+ achievement = fetch_game_data_response.achievements;
270
+
271
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
272
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
273
+ ASSERT_STR_EQUALS(achievement->description, "Desc1");
274
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
275
+ ASSERT_NUM_EQUALS(achievement->points, 5);
276
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
277
+ ASSERT_STR_EQUALS(achievement->author, "User1");
278
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
279
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
280
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
281
+
282
+ ++achievement;
283
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
284
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
285
+ ASSERT_STR_EQUALS(achievement->description, "Desc2");
286
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
287
+ ASSERT_NUM_EQUALS(achievement->points, 2);
288
+ ASSERT_STR_EQUALS(achievement->definition, "0=2");
289
+ ASSERT_STR_EQUALS(achievement->author, "User1");
290
+ ASSERT_STR_EQUALS(achievement->badge_name, "00235");
291
+ ASSERT_NUM_EQUALS(achievement->created, 1376970283);
292
+ ASSERT_NUM_EQUALS(achievement->updated, 1376970283);
293
+
294
+ ++achievement;
295
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
296
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
297
+ ASSERT_STR_EQUALS(achievement->description, "Desc3");
298
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL);
299
+ ASSERT_NUM_EQUALS(achievement->points, 0);
300
+ ASSERT_STR_EQUALS(achievement->definition, "0=3");
301
+ ASSERT_STR_EQUALS(achievement->author, "User2");
302
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
303
+ ASSERT_NUM_EQUALS(achievement->created, 1376969412);
304
+ ASSERT_NUM_EQUALS(achievement->updated, 1376969412);
305
+
306
+ ++achievement;
307
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
308
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
309
+ ASSERT_STR_EQUALS(achievement->description, "Desc4");
310
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
311
+ ASSERT_NUM_EQUALS(achievement->points, 10);
312
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
313
+ ASSERT_STR_EQUALS(achievement->author, "User1");
314
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
315
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
316
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
317
+
318
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
319
+ }
320
+
321
+ static void test_process_fetch_game_data_response_achievement_types() {
322
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
323
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
324
+ "\"ID\":20,\"Title\":\"Another Amazing Game\",\"ConsoleID\":19,\"ImageIcon\":\"/Images/112233.png\","
325
+ "\"Achievements\":["
326
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
327
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\",\"Type\":\"\","
328
+ "\"Created\":1367266583,\"Modified\":1376929305},"
329
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
330
+ "\"MemAddr\":\"0=2\",\"Author\":\"User1\",\"BadgeName\":\"00235\",\"Type\":\"missable\","
331
+ "\"Created\":1376970283,\"Modified\":1376970283},"
332
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
333
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\",\"Type\":\"progression\","
334
+ "\"Created\":1376969412,\"Modified\":1376969412},"
335
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":3,\"Points\":10,"
336
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"win_condition\","
337
+ "\"Created\":1504474554,\"Modified\":1504474554},"
338
+ "{\"ID\":5505,\"Title\":\"Ach5 [m]\",\"Description\":\"Desc5\",\"Flags\":3,\"Points\":10,"
339
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
340
+ "\"Created\":1504474554,\"Modified\":1504474554},"
341
+ "{\"ID\":5506,\"Title\":\"[m] Ach6\",\"Description\":\"Desc6\",\"Flags\":3,\"Points\":10,"
342
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
343
+ "\"Created\":1504474554,\"Modified\":1504474554},"
344
+ "{\"ID\":5507,\"Title\":\"Ach7\",\"Description\":\"Desc7\",\"Flags\":3,\"Points\":5,"
345
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
346
+ "\"Created\":1367266583,\"Modified\":1376929305}"
347
+ "],\"Leaderboards\":[]"
348
+ "}}";
349
+ rc_api_achievement_definition_t* achievement;
350
+
351
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
352
+
353
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
354
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
355
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
356
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 7);
357
+
358
+ ASSERT_PTR_NOT_NULL(fetch_game_data_response.achievements);
359
+ achievement = fetch_game_data_response.achievements;
360
+
361
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
362
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
363
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD);
364
+
365
+ ++achievement;
366
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
367
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
368
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
369
+
370
+ ++achievement;
371
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
372
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
373
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_PROGRESSION);
374
+
375
+ ++achievement;
376
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
377
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
378
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_WIN);
379
+
380
+ ++achievement;
381
+ ASSERT_NUM_EQUALS(achievement->id, 5505);
382
+ ASSERT_STR_EQUALS(achievement->title, "Ach5");
383
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
384
+
385
+ ++achievement;
386
+ ASSERT_NUM_EQUALS(achievement->id, 5506);
387
+ ASSERT_STR_EQUALS(achievement->title, "Ach6");
388
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
389
+
390
+ ++achievement;
391
+ ASSERT_NUM_EQUALS(achievement->id, 5507);
392
+ ASSERT_STR_EQUALS(achievement->title, "Ach7");
393
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD);
394
+
395
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
396
+ }
397
+
398
+ static void test_process_fetch_game_data_response_achievement_rarity() {
399
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
400
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
401
+ "\"ID\":20,\"Title\":\"Another Amazing Game\",\"ConsoleID\":19,\"ImageIcon\":\"/Images/112233.png\","
402
+ "\"Achievements\":["
403
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
404
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\",\"Rarity\":100.0,\"RarityHardcore\":66.67,"
405
+ "\"Created\":1367266583,\"Modified\":1376929305},"
406
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
407
+ "\"MemAddr\":\"0=2\",\"Author\":\"User1\",\"BadgeName\":\"00235\",\"Rarity\":57.43,\"RarityHardcore\":57.43,"
408
+ "\"Created\":1376970283,\"Modified\":1376970283},"
409
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
410
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\",\"Rarity\":6.8,\"RarityHardcore\":0,"
411
+ "\"Created\":1376969412,\"Modified\":1376969412},"
412
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":5,\"Points\":0,"
413
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\","
414
+ "\"Created\":1376969412,\"Modified\":1376969412}"
415
+ "],\"Leaderboards\":[]"
416
+ "}}";
417
+ rc_api_achievement_definition_t* achievement;
418
+
419
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
420
+
421
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
422
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
423
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
424
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 4);
425
+
426
+ ASSERT_PTR_NOT_NULL(fetch_game_data_response.achievements);
427
+ achievement = fetch_game_data_response.achievements;
428
+
429
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
430
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
431
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
432
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 66.67f);
433
+
434
+ ++achievement;
435
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
436
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
437
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 57.43f);
438
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 57.43f);
439
+
440
+ ++achievement;
441
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
442
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
443
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 6.8f);
444
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 0.0f);
445
+
446
+ ++achievement;
447
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
448
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
449
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
450
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
451
+
452
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
453
+ }
454
+
455
+ static void test_process_fetch_game_data_response_achievement_null_author()
456
+ {
457
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
458
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
459
+ "\"ID\":20,\"Title\":\"Another Amazing Game\",\"ConsoleID\":19,\"ImageIcon\":\"/Images/112233.png\","
460
+ "\"Achievements\":["
461
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
462
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
463
+ "\"BadgeURL\":\"http://host/Badge/00234.png\",\"BadgeLockedURL\":\"http://host/Badge/00234_lock.png\","
464
+ "\"Created\":1367266583,\"Modified\":1376929305},"
465
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
466
+ "\"MemAddr\":\"0=2\",\"Author\":null,\"BadgeName\":\"00235\","
467
+ "\"Created\":1376970283,\"Modified\":1376970283},"
468
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
469
+ "\"MemAddr\":\"0=3\",\"Author\":null,\"BadgeName\":\"00236\","
470
+ "\"Created\":1376969412,\"Modified\":1376969412},"
471
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":3,\"Points\":10,"
472
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\","
473
+ "\"Created\":1504474554,\"Modified\":1504474554}"
474
+ "],\"Leaderboards\":[]"
475
+ "}}";
476
+ rc_api_achievement_definition_t* achievement;
477
+
478
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
479
+
480
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
481
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
482
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
483
+ ASSERT_NUM_EQUALS(fetch_game_data_response.id, 20);
484
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Another Amazing Game");
485
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 19);
486
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "112233");
487
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "");
488
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 4);
489
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
490
+
491
+ ASSERT_PTR_NOT_NULL(fetch_game_data_response.achievements);
492
+ achievement = fetch_game_data_response.achievements;
493
+
494
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
495
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
496
+ ASSERT_STR_EQUALS(achievement->description, "Desc1");
497
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
498
+ ASSERT_NUM_EQUALS(achievement->points, 5);
499
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
500
+ ASSERT_STR_EQUALS(achievement->author, "User1");
501
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
502
+ ASSERT_STR_EQUALS(achievement->badge_url, "http://host/Badge/00234.png");
503
+ ASSERT_STR_EQUALS(achievement->badge_locked_url, "http://host/Badge/00234_lock.png");
504
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
505
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
506
+
507
+ ++achievement;
508
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
509
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
510
+ ASSERT_STR_EQUALS(achievement->description, "Desc2");
511
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
512
+ ASSERT_NUM_EQUALS(achievement->points, 2);
513
+ ASSERT_STR_EQUALS(achievement->definition, "0=2");
514
+ ASSERT_STR_EQUALS(achievement->author, "");
515
+ ASSERT_STR_EQUALS(achievement->badge_name, "00235");
516
+ ASSERT_STR_EQUALS(achievement->badge_url, "https://media.retroachievements.org/Badge/00235.png");
517
+ ASSERT_STR_EQUALS(achievement->badge_locked_url, "https://media.retroachievements.org/Badge/00235_lock.png");
518
+ ASSERT_NUM_EQUALS(achievement->created, 1376970283);
519
+ ASSERT_NUM_EQUALS(achievement->updated, 1376970283);
520
+
521
+ ++achievement;
522
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
523
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
524
+ ASSERT_STR_EQUALS(achievement->description, "Desc3");
525
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL);
526
+ ASSERT_NUM_EQUALS(achievement->points, 0);
527
+ ASSERT_STR_EQUALS(achievement->definition, "0=3");
528
+ ASSERT_STR_EQUALS(achievement->author, "");
529
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
530
+ ASSERT_STR_EQUALS(achievement->badge_url, "https://media.retroachievements.org/Badge/00236.png");
531
+ ASSERT_STR_EQUALS(achievement->badge_locked_url, "https://media.retroachievements.org/Badge/00236_lock.png");
532
+ ASSERT_NUM_EQUALS(achievement->created, 1376969412);
533
+ ASSERT_NUM_EQUALS(achievement->updated, 1376969412);
534
+
535
+ ++achievement;
536
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
537
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
538
+ ASSERT_STR_EQUALS(achievement->description, "Desc4");
539
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
540
+ ASSERT_NUM_EQUALS(achievement->points, 10);
541
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
542
+ ASSERT_STR_EQUALS(achievement->author, "User1");
543
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
544
+ ASSERT_STR_EQUALS(achievement->badge_url, "https://media.retroachievements.org/Badge/00236.png");
545
+ ASSERT_STR_EQUALS(achievement->badge_locked_url, "https://media.retroachievements.org/Badge/00236_lock.png");
546
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
547
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
548
+
549
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
550
+ }
551
+
552
+ static void test_process_fetch_game_data_response_leaderboards() {
553
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
554
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
555
+ "\"ID\":177,\"Title\":\"Another Amazing Game\",\"ConsoleID\":19,\"ImageIcon\":\"/Images/112233.png\","
556
+ "\"Achievements\":[],\"Leaderboards\":["
557
+ "{\"ID\":4401,\"Title\":\"Leaderboard1\",\"Description\":\"Desc1\","
558
+ "\"Mem\":\"0=1\",\"Format\":\"SCORE\"},"
559
+ "{\"ID\":4402,\"Title\":\"Leaderboard2\",\"Description\":\"Desc2\","
560
+ "\"Mem\":\"0=1\",\"Format\":\"SECS\",\"LowerIsBetter\":false,\"Hidden\":true},"
561
+ "{\"ID\":4403,\"Title\":\"Leaderboard3\",\"Description\":\"Desc3\","
562
+ "\"Mem\":\"0=1\",\"Format\":\"UNKNOWN\",\"LowerIsBetter\":true,\"Hidden\":false}"
563
+ "]}}";
564
+ rc_api_leaderboard_definition_t* leaderboard;
565
+
566
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
567
+
568
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
569
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
570
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
571
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Another Amazing Game");
572
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 19);
573
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "112233");
574
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "");
575
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
576
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 3);
577
+
578
+ ASSERT_PTR_NOT_NULL(fetch_game_data_response.leaderboards);
579
+ leaderboard = fetch_game_data_response.leaderboards;
580
+
581
+ ASSERT_NUM_EQUALS(leaderboard->id, 4401);
582
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard1");
583
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc1");
584
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
585
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SCORE);
586
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
587
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 0);
588
+
589
+ ++leaderboard;
590
+ ASSERT_NUM_EQUALS(leaderboard->id, 4402);
591
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard2");
592
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc2");
593
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
594
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SECONDS);
595
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
596
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 1);
597
+
598
+ ++leaderboard;
599
+ ASSERT_NUM_EQUALS(leaderboard->id, 4403);
600
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard3");
601
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc3");
602
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
603
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_VALUE);
604
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 1);
605
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 0);
606
+
607
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
608
+ }
609
+
610
+ static void test_process_fetch_game_data_response_rich_presence() {
611
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
612
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
613
+ "\"ID\":177,\"Title\":\"Some Other Game\",\"ConsoleID\":2,\"ImageIcon\":\"/Images/000001.png\","
614
+ "\"ImageIconURL\":\"http://host/Images/000001.png\","
615
+ "\"Achievements\":[],\"Leaderboards\":[],"
616
+ "\"RichPresencePatch\":\"Display:\\r\\nTest\\r\\n\""
617
+ "}}";
618
+
619
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
620
+
621
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
622
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
623
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
624
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Some Other Game");
625
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 2);
626
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "000001");
627
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_url, "http://host/Images/000001.png");
628
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "Display:\r\nTest\r\n");
629
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
630
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
631
+
632
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
633
+ }
634
+
635
+ static void test_process_fetch_game_data_response_rich_presence_null() {
636
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
637
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
638
+ "\"ID\":177,\"Title\":\"Some Other Game\",\"ConsoleID\":2,\"ImageIcon\":\"/Images/000001.png\","
639
+ "\"Achievements\":[],\"Leaderboards\":[],"
640
+ "\"RichPresencePatch\":null"
641
+ "}}";
642
+
643
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
644
+
645
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
646
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
647
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
648
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Some Other Game");
649
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 2);
650
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "000001");
651
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_url, "https://media.retroachievements.org/Images/000001.png");
652
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "");
653
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
654
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
655
+
656
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
657
+ }
658
+
659
+ static void test_process_fetch_game_data_response_rich_presence_tab() {
660
+ rc_api_fetch_game_data_response_t fetch_game_data_response;
661
+ const char* server_response = "{\"Success\":true,\"PatchData\":{"
662
+ "\"ID\":177,\"Title\":\"Some Other Game\",\"ConsoleID\":2,\"ImageIcon\":\"/Images/000001.png\","
663
+ "\"Achievements\":[],\"Leaderboards\":[],"
664
+ "\"RichPresencePatch\":\"Display:\\r\\nTest\\tTab\\r\\n\""
665
+ "}}";
666
+
667
+ memset(&fetch_game_data_response, 0, sizeof(fetch_game_data_response));
668
+
669
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_data_response(&fetch_game_data_response, server_response), RC_OK);
670
+ ASSERT_NUM_EQUALS(fetch_game_data_response.response.succeeded, 1);
671
+ ASSERT_PTR_NULL(fetch_game_data_response.response.error_message);
672
+ ASSERT_STR_EQUALS(fetch_game_data_response.title, "Some Other Game");
673
+ ASSERT_NUM_EQUALS(fetch_game_data_response.console_id, 2);
674
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_name, "000001");
675
+ ASSERT_STR_EQUALS(fetch_game_data_response.image_url, "https://media.retroachievements.org/Images/000001.png");
676
+ ASSERT_STR_EQUALS(fetch_game_data_response.rich_presence_script, "Display:\r\nTest\tTab\r\n");
677
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_achievements, 0);
678
+ ASSERT_NUM_EQUALS(fetch_game_data_response.num_leaderboards, 0);
679
+
680
+ rc_api_destroy_fetch_game_data_response(&fetch_game_data_response);
681
+ }
682
+
683
+ /* ----- fetch game sets ----- */
684
+
685
+ static void test_init_fetch_game_sets_request() {
686
+ rc_api_fetch_game_sets_request_t fetch_game_sets_request;
687
+ rc_api_request_t request;
688
+
689
+ memset(&fetch_game_sets_request, 0, sizeof(fetch_game_sets_request));
690
+ fetch_game_sets_request.username = "Username";
691
+ fetch_game_sets_request.api_token = "API_TOKEN";
692
+ fetch_game_sets_request.game_hash = "ABCDEF0123456789";
693
+
694
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_sets_request(&request, &fetch_game_sets_request), RC_OK);
695
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
696
+ ASSERT_STR_EQUALS(request.post_data, "r=achievementsets&u=Username&t=API_TOKEN&m=ABCDEF0123456789");
697
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
698
+
699
+ rc_api_destroy_request(&request);
700
+ }
701
+
702
+ static void test_init_fetch_game_sets_request_no_hash() {
703
+ rc_api_fetch_game_sets_request_t fetch_game_sets_request;
704
+ rc_api_request_t request;
705
+
706
+ memset(&fetch_game_sets_request, 0, sizeof(fetch_game_sets_request));
707
+ fetch_game_sets_request.username = "Username";
708
+ fetch_game_sets_request.api_token = "API_TOKEN";
709
+
710
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_sets_request(&request, &fetch_game_sets_request), RC_INVALID_STATE);
711
+
712
+ rc_api_destroy_request(&request);
713
+ }
714
+
715
+ static void test_init_fetch_game_sets_request_by_id() {
716
+ rc_api_fetch_game_sets_request_t fetch_game_sets_request;
717
+ rc_api_request_t request;
718
+
719
+ memset(&fetch_game_sets_request, 0, sizeof(fetch_game_sets_request));
720
+ fetch_game_sets_request.username = "Username";
721
+ fetch_game_sets_request.api_token = "API_TOKEN";
722
+ fetch_game_sets_request.game_id = 953;
723
+
724
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_sets_request(&request, &fetch_game_sets_request), RC_OK);
725
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
726
+ ASSERT_STR_EQUALS(request.post_data, "r=achievementsets&u=Username&t=API_TOKEN&g=953");
727
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
728
+
729
+ rc_api_destroy_request(&request);
730
+ }
731
+
732
+ static void test_init_fetch_game_sets_request_by_hash_and_id() {
733
+ rc_api_fetch_game_sets_request_t fetch_game_sets_request;
734
+ rc_api_request_t request;
735
+
736
+ memset(&fetch_game_sets_request, 0, sizeof(fetch_game_sets_request));
737
+ fetch_game_sets_request.username = "Username";
738
+ fetch_game_sets_request.api_token = "API_TOKEN";
739
+ fetch_game_sets_request.game_id = 953;
740
+ fetch_game_sets_request.game_hash = "ABCDEF0123456789";
741
+
742
+ ASSERT_NUM_EQUALS(rc_api_init_fetch_game_sets_request(&request, &fetch_game_sets_request), RC_OK);
743
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
744
+ ASSERT_STR_EQUALS(request.post_data, "r=achievementsets&u=Username&t=API_TOKEN&g=953");
745
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
746
+
747
+ rc_api_destroy_request(&request);
748
+ }
749
+
750
+ static void test_process_fetch_game_sets_response_empty() {
751
+ rc_api_achievement_set_definition_t* set;
752
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
753
+ const char server_response[] = "{\"Success\":true,"
754
+ "\"GameId\":177,\"Title\":\"My Game\",\"ConsoleId\":23,"
755
+ "\"ImageIconUrl\":\"http://server/Images/012345.png\","
756
+ "\"RichPresenceGameId\":177,\"RichPresencePatch\":\"\",\"Sets\":[{"
757
+ "\"AchievementSetId\":192,\"GameId\":177,\"Title\":null,\"Type\":\"core\","
758
+ "\"ImageIconUrl\":\"http://server/Images/012345.png\","
759
+ "\"Achievements\":[],\"Leaderboards\":[]"
760
+ "}]}";
761
+
762
+ rc_api_server_response_t fetch_game_sets_server_response;
763
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
764
+
765
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
766
+
767
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
768
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
769
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
770
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 177);
771
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "My Game");
772
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 23);
773
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "012345");
774
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/012345.png");
775
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
776
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 177);
777
+
778
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
779
+ set = &fetch_game_sets_response.sets[0];
780
+ ASSERT_NUM_EQUALS(set->id, 192);
781
+ ASSERT_NUM_EQUALS(set->game_id, 177);
782
+ ASSERT_STR_EQUALS(set->title, "My Game");
783
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
784
+ ASSERT_STR_EQUALS(set->image_name, "012345");
785
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/012345.png");
786
+ ASSERT_NUM_EQUALS(set->num_achievements, 0);
787
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
788
+
789
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
790
+ }
791
+
792
+ static void test_process_fetch_game_sets_response_invalid_credentials() {
793
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
794
+ const char server_response[] = "{\"Success\":false,\"Error\":\"Credentials invalid (0)\"}";
795
+ rc_api_server_response_t fetch_game_sets_server_response;
796
+ init_server_response(&fetch_game_sets_server_response, 403, server_response, sizeof(server_response) - 1);
797
+
798
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
799
+
800
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
801
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 0);
802
+ ASSERT_STR_EQUALS(fetch_game_sets_response.response.error_message, "Credentials invalid (0)");
803
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 0);
804
+ ASSERT_PTR_NULL(fetch_game_sets_response.title);
805
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 0);
806
+ ASSERT_PTR_NULL(fetch_game_sets_response.image_name);
807
+ ASSERT_PTR_NULL(fetch_game_sets_response.rich_presence_script);
808
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 0);
809
+
810
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
811
+ }
812
+
813
+ static void test_process_fetch_game_sets_response_not_found() {
814
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
815
+ const char server_response[] = "{\"Success\":false,\"Error\":\"Unknown game\",\"Code\":\"not_found\",\"Status\":404}";
816
+ rc_api_server_response_t fetch_game_sets_server_response;
817
+ init_server_response(&fetch_game_sets_server_response, 404, server_response, sizeof(server_response) - 1);
818
+
819
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
820
+
821
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_NOT_FOUND);
822
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 0);
823
+ ASSERT_STR_EQUALS(fetch_game_sets_response.response.error_message, "Unknown game");
824
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 0);
825
+ ASSERT_PTR_NULL(fetch_game_sets_response.title);
826
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 0);
827
+ ASSERT_PTR_NULL(fetch_game_sets_response.image_name);
828
+ ASSERT_PTR_NULL(fetch_game_sets_response.rich_presence_script);
829
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 0);
830
+
831
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
832
+ }
833
+
834
+ static void test_process_fetch_game_sets_response_achievements() {
835
+ rc_api_achievement_set_definition_t* set;
836
+ rc_api_achievement_definition_t* achievement;
837
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
838
+ const char server_response[] = "{\"Success\":true,"
839
+ "\"GameId\":20,\"Title\":\"Another Amazing Game\",\"ConsoleId\":19,"
840
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
841
+ "\"RichPresenceGameId\":20,\"RichPresencePatch\":\"\",\"Sets\":[{"
842
+ "\"AchievementSetId\":192,\"GameId\":20,\"Title\":null,\"Type\":\"core\","
843
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
844
+ "\"Achievements\":["
845
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
846
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\",\"Type\":\"\","
847
+ "\"Rarity\":100.0,\"RarityHardcore\":66.67,\"Created\":1367266583,\"Modified\":1376929305},"
848
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
849
+ "\"MemAddr\":\"0=2\",\"Author\":\"User1\",\"BadgeName\":\"00235\",\"Type\":\"missable\","
850
+ "\"Rarity\":57.43,\"RarityHardcore\":57.43,\"Created\":1376970283,\"Modified\":1376970283},"
851
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
852
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\",\"Type\":\"progression\","
853
+ "\"Rarity\":6.8,\"RarityHardcore\":0,\"Created\":1376969412,\"Modified\":1376969412},"
854
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":3,\"Points\":10,"
855
+ "\"MemAddr\":\"0=4\",\"Author\":null,\"BadgeName\":\"00236\",\"Type\":\"win_condition\","
856
+ "\"Created\":1504474554,\"Modified\":1504474554},"
857
+ "{\"ID\":5505,\"Title\":\"Ach5 [m]\",\"Description\":\"Desc5\",\"Flags\":3,\"Points\":10,"
858
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
859
+ "\"Created\":1504474554,\"Modified\":1504474554},"
860
+ "{\"ID\":5506,\"Title\":\"[m] Ach6\",\"Description\":\"Desc6\",\"Flags\":3,\"Points\":10,"
861
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
862
+ "\"Created\":1504474554,\"Modified\":1504474554},"
863
+ "{\"ID\":5507,\"Title\":\"Ach7\",\"Description\":\"Desc7\",\"Flags\":3,\"Points\":5,"
864
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
865
+ "\"Created\":1367266583,\"Modified\":1376929305}"
866
+ "],\"Leaderboards\":[]"
867
+ "}]}";
868
+ rc_api_server_response_t fetch_game_sets_server_response;
869
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
870
+
871
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
872
+
873
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
874
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
875
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
876
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 20);
877
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Another Amazing Game");
878
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 19);
879
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "112233");
880
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/112233.png");
881
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
882
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 20);
883
+
884
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
885
+ set = &fetch_game_sets_response.sets[0];
886
+ ASSERT_NUM_EQUALS(set->id, 192);
887
+ ASSERT_NUM_EQUALS(set->game_id, 20);
888
+ ASSERT_STR_EQUALS(set->title, "Another Amazing Game");
889
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
890
+ ASSERT_STR_EQUALS(set->image_name, "112233");
891
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112233.png");
892
+ ASSERT_NUM_EQUALS(set->num_achievements, 7);
893
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
894
+
895
+ ASSERT_PTR_NOT_NULL(set->achievements);
896
+ achievement = set->achievements;
897
+
898
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
899
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
900
+ ASSERT_STR_EQUALS(achievement->description, "Desc1");
901
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
902
+ ASSERT_NUM_EQUALS(achievement->points, 5);
903
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
904
+ ASSERT_STR_EQUALS(achievement->author, "User1");
905
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
906
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD);
907
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
908
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 66.67f);
909
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
910
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
911
+
912
+ ++achievement;
913
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
914
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
915
+ ASSERT_STR_EQUALS(achievement->description, "Desc2");
916
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
917
+ ASSERT_NUM_EQUALS(achievement->points, 2);
918
+ ASSERT_STR_EQUALS(achievement->definition, "0=2");
919
+ ASSERT_STR_EQUALS(achievement->author, "User1");
920
+ ASSERT_STR_EQUALS(achievement->badge_name, "00235");
921
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
922
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 57.43f);
923
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 57.43f);
924
+ ASSERT_NUM_EQUALS(achievement->created, 1376970283);
925
+ ASSERT_NUM_EQUALS(achievement->updated, 1376970283);
926
+
927
+ ++achievement;
928
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
929
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
930
+ ASSERT_STR_EQUALS(achievement->description, "Desc3");
931
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL);
932
+ ASSERT_NUM_EQUALS(achievement->points, 0);
933
+ ASSERT_STR_EQUALS(achievement->definition, "0=3");
934
+ ASSERT_STR_EQUALS(achievement->author, "User2");
935
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
936
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_PROGRESSION);
937
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 6.8f);
938
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 0.0f);
939
+ ASSERT_NUM_EQUALS(achievement->created, 1376969412);
940
+ ASSERT_NUM_EQUALS(achievement->updated, 1376969412);
941
+
942
+ ++achievement;
943
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
944
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
945
+ ASSERT_STR_EQUALS(achievement->description, "Desc4");
946
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
947
+ ASSERT_NUM_EQUALS(achievement->points, 10);
948
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
949
+ ASSERT_STR_EQUALS(achievement->author, ""); /* null author */
950
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
951
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_WIN);
952
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
953
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
954
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
955
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
956
+
957
+ ++achievement;
958
+ ASSERT_NUM_EQUALS(achievement->id, 5505);
959
+ ASSERT_STR_EQUALS(achievement->title, "Ach5"); /* [m] stripped */
960
+ ASSERT_STR_EQUALS(achievement->description, "Desc5");
961
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
962
+ ASSERT_NUM_EQUALS(achievement->points, 10);
963
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
964
+ ASSERT_STR_EQUALS(achievement->author, "User1");
965
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
966
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
967
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
968
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
969
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
970
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
971
+
972
+ ++achievement;
973
+ ASSERT_NUM_EQUALS(achievement->id, 5506);
974
+ ASSERT_STR_EQUALS(achievement->title, "Ach6"); /* [m] stripped */
975
+ ASSERT_STR_EQUALS(achievement->description, "Desc6");
976
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
977
+ ASSERT_NUM_EQUALS(achievement->points, 10);
978
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
979
+ ASSERT_STR_EQUALS(achievement->author, "User1");
980
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
981
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
982
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
983
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
984
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
985
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
986
+
987
+ ++achievement;
988
+ ASSERT_NUM_EQUALS(achievement->id, 5507);
989
+ ASSERT_STR_EQUALS(achievement->title, "Ach7");
990
+ ASSERT_STR_EQUALS(achievement->description, "Desc7");
991
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
992
+ ASSERT_NUM_EQUALS(achievement->points, 5);
993
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
994
+ ASSERT_STR_EQUALS(achievement->author, "User1");
995
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
996
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD); /* no type specified */
997
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
998
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
999
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
1000
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
1001
+
1002
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1003
+ }
1004
+
1005
+ static void test_process_fetch_game_sets_response_leaderboards() {
1006
+ rc_api_achievement_set_definition_t* set;
1007
+ rc_api_leaderboard_definition_t* leaderboard;
1008
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
1009
+ const char server_response[] = "{\"Success\":true,"
1010
+ "\"GameId\":20,\"Title\":\"Another Amazing Game\",\"ConsoleId\":19,"
1011
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
1012
+ "\"RichPresenceGameId\":20,\"RichPresencePatch\":\"\",\"Sets\":[{"
1013
+ "\"AchievementSetId\":192,\"GameId\":20,\"Title\":null,\"Type\":\"core\","
1014
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
1015
+ "\"Achievements\":[],\"Leaderboards\":["
1016
+ "{\"ID\":4401,\"Title\":\"Leaderboard1\",\"Description\":\"Desc1\","
1017
+ "\"Mem\":\"0=1\",\"Format\":\"SCORE\"},"
1018
+ "{\"ID\":4402,\"Title\":\"Leaderboard2\",\"Description\":\"Desc2\","
1019
+ "\"Mem\":\"0=1\",\"Format\":\"SECS\",\"LowerIsBetter\":false,\"Hidden\":true},"
1020
+ "{\"ID\":4403,\"Title\":\"Leaderboard3\",\"Description\":\"Desc3\","
1021
+ "\"Mem\":\"0=1\",\"Format\":\"UNKNOWN\",\"LowerIsBetter\":true,\"Hidden\":false}"
1022
+ "]"
1023
+ "}]}";
1024
+
1025
+ rc_api_server_response_t fetch_game_sets_server_response;
1026
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
1027
+
1028
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
1029
+
1030
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
1031
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
1032
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
1033
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 20);
1034
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Another Amazing Game");
1035
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 19);
1036
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "112233");
1037
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/112233.png");
1038
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
1039
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 20);
1040
+
1041
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
1042
+ set = &fetch_game_sets_response.sets[0];
1043
+ ASSERT_NUM_EQUALS(set->id, 192);
1044
+ ASSERT_NUM_EQUALS(set->game_id, 20);
1045
+ ASSERT_STR_EQUALS(set->title, "Another Amazing Game");
1046
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
1047
+ ASSERT_STR_EQUALS(set->image_name, "112233");
1048
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112233.png");
1049
+ ASSERT_NUM_EQUALS(set->num_achievements, 0);
1050
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 3);
1051
+
1052
+ ASSERT_PTR_NOT_NULL(set->leaderboards);
1053
+ leaderboard = set->leaderboards;
1054
+
1055
+ ASSERT_NUM_EQUALS(leaderboard->id, 4401);
1056
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard1");
1057
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc1");
1058
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
1059
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SCORE);
1060
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
1061
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 0);
1062
+
1063
+ ++leaderboard;
1064
+ ASSERT_NUM_EQUALS(leaderboard->id, 4402);
1065
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard2");
1066
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc2");
1067
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
1068
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SECONDS);
1069
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
1070
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 1);
1071
+
1072
+ ++leaderboard;
1073
+ ASSERT_NUM_EQUALS(leaderboard->id, 4403);
1074
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard3");
1075
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc3");
1076
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
1077
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_VALUE);
1078
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 1);
1079
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 0);
1080
+
1081
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1082
+ }
1083
+
1084
+ static void test_process_fetch_game_sets_response_rich_presence() {
1085
+ rc_api_achievement_set_definition_t* set;
1086
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
1087
+ const char server_response[] = "{\"Success\":true,"
1088
+ "\"GameId\":99,\"Title\":\"Some Other Game\",\"ConsoleId\":2,"
1089
+ "\"ImageIconUrl\":\"http://server/Images/000001.png\","
1090
+ "\"RichPresenceGameId\":99,\"RichPresencePatch\":\"Display:\\r\\nTest\\r\\n\",\"Sets\":[{"
1091
+ "\"AchievementSetId\":106,\"GameId\":99,\"Title\":null,\"Type\":\"core\","
1092
+ "\"ImageIconUrl\":\"http://server/Images/000001.png\","
1093
+ "\"Achievements\":[],\"Leaderboards\":[]"
1094
+ "}]}";
1095
+
1096
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
1097
+ rc_api_server_response_t fetch_game_sets_server_response;
1098
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
1099
+
1100
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
1101
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
1102
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
1103
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 99);
1104
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Some Other Game");
1105
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 2);
1106
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "000001");
1107
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/000001.png");
1108
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "Display:\r\nTest\r\n");
1109
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 99);
1110
+
1111
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
1112
+ set = &fetch_game_sets_response.sets[0];
1113
+ ASSERT_NUM_EQUALS(set->id, 106);
1114
+ ASSERT_NUM_EQUALS(set->game_id, 99);
1115
+ ASSERT_STR_EQUALS(set->title, "Some Other Game");
1116
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
1117
+ ASSERT_STR_EQUALS(set->image_name, "000001");
1118
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/000001.png");
1119
+ ASSERT_NUM_EQUALS(set->num_achievements, 0);
1120
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
1121
+
1122
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1123
+ }
1124
+
1125
+ static void test_process_fetch_game_sets_response_rich_presence_null() {
1126
+ rc_api_achievement_set_definition_t* set;
1127
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
1128
+ const char server_response[] = "{\"Success\":true,"
1129
+ "\"GameId\":99,\"Title\":\"Some Other Game\",\"ConsoleId\":2,"
1130
+ "\"ImageIconUrl\":\"http://server/Images/000001.png\","
1131
+ "\"RichPresenceGameId\":99,\"RichPresencePatch\":null,\"Sets\":[{"
1132
+ "\"AchievementSetId\":106,\"GameId\":99,\"Title\":null,\"Type\":\"core\","
1133
+ "\"ImageIconUrl\":\"http://server/Images/000001.png\","
1134
+ "\"Achievements\":[],\"Leaderboards\":[]"
1135
+ "}]}";
1136
+
1137
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
1138
+ rc_api_server_response_t fetch_game_sets_server_response;
1139
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
1140
+
1141
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
1142
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
1143
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
1144
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 99);
1145
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Some Other Game");
1146
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 2);
1147
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "000001");
1148
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/000001.png");
1149
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
1150
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 99);
1151
+
1152
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
1153
+ set = &fetch_game_sets_response.sets[0];
1154
+ ASSERT_NUM_EQUALS(set->id, 106);
1155
+ ASSERT_NUM_EQUALS(set->game_id, 99);
1156
+ ASSERT_STR_EQUALS(set->title, "Some Other Game");
1157
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
1158
+ ASSERT_STR_EQUALS(set->image_name, "000001");
1159
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/000001.png");
1160
+ ASSERT_NUM_EQUALS(set->num_achievements, 0);
1161
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
1162
+
1163
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1164
+ }
1165
+
1166
+ static void test_process_fetch_game_sets_response_specialty_subset() {
1167
+ rc_api_achievement_set_definition_t* set;
1168
+ rc_api_achievement_definition_t* achievement;
1169
+ rc_api_leaderboard_definition_t* leaderboard;
1170
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
1171
+ const char server_response[] = "{\"Success\":true,"
1172
+ "\"GameId\":20,\"Title\":\"Another Amazing Game\",\"ConsoleId\":19,"
1173
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
1174
+ "\"RichPresenceGameId\":20,\"RichPresencePatch\":\"\",\"Sets\":["
1175
+ "{"
1176
+ "\"AchievementSetId\":98,\"GameId\":26,\"Title\":\"Low Level Run\",\"Type\":\"specialty\","
1177
+ "\"ImageIconUrl\":\"http://server/Images/112236.png\","
1178
+ "\"Achievements\":["
1179
+ "{\"ID\":5507,\"Title\":\"Ach7\",\"Description\":\"Desc7\",\"Flags\":3,\"Points\":5,"
1180
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
1181
+ "\"Created\":1367266583,\"Modified\":1376929305}"
1182
+ "],\"Leaderboards\":[]"
1183
+ "},{"
1184
+ "\"AchievementSetId\":192,\"GameId\":20,\"Title\":null,\"Type\":\"core\","
1185
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
1186
+ "\"Achievements\":["
1187
+ "{\"ID\":5501,\"Title\":\"Ach1\",\"Description\":\"Desc1\",\"Flags\":3,\"Points\":5,"
1188
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\",\"Type\":\"progression\","
1189
+ "\"Rarity\":100.0,\"RarityHardcore\":66.67,\"Created\":1367266583,\"Modified\":1376929305},"
1190
+ "{\"ID\":5502,\"Title\":\"Ach2\",\"Description\":\"Desc2\",\"Flags\":3,\"Points\":2,"
1191
+ "\"MemAddr\":\"0=2\",\"Author\":\"User1\",\"BadgeName\":\"00235\",\"Type\":\"missable\","
1192
+ "\"Rarity\":57.43,\"RarityHardcore\":57.43,\"Created\":1376970283,\"Modified\":1376970283},"
1193
+ "{\"ID\":5503,\"Title\":\"Ach3\",\"Description\":\"Desc3\",\"Flags\":5,\"Points\":0,"
1194
+ "\"MemAddr\":\"0=3\",\"Author\":\"User2\",\"BadgeName\":\"00236\",\"Type\":\"win_condition\","
1195
+ "\"Rarity\":6.8,\"RarityHardcore\":0,\"Created\":1376969412,\"Modified\":1376969412}"
1196
+ "],\"Leaderboards\":["
1197
+ "{\"ID\":4401,\"Title\":\"Leaderboard1\",\"Description\":\"Desc1\","
1198
+ "\"Mem\":\"0=1\",\"Format\":\"SCORE\"}"
1199
+ "]"
1200
+ "},{"
1201
+ "\"AchievementSetId\":77,\"GameId\":21,\"Title\":\"Bonus\",\"Type\":\"bonus\","
1202
+ "\"ImageIconUrl\":\"http://server/Images/112236.png\","
1203
+ "\"Achievements\":["
1204
+ "{\"ID\":5504,\"Title\":\"Ach4\",\"Description\":\"Desc4\",\"Flags\":3,\"Points\":10,"
1205
+ "\"MemAddr\":\"0=4\",\"Author\":null,\"BadgeName\":\"00236\",\"Type\":\"\","
1206
+ "\"Created\":1504474554,\"Modified\":1504474554},"
1207
+ "{\"ID\":5505,\"Title\":\"Ach5 [m]\",\"Description\":\"Desc5\",\"Flags\":3,\"Points\":10,"
1208
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
1209
+ "\"Created\":1504474554,\"Modified\":1504474554},"
1210
+ "{\"ID\":5506,\"Title\":\"[m] Ach6\",\"Description\":\"Desc6\",\"Flags\":3,\"Points\":10,"
1211
+ "\"MemAddr\":\"0=4\",\"Author\":\"User1\",\"BadgeName\":\"00236\",\"Type\":\"\","
1212
+ "\"Created\":1504474554,\"Modified\":1504474554}"
1213
+ "],\"Leaderboards\":["
1214
+ "{\"ID\":4402,\"Title\":\"Leaderboard2\",\"Description\":\"Desc2\","
1215
+ "\"Mem\":\"0=1\",\"Format\":\"SECS\",\"LowerIsBetter\":false,\"Hidden\":true}"
1216
+ "]"
1217
+ "}"
1218
+ "]}";
1219
+ rc_api_server_response_t fetch_game_sets_server_response;
1220
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
1221
+
1222
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
1223
+
1224
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
1225
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
1226
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
1227
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 20);
1228
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Another Amazing Game");
1229
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 19);
1230
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "112233");
1231
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/112233.png");
1232
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
1233
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 20);
1234
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 3);
1235
+
1236
+ set = &fetch_game_sets_response.sets[0];
1237
+ ASSERT_NUM_EQUALS(set->id, 98);
1238
+ ASSERT_NUM_EQUALS(set->game_id, 26);
1239
+ ASSERT_STR_EQUALS(set->title, "Low Level Run");
1240
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_SPECIALTY);
1241
+ ASSERT_STR_EQUALS(set->image_name, "112236");
1242
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112236.png");
1243
+ ASSERT_NUM_EQUALS(set->num_achievements, 1);
1244
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
1245
+
1246
+ ASSERT_PTR_NOT_NULL(set->achievements);
1247
+ achievement = set->achievements;
1248
+
1249
+ ASSERT_NUM_EQUALS(achievement->id, 5507);
1250
+ ASSERT_STR_EQUALS(achievement->title, "Ach7");
1251
+ ASSERT_STR_EQUALS(achievement->description, "Desc7");
1252
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1253
+ ASSERT_NUM_EQUALS(achievement->points, 5);
1254
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
1255
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1256
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
1257
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD); /* no type specified */
1258
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
1259
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
1260
+
1261
+ set = &fetch_game_sets_response.sets[1];
1262
+ ASSERT_NUM_EQUALS(set->id, 192);
1263
+ ASSERT_NUM_EQUALS(set->game_id, 20);
1264
+ ASSERT_STR_EQUALS(set->title, "Another Amazing Game");
1265
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_CORE);
1266
+ ASSERT_STR_EQUALS(set->image_name, "112233");
1267
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112233.png");
1268
+ ASSERT_NUM_EQUALS(set->num_achievements, 3);
1269
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 1);
1270
+
1271
+ ASSERT_PTR_NOT_NULL(set->achievements);
1272
+ achievement = set->achievements;
1273
+ ASSERT_NUM_EQUALS(achievement->id, 5501);
1274
+ ASSERT_STR_EQUALS(achievement->title, "Ach1");
1275
+ ASSERT_STR_EQUALS(achievement->description, "Desc1");
1276
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1277
+ ASSERT_NUM_EQUALS(achievement->points, 5);
1278
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
1279
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1280
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
1281
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_PROGRESSION);
1282
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
1283
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 66.67f);
1284
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
1285
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
1286
+
1287
+ ++achievement;
1288
+ ASSERT_NUM_EQUALS(achievement->id, 5502);
1289
+ ASSERT_STR_EQUALS(achievement->title, "Ach2");
1290
+ ASSERT_STR_EQUALS(achievement->description, "Desc2");
1291
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1292
+ ASSERT_NUM_EQUALS(achievement->points, 2);
1293
+ ASSERT_STR_EQUALS(achievement->definition, "0=2");
1294
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1295
+ ASSERT_STR_EQUALS(achievement->badge_name, "00235");
1296
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
1297
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 57.43f);
1298
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 57.43f);
1299
+ ASSERT_NUM_EQUALS(achievement->created, 1376970283);
1300
+ ASSERT_NUM_EQUALS(achievement->updated, 1376970283);
1301
+
1302
+ ++achievement;
1303
+ ASSERT_NUM_EQUALS(achievement->id, 5503);
1304
+ ASSERT_STR_EQUALS(achievement->title, "Ach3");
1305
+ ASSERT_STR_EQUALS(achievement->description, "Desc3");
1306
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_UNOFFICIAL);
1307
+ ASSERT_NUM_EQUALS(achievement->points, 0);
1308
+ ASSERT_STR_EQUALS(achievement->definition, "0=3");
1309
+ ASSERT_STR_EQUALS(achievement->author, "User2");
1310
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
1311
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_WIN);
1312
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 6.8f);
1313
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 0.0f);
1314
+ ASSERT_NUM_EQUALS(achievement->created, 1376969412);
1315
+ ASSERT_NUM_EQUALS(achievement->updated, 1376969412);
1316
+
1317
+ ASSERT_PTR_NOT_NULL(set->leaderboards);
1318
+ leaderboard = set->leaderboards;
1319
+
1320
+ ASSERT_NUM_EQUALS(leaderboard->id, 4401);
1321
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard1");
1322
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc1");
1323
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
1324
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SCORE);
1325
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
1326
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 0);
1327
+
1328
+ set = &fetch_game_sets_response.sets[2];
1329
+ ASSERT_NUM_EQUALS(set->id, 77);
1330
+ ASSERT_NUM_EQUALS(set->game_id, 21);
1331
+ ASSERT_STR_EQUALS(set->title, "Bonus");
1332
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_BONUS);
1333
+ ASSERT_STR_EQUALS(set->image_name, "112236");
1334
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112236.png");
1335
+ ASSERT_NUM_EQUALS(set->num_achievements, 3);
1336
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 1);
1337
+
1338
+ ASSERT_PTR_NOT_NULL(set->achievements);
1339
+ achievement = set->achievements;
1340
+ ASSERT_NUM_EQUALS(achievement->id, 5504);
1341
+ ASSERT_STR_EQUALS(achievement->title, "Ach4");
1342
+ ASSERT_STR_EQUALS(achievement->description, "Desc4");
1343
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1344
+ ASSERT_NUM_EQUALS(achievement->points, 10);
1345
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
1346
+ ASSERT_STR_EQUALS(achievement->author, ""); /* null author */
1347
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
1348
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD);
1349
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
1350
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
1351
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
1352
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
1353
+
1354
+ ++achievement;
1355
+ ASSERT_NUM_EQUALS(achievement->id, 5505);
1356
+ ASSERT_STR_EQUALS(achievement->title, "Ach5"); /* [m] stripped */
1357
+ ASSERT_STR_EQUALS(achievement->description, "Desc5");
1358
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1359
+ ASSERT_NUM_EQUALS(achievement->points, 10);
1360
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
1361
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1362
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
1363
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
1364
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
1365
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
1366
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
1367
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
1368
+
1369
+ ++achievement;
1370
+ ASSERT_NUM_EQUALS(achievement->id, 5506);
1371
+ ASSERT_STR_EQUALS(achievement->title, "Ach6"); /* [m] stripped */
1372
+ ASSERT_STR_EQUALS(achievement->description, "Desc6");
1373
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1374
+ ASSERT_NUM_EQUALS(achievement->points, 10);
1375
+ ASSERT_STR_EQUALS(achievement->definition, "0=4");
1376
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1377
+ ASSERT_STR_EQUALS(achievement->badge_name, "00236");
1378
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_MISSABLE);
1379
+ ASSERT_FLOAT_EQUALS(achievement->rarity, 100.0f);
1380
+ ASSERT_FLOAT_EQUALS(achievement->rarity_hardcore, 100.0f);
1381
+ ASSERT_NUM_EQUALS(achievement->created, 1504474554);
1382
+ ASSERT_NUM_EQUALS(achievement->updated, 1504474554);
1383
+
1384
+ ASSERT_PTR_NOT_NULL(set->leaderboards);
1385
+ leaderboard = set->leaderboards;
1386
+
1387
+ ASSERT_NUM_EQUALS(leaderboard->id, 4402);
1388
+ ASSERT_STR_EQUALS(leaderboard->title, "Leaderboard2");
1389
+ ASSERT_STR_EQUALS(leaderboard->description, "Desc2");
1390
+ ASSERT_STR_EQUALS(leaderboard->definition, "0=1");
1391
+ ASSERT_NUM_EQUALS(leaderboard->format, RC_FORMAT_SECONDS);
1392
+ ASSERT_NUM_EQUALS(leaderboard->lower_is_better, 0);
1393
+ ASSERT_NUM_EQUALS(leaderboard->hidden, 1);
1394
+
1395
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1396
+ }
1397
+
1398
+ static void test_process_fetch_game_sets_response_exclusive_subset() {
1399
+ rc_api_achievement_set_definition_t* set;
1400
+ rc_api_achievement_definition_t* achievement;
1401
+ rc_api_fetch_game_sets_response_t fetch_game_sets_response;
1402
+ const char server_response[] = "{\"Success\":true,"
1403
+ "\"GameId\":20,\"Title\":\"Another Amazing Game\",\"ConsoleId\":19,"
1404
+ "\"ImageIconUrl\":\"http://server/Images/112233.png\","
1405
+ "\"RichPresenceGameId\":26,\"RichPresencePatch\":\"\",\"Sets\":[{"
1406
+ "\"AchievementSetId\":98,\"GameId\":26,\"Title\":\"Low Level Run\",\"Type\":\"exclusive\","
1407
+ "\"ImageIconUrl\":\"http://server/Images/112236.png\","
1408
+ "\"Achievements\":["
1409
+ "{\"ID\":5507,\"Title\":\"Ach7\",\"Description\":\"Desc7\",\"Flags\":3,\"Points\":5,"
1410
+ "\"MemAddr\":\"0=1\",\"Author\":\"User1\",\"BadgeName\":\"00234\","
1411
+ "\"Created\":1367266583,\"Modified\":1376929305}"
1412
+ "],\"Leaderboards\":[]"
1413
+ "}]}";
1414
+ rc_api_server_response_t fetch_game_sets_server_response;
1415
+ init_server_response(&fetch_game_sets_server_response, 200, server_response, sizeof(server_response) - 1);
1416
+
1417
+ memset(&fetch_game_sets_response, 0, sizeof(fetch_game_sets_response));
1418
+
1419
+ ASSERT_NUM_EQUALS(rc_api_process_fetch_game_sets_server_response(&fetch_game_sets_response, &fetch_game_sets_server_response), RC_OK);
1420
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.response.succeeded, 1);
1421
+ ASSERT_PTR_NULL(fetch_game_sets_response.response.error_message);
1422
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.id, 20);
1423
+ ASSERT_STR_EQUALS(fetch_game_sets_response.title, "Another Amazing Game");
1424
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.console_id, 19);
1425
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_name, "112233");
1426
+ ASSERT_STR_EQUALS(fetch_game_sets_response.image_url, "http://server/Images/112233.png");
1427
+ ASSERT_STR_EQUALS(fetch_game_sets_response.rich_presence_script, "");
1428
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.session_game_id, 26);
1429
+ ASSERT_NUM_EQUALS(fetch_game_sets_response.num_sets, 1);
1430
+
1431
+ set = &fetch_game_sets_response.sets[0];
1432
+ ASSERT_NUM_EQUALS(set->id, 98);
1433
+ ASSERT_NUM_EQUALS(set->game_id, 26);
1434
+ ASSERT_STR_EQUALS(set->title, "Low Level Run");
1435
+ ASSERT_NUM_EQUALS(set->type, RC_ACHIEVEMENT_SET_TYPE_EXCLUSIVE);
1436
+ ASSERT_STR_EQUALS(set->image_name, "112236");
1437
+ ASSERT_STR_EQUALS(set->image_url, "http://server/Images/112236.png");
1438
+ ASSERT_NUM_EQUALS(set->num_achievements, 1);
1439
+ ASSERT_NUM_EQUALS(set->num_leaderboards, 0);
1440
+
1441
+ ASSERT_PTR_NOT_NULL(set->achievements);
1442
+ achievement = set->achievements;
1443
+
1444
+ ASSERT_NUM_EQUALS(achievement->id, 5507);
1445
+ ASSERT_STR_EQUALS(achievement->title, "Ach7");
1446
+ ASSERT_STR_EQUALS(achievement->description, "Desc7");
1447
+ ASSERT_NUM_EQUALS(achievement->category, RC_ACHIEVEMENT_CATEGORY_CORE);
1448
+ ASSERT_NUM_EQUALS(achievement->points, 5);
1449
+ ASSERT_STR_EQUALS(achievement->definition, "0=1");
1450
+ ASSERT_STR_EQUALS(achievement->author, "User1");
1451
+ ASSERT_STR_EQUALS(achievement->badge_name, "00234");
1452
+ ASSERT_NUM_EQUALS(achievement->type, RC_ACHIEVEMENT_TYPE_STANDARD); /* no type specified */
1453
+ ASSERT_NUM_EQUALS(achievement->created, 1367266583);
1454
+ ASSERT_NUM_EQUALS(achievement->updated, 1376929305);
1455
+
1456
+ rc_api_destroy_fetch_game_sets_response(&fetch_game_sets_response);
1457
+ }
1458
+
1459
+ /* ----- ping ----- */
1460
+
1461
+ static void test_init_ping_request() {
1462
+ rc_api_ping_request_t ping_request;
1463
+ rc_api_request_t request;
1464
+
1465
+ memset(&ping_request, 0, sizeof(ping_request));
1466
+ ping_request.username = "Username";
1467
+ ping_request.api_token = "API_TOKEN";
1468
+ ping_request.game_id = 1234;
1469
+
1470
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1471
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1472
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1234");
1473
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1474
+
1475
+ rc_api_destroy_request(&request);
1476
+ }
1477
+
1478
+ static void test_init_ping_request_no_game_id() {
1479
+ rc_api_ping_request_t ping_request;
1480
+ rc_api_request_t request;
1481
+
1482
+ memset(&ping_request, 0, sizeof(ping_request));
1483
+ ping_request.username = "Username";
1484
+ ping_request.api_token = "API_TOKEN";
1485
+
1486
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_INVALID_STATE);
1487
+
1488
+ rc_api_destroy_request(&request);
1489
+ }
1490
+
1491
+ static void test_init_ping_request_rich_presence() {
1492
+ rc_api_ping_request_t ping_request;
1493
+ rc_api_request_t request;
1494
+
1495
+ memset(&ping_request, 0, sizeof(ping_request));
1496
+ ping_request.username = "Username";
1497
+ ping_request.api_token = "API_TOKEN";
1498
+ ping_request.game_id = 1234;
1499
+ ping_request.rich_presence = "Level 1, 70% complete";
1500
+
1501
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1502
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1503
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1234&m=Level+1%2c+70%25+complete");
1504
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1505
+
1506
+ rc_api_destroy_request(&request);
1507
+ }
1508
+
1509
+ static void test_init_ping_request_rich_presence_unicode() {
1510
+ rc_api_ping_request_t ping_request;
1511
+ rc_api_request_t request;
1512
+
1513
+ memset(&ping_request, 0, sizeof(ping_request));
1514
+ ping_request.username = "Username";
1515
+ ping_request.api_token = "API_TOKEN";
1516
+ ping_request.game_id = 1446;
1517
+ ping_request.rich_presence = "\xf0\x9f\x9a\xb6:3, 1st Quest";
1518
+
1519
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1520
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1521
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1446&m=%f0%9f%9a%b6%3a3%2c+1st+Quest");
1522
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1523
+
1524
+ rc_api_destroy_request(&request);
1525
+ }
1526
+
1527
+ static void test_init_ping_request_rich_presence_empty() {
1528
+ rc_api_ping_request_t ping_request;
1529
+ rc_api_request_t request;
1530
+
1531
+ memset(&ping_request, 0, sizeof(ping_request));
1532
+ ping_request.username = "Username";
1533
+ ping_request.api_token = "API_TOKEN";
1534
+ ping_request.game_id = 1234;
1535
+ ping_request.rich_presence = "";
1536
+
1537
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1538
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1539
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1234");
1540
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1541
+
1542
+ rc_api_destroy_request(&request);
1543
+ }
1544
+
1545
+ static void test_init_ping_request_game_hash_softcore() {
1546
+ rc_api_ping_request_t ping_request;
1547
+ rc_api_request_t request;
1548
+
1549
+ memset(&ping_request, 0, sizeof(ping_request));
1550
+ ping_request.username = "Username";
1551
+ ping_request.api_token = "API_TOKEN";
1552
+ ping_request.game_id = 1234;
1553
+ ping_request.game_hash = "ABCDEF0123456789";
1554
+
1555
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1556
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1557
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1234&h=0&x=ABCDEF0123456789");
1558
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1559
+
1560
+ rc_api_destroy_request(&request);
1561
+ }
1562
+
1563
+ static void test_init_ping_request_game_hash_hardcore() {
1564
+ rc_api_ping_request_t ping_request;
1565
+ rc_api_request_t request;
1566
+
1567
+ memset(&ping_request, 0, sizeof(ping_request));
1568
+ ping_request.username = "Username";
1569
+ ping_request.api_token = "API_TOKEN";
1570
+ ping_request.game_id = 1234;
1571
+ ping_request.hardcore = 1;
1572
+ ping_request.game_hash = "ABCDEF0123456789";
1573
+
1574
+ ASSERT_NUM_EQUALS(rc_api_init_ping_request(&request, &ping_request), RC_OK);
1575
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1576
+ ASSERT_STR_EQUALS(request.post_data, "r=ping&u=Username&t=API_TOKEN&g=1234&h=1&x=ABCDEF0123456789");
1577
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1578
+
1579
+ rc_api_destroy_request(&request);
1580
+ }
1581
+
1582
+ static void test_process_ping_response() {
1583
+ rc_api_ping_response_t ping_response;
1584
+ const char* server_response = "{\"Success\":true}";
1585
+
1586
+ memset(&ping_response, 0, sizeof(ping_response));
1587
+
1588
+ ASSERT_NUM_EQUALS(rc_api_process_ping_response(&ping_response, server_response), RC_OK);
1589
+ ASSERT_NUM_EQUALS(ping_response.response.succeeded, 1);
1590
+ ASSERT_PTR_NULL(ping_response.response.error_message);
1591
+
1592
+ rc_api_destroy_ping_response(&ping_response);
1593
+ }
1594
+
1595
+ /* ----- award achievement ----- */
1596
+
1597
+ static void test_init_award_achievement_request_hardcore() {
1598
+ rc_api_award_achievement_request_t award_achievement_request;
1599
+ rc_api_request_t request;
1600
+
1601
+ memset(&award_achievement_request, 0, sizeof(award_achievement_request));
1602
+ award_achievement_request.username = "Username";
1603
+ award_achievement_request.api_token = "API_TOKEN";
1604
+ award_achievement_request.achievement_id = 1234;
1605
+ award_achievement_request.hardcore = 1;
1606
+ award_achievement_request.game_hash = "ABCDEF0123456789";
1607
+
1608
+ ASSERT_NUM_EQUALS(rc_api_init_award_achievement_request(&request, &award_achievement_request), RC_OK);
1609
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1610
+ ASSERT_STR_EQUALS(request.post_data, "r=awardachievement&u=Username&t=API_TOKEN&a=1234&h=1&m=ABCDEF0123456789&v=b8aefaad6f9659e2164bc60da0c3b64d");
1611
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1612
+
1613
+ rc_api_destroy_request(&request);
1614
+ }
1615
+
1616
+ static void test_init_award_achievement_request_non_hardcore() {
1617
+ rc_api_award_achievement_request_t award_achievement_request;
1618
+ rc_api_request_t request;
1619
+
1620
+ memset(&award_achievement_request, 0, sizeof(award_achievement_request));
1621
+ award_achievement_request.username = "Username";
1622
+ award_achievement_request.api_token = "API_TOKEN";
1623
+ award_achievement_request.achievement_id = 1234;
1624
+ award_achievement_request.hardcore = 0;
1625
+ award_achievement_request.game_hash = "ABABCBCBDEDEFFFF";
1626
+
1627
+ ASSERT_NUM_EQUALS(rc_api_init_award_achievement_request(&request, &award_achievement_request), RC_OK);
1628
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1629
+ ASSERT_STR_EQUALS(request.post_data, "r=awardachievement&u=Username&t=API_TOKEN&a=1234&h=0&m=ABABCBCBDEDEFFFF&v=ed81d6ecf825f8cbe3ae1edace098892");
1630
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1631
+
1632
+ rc_api_destroy_request(&request);
1633
+ }
1634
+
1635
+ static void test_init_award_achievement_request_no_hash() {
1636
+ rc_api_award_achievement_request_t award_achievement_request;
1637
+ rc_api_request_t request;
1638
+
1639
+ memset(&award_achievement_request, 0, sizeof(award_achievement_request));
1640
+ award_achievement_request.username = "Username";
1641
+ award_achievement_request.api_token = "API_TOKEN";
1642
+ award_achievement_request.achievement_id = 5432;
1643
+ award_achievement_request.hardcore = 1;
1644
+
1645
+ ASSERT_NUM_EQUALS(rc_api_init_award_achievement_request(&request, &award_achievement_request), RC_OK);
1646
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1647
+ ASSERT_STR_EQUALS(request.post_data, "r=awardachievement&u=Username&t=API_TOKEN&a=5432&h=1&v=31048257ab1788386e71ab0c222aa5c8");
1648
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1649
+
1650
+ rc_api_destroy_request(&request);
1651
+ }
1652
+
1653
+ static void test_init_award_achievement_request_no_achievement_id() {
1654
+ rc_api_award_achievement_request_t award_achievement_request;
1655
+ rc_api_request_t request;
1656
+
1657
+ memset(&award_achievement_request, 0, sizeof(award_achievement_request));
1658
+ award_achievement_request.username = "Username";
1659
+ award_achievement_request.api_token = "API_TOKEN";
1660
+ award_achievement_request.hardcore = 1;
1661
+ award_achievement_request.game_hash = "ABABCBCBDEDEFFFF";
1662
+
1663
+ ASSERT_NUM_EQUALS(rc_api_init_award_achievement_request(&request, &award_achievement_request), RC_INVALID_STATE);
1664
+
1665
+ rc_api_destroy_request(&request);
1666
+ }
1667
+
1668
+ static void test_init_award_achievement_request_delayed() {
1669
+ rc_api_award_achievement_request_t award_achievement_request;
1670
+ rc_api_request_t request;
1671
+
1672
+ memset(&award_achievement_request, 0, sizeof(award_achievement_request));
1673
+ award_achievement_request.username = "Username";
1674
+ award_achievement_request.api_token = "API_TOKEN";
1675
+ award_achievement_request.achievement_id = 1234;
1676
+ award_achievement_request.hardcore = 1;
1677
+ award_achievement_request.game_hash = "ABCDEF0123456789";
1678
+ award_achievement_request.seconds_since_unlock = 17;
1679
+
1680
+ ASSERT_NUM_EQUALS(rc_api_init_award_achievement_request(&request, &award_achievement_request), RC_OK);
1681
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1682
+ ASSERT_STR_EQUALS(request.post_data, "r=awardachievement&u=Username&t=API_TOKEN&a=1234&h=1&m=ABCDEF0123456789&o=17&v=b2326b09d61e9264eb5d3607d947317d");
1683
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1684
+
1685
+ rc_api_destroy_request(&request);
1686
+ }
1687
+
1688
+ static void test_process_award_achievement_response_success() {
1689
+ rc_api_award_achievement_response_t award_achievement_response;
1690
+ const char* server_response = "{\"Success\":true,\"Score\":119102,\"SoftcoreScore\":777,\"AchievementID\":56481,\"AchievementsRemaining\":11}";
1691
+
1692
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1693
+
1694
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1695
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 1);
1696
+ ASSERT_PTR_NULL(award_achievement_response.response.error_message);
1697
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 119102);
1698
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 777);
1699
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 56481);
1700
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 11);
1701
+
1702
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1703
+ }
1704
+
1705
+ static void test_process_award_achievement_response_hardcore_already_unlocked() {
1706
+ rc_api_award_achievement_response_t award_achievement_response;
1707
+ const char* server_response = "{\"Success\":false,\"Error\":\"User already has hardcore and regular achievements awarded.\",\"Score\":119210,\"SoftcoreScore\":777,\"AchievementID\":56494,\"AchievementsRemaining\":17}";
1708
+
1709
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1710
+
1711
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1712
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 1);
1713
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "User already has hardcore and regular achievements awarded.");
1714
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 119210);
1715
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 777);
1716
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 56494);
1717
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 17);
1718
+
1719
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1720
+ }
1721
+
1722
+ static void test_process_award_achievement_response_non_hardcore_already_unlocked() {
1723
+ rc_api_award_achievement_response_t award_achievement_response;
1724
+ const char* server_response = "{\"Success\":false,\"Error\":\"User already has this achievement awarded.\",\"Score\":119210,\"SoftcoreScore\":777,\"AchievementID\":56494}";
1725
+
1726
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1727
+
1728
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1729
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 1);
1730
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "User already has this achievement awarded.");
1731
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 119210);
1732
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 777);
1733
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 56494);
1734
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0xFFFFFFFF);
1735
+
1736
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1737
+ }
1738
+
1739
+ static void test_process_award_achievement_response_generic_failure() {
1740
+ rc_api_award_achievement_response_t award_achievement_response;
1741
+ const char* server_response = "{\"Success\":false}";
1742
+
1743
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1744
+
1745
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1746
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1747
+ ASSERT_PTR_NULL(award_achievement_response.response.error_message);
1748
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1749
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1750
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1751
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1752
+
1753
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1754
+ }
1755
+
1756
+ static void test_process_award_achievement_response_empty() {
1757
+ rc_api_award_achievement_response_t award_achievement_response;
1758
+ const char* server_response = "";
1759
+
1760
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1761
+
1762
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_NO_RESPONSE);
1763
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1764
+ ASSERT_PTR_NULL(award_achievement_response.response.error_message);
1765
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1766
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1767
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1768
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1769
+
1770
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1771
+ }
1772
+
1773
+ static void test_process_award_achievement_response_invalid_credentials() {
1774
+ rc_api_award_achievement_response_t award_achievement_response;
1775
+ const char* server_response = "{\"Success\":false,\"Error\":\"Credentials invalid (0)\"}";
1776
+
1777
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1778
+
1779
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1780
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1781
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "Credentials invalid (0)");
1782
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1783
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1784
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1785
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1786
+
1787
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1788
+ }
1789
+
1790
+ static void test_process_award_achievement_response_text() {
1791
+ rc_api_award_achievement_response_t award_achievement_response;
1792
+ const char* server_response = "You do not have access to that resource";
1793
+
1794
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1795
+
1796
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_INVALID_JSON);
1797
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1798
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "You do not have access to that resource");
1799
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1800
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1801
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1802
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1803
+
1804
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1805
+ }
1806
+
1807
+ static void test_process_award_achievement_response_no_fields() {
1808
+ rc_api_award_achievement_response_t award_achievement_response;
1809
+ const char* server_response = "{\"Success\":true}";
1810
+
1811
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1812
+
1813
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1814
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 1);
1815
+ ASSERT_PTR_NULL(award_achievement_response.response.error_message);
1816
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1817
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1818
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1819
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0xFFFFFFFF);
1820
+
1821
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1822
+ }
1823
+
1824
+ static void test_process_award_achievement_response_429() {
1825
+ rc_api_award_achievement_response_t award_achievement_response;
1826
+ const char* server_response =
1827
+ "<html>\n"
1828
+ "<head><title>429 Too Many Requests</title></head>\n"
1829
+ "<body>\n"
1830
+ "<center><h1>429 Too Many Requests</h1></center>\n"
1831
+ "<hr><center>nginx</center>\n"
1832
+ "</body>\n"
1833
+ "</html>";
1834
+
1835
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1836
+
1837
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_INVALID_JSON);
1838
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1839
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "429 Too Many Requests");
1840
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1841
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1842
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1843
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1844
+
1845
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1846
+ }
1847
+
1848
+ static void test_process_award_achievement_response_429_json() {
1849
+ rc_api_award_achievement_response_t award_achievement_response;
1850
+ const char* server_response =
1851
+ "{\"Success\": false,\"Error\":\"Too Many Attempts\"}";
1852
+
1853
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1854
+
1855
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_OK);
1856
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1857
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "Too Many Attempts");
1858
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1859
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1860
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1861
+
1862
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1863
+ }
1864
+
1865
+ static void test_process_award_achievement_response_503_fancy() {
1866
+ rc_api_award_achievement_response_t award_achievement_response;
1867
+ const char* server_response =
1868
+ "<!DOCTYPE html>\n"
1869
+ "<html>\n"
1870
+ "<head>\n"
1871
+ " <meta charset='utf-8'>\n"
1872
+ " <meta name='viewport' content='width=device-width, initial-scale=1'>\n"
1873
+ " <style>\n"
1874
+ " body {\n"
1875
+ " background-color: #1a1a1a;\n"
1876
+ " color: white; width: 100%;\n"
1877
+ " }\n"
1878
+ " a {\n"
1879
+ " color: #cc9900;\n"
1880
+ " text-decoration: none;\n"
1881
+ " }\n"
1882
+ " .center {\n"
1883
+ " margin: 0;\n"
1884
+ " padding: 0;\n"
1885
+ " text - align: center;\n"
1886
+ " position: absolute;\n"
1887
+ " top: 50%;\n"
1888
+ " left: 50%;\n"
1889
+ " transform: translateX(-50%) translateY(-50%);\n"
1890
+ " }\n"
1891
+ " </style>\n"
1892
+ " <title>503 Service Temporarily Unavailable</title>\n"
1893
+ "</head>\n"
1894
+ "<body style='background-color: #1a1a1a; color:white; width:100%;'>\n"
1895
+ "<div class='center'>\n"
1896
+ " <img style='text-align: center; width: 75%;' src = 'https://static.retroachievements.org/assets/images/ra-logo-sm.webp'>\n"
1897
+ " <h1>503</h1>\n"
1898
+ " <h2>Service Temporarily Unavailable</h2>\n"
1899
+ " <img src='https://static.retroachievements.org/assets/images/cheevo/sad.webp' alt='Sad Cheevo'>\n"
1900
+ " <p>The RetroAchievements website is currently offline, we apologize for any inconvenience caused.</p>\n"
1901
+ " <p><strong><u>You can still earn achievements in any supported emulator.</u></strong></p>\n"
1902
+ " <p><strong>Make sure that the emulator has informed you that you have successfully logged in before you begin playing to avoid missing unlocks.</strong></p>\n"
1903
+ " <p>For more information and updates, please join our <a href='https://discord.gg/retroachievements'>Discord</a>.</p>\n"
1904
+ " <br/>\n"
1905
+ " <a href='https://retroachievements.org'>retroachievements.org</a>\n"
1906
+ "</div>\n"
1907
+ "</body>\n"
1908
+ "</html>";
1909
+
1910
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1911
+
1912
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_INVALID_JSON);
1913
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1914
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "503 Service Temporarily Unavailable");
1915
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1916
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1917
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1918
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1919
+
1920
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1921
+ }
1922
+
1923
+ static void test_process_award_achievement_response_522_simple() {
1924
+ rc_api_award_achievement_response_t award_achievement_response;
1925
+ const char* server_response = "error code: 522";
1926
+
1927
+ memset(&award_achievement_response, 0, sizeof(award_achievement_response));
1928
+
1929
+ ASSERT_NUM_EQUALS(rc_api_process_award_achievement_response(&award_achievement_response, server_response), RC_INVALID_JSON);
1930
+ ASSERT_NUM_EQUALS(award_achievement_response.response.succeeded, 0);
1931
+ ASSERT_STR_EQUALS(award_achievement_response.response.error_message, "error code: 522");
1932
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score, 0);
1933
+ ASSERT_UNUM_EQUALS(award_achievement_response.new_player_score_softcore, 0);
1934
+ ASSERT_UNUM_EQUALS(award_achievement_response.awarded_achievement_id, 0);
1935
+ ASSERT_UNUM_EQUALS(award_achievement_response.achievements_remaining, 0);
1936
+
1937
+ rc_api_destroy_award_achievement_response(&award_achievement_response);
1938
+ }
1939
+
1940
+ /* ----- submit lboard entry ----- */
1941
+
1942
+ static void test_init_submit_lboard_entry_request() {
1943
+ rc_api_submit_lboard_entry_request_t submit_lboard_entry_request;
1944
+ rc_api_request_t request;
1945
+
1946
+ memset(&submit_lboard_entry_request, 0, sizeof(submit_lboard_entry_request));
1947
+ submit_lboard_entry_request.username = "Username";
1948
+ submit_lboard_entry_request.api_token = "API_TOKEN";
1949
+ submit_lboard_entry_request.leaderboard_id = 1234;
1950
+ submit_lboard_entry_request.score = 10999;
1951
+ submit_lboard_entry_request.game_hash = "ABCDEF0123456789";
1952
+
1953
+ ASSERT_NUM_EQUALS(rc_api_init_submit_lboard_entry_request(&request, &submit_lboard_entry_request), RC_OK);
1954
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1955
+ ASSERT_STR_EQUALS(request.post_data, "r=submitlbentry&u=Username&t=API_TOKEN&i=1234&s=10999&m=ABCDEF0123456789&v=e13c9132ee651256f9d2ee8f06f75d76");
1956
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1957
+
1958
+ rc_api_destroy_request(&request);
1959
+ }
1960
+
1961
+ static void test_init_submit_lboard_entry_request_zero_value() {
1962
+ rc_api_submit_lboard_entry_request_t submit_lboard_entry_request;
1963
+ rc_api_request_t request;
1964
+
1965
+ memset(&submit_lboard_entry_request, 0, sizeof(submit_lboard_entry_request));
1966
+ submit_lboard_entry_request.username = "Username";
1967
+ submit_lboard_entry_request.api_token = "API_TOKEN";
1968
+ submit_lboard_entry_request.leaderboard_id = 1111;
1969
+ submit_lboard_entry_request.score = 0;
1970
+ submit_lboard_entry_request.game_hash = "ABCDEF0123456789";
1971
+
1972
+ ASSERT_NUM_EQUALS(rc_api_init_submit_lboard_entry_request(&request, &submit_lboard_entry_request), RC_OK);
1973
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1974
+ ASSERT_STR_EQUALS(request.post_data, "r=submitlbentry&u=Username&t=API_TOKEN&i=1111&s=0&m=ABCDEF0123456789&v=9c2ac665157d68b8a26e83bb71dd8aaf");
1975
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1976
+
1977
+ rc_api_destroy_request(&request);
1978
+ }
1979
+
1980
+ static void test_init_submit_lboard_entry_request_negative_value() {
1981
+ rc_api_submit_lboard_entry_request_t submit_lboard_entry_request;
1982
+ rc_api_request_t request;
1983
+
1984
+ memset(&submit_lboard_entry_request, 0, sizeof(submit_lboard_entry_request));
1985
+ submit_lboard_entry_request.username = "Username";
1986
+ submit_lboard_entry_request.api_token = "API_TOKEN";
1987
+ submit_lboard_entry_request.leaderboard_id = 1111;
1988
+ submit_lboard_entry_request.score = -234781;
1989
+ submit_lboard_entry_request.game_hash = "ABCDEF0123456789";
1990
+
1991
+ ASSERT_NUM_EQUALS(rc_api_init_submit_lboard_entry_request(&request, &submit_lboard_entry_request), RC_OK);
1992
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
1993
+ ASSERT_STR_EQUALS(request.post_data, "r=submitlbentry&u=Username&t=API_TOKEN&i=1111&s=-234781&m=ABCDEF0123456789&v=fbe290266f2d121a7a37942e1e90f453");
1994
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
1995
+
1996
+ rc_api_destroy_request(&request);
1997
+ }
1998
+
1999
+ static void test_init_submit_lboard_entry_request_no_leaderboard_id() {
2000
+ rc_api_submit_lboard_entry_request_t submit_lboard_entry_request;
2001
+ rc_api_request_t request;
2002
+
2003
+ memset(&submit_lboard_entry_request, 0, sizeof(submit_lboard_entry_request));
2004
+ submit_lboard_entry_request.username = "Username";
2005
+ submit_lboard_entry_request.api_token = "API_TOKEN";
2006
+ submit_lboard_entry_request.score = 12345;
2007
+ submit_lboard_entry_request.game_hash = "ABCDEF0123456789";
2008
+
2009
+ ASSERT_NUM_EQUALS(rc_api_init_submit_lboard_entry_request(&request, &submit_lboard_entry_request), RC_INVALID_STATE);
2010
+
2011
+ rc_api_destroy_request(&request);
2012
+ }
2013
+
2014
+ static void test_init_submit_lboard_entry_request_delayed() {
2015
+ rc_api_submit_lboard_entry_request_t submit_lboard_entry_request;
2016
+ rc_api_request_t request;
2017
+
2018
+ memset(&submit_lboard_entry_request, 0, sizeof(submit_lboard_entry_request));
2019
+ submit_lboard_entry_request.username = "Username";
2020
+ submit_lboard_entry_request.api_token = "API_TOKEN";
2021
+ submit_lboard_entry_request.leaderboard_id = 1234;
2022
+ submit_lboard_entry_request.score = 10999;
2023
+ submit_lboard_entry_request.game_hash = "ABCDEF0123456789";
2024
+ submit_lboard_entry_request.seconds_since_completion = 33;
2025
+
2026
+ ASSERT_NUM_EQUALS(rc_api_init_submit_lboard_entry_request(&request, &submit_lboard_entry_request), RC_OK);
2027
+ ASSERT_STR_EQUALS(request.url, DOREQUEST_URL);
2028
+ ASSERT_STR_EQUALS(request.post_data, "r=submitlbentry&u=Username&t=API_TOKEN&i=1234&s=10999&m=ABCDEF0123456789&o=33&v=7971fc37cf38026f99dd4bae84360ac1");
2029
+ ASSERT_STR_EQUALS(request.content_type, RC_CONTENT_TYPE_URLENCODED);
2030
+
2031
+ rc_api_destroy_request(&request);
2032
+ }
2033
+
2034
+ static void test_process_submit_lb_entry_response_success() {
2035
+ rc_api_submit_lboard_entry_response_t submit_lb_entry_response;
2036
+ rc_api_lboard_entry_t* entry;
2037
+ const char* server_response = "{\"Success\":true,\"Response\":{\"Score\":1234,\"BestScore\":2345,"
2038
+ "\"TopEntries\":[{\"User\":\"Player1\",\"Score\":8765,\"Rank\":1},{\"User\":\"Player2\",\"Score\":7654,\"Rank\":2}],"
2039
+ "\"RankInfo\":{\"Rank\":5,\"NumEntries\":\"17\"}}}";
2040
+
2041
+ memset(&submit_lb_entry_response, 0, sizeof(submit_lb_entry_response));
2042
+
2043
+ ASSERT_NUM_EQUALS(rc_api_process_submit_lboard_entry_response(&submit_lb_entry_response, server_response), RC_OK);
2044
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.response.succeeded, 1);
2045
+ ASSERT_PTR_NULL(submit_lb_entry_response.response.error_message);
2046
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.submitted_score, 1234);
2047
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.best_score, 2345);
2048
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.new_rank, 5);
2049
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_entries, 17);
2050
+
2051
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_top_entries, 2);
2052
+ entry = &submit_lb_entry_response.top_entries[0];
2053
+ ASSERT_NUM_EQUALS(entry->rank, 1);
2054
+ ASSERT_STR_EQUALS(entry->username, "Player1");
2055
+ ASSERT_NUM_EQUALS(entry->score, 8765);
2056
+ entry = &submit_lb_entry_response.top_entries[1];
2057
+ ASSERT_NUM_EQUALS(entry->rank, 2);
2058
+ ASSERT_STR_EQUALS(entry->username, "Player2");
2059
+ ASSERT_NUM_EQUALS(entry->score, 7654);
2060
+
2061
+ rc_api_destroy_submit_lboard_entry_response(&submit_lb_entry_response);
2062
+ }
2063
+
2064
+ static void test_process_submit_lb_entry_response_no_entries() {
2065
+ rc_api_submit_lboard_entry_response_t submit_lb_entry_response;
2066
+ const char* server_response = "{\"Success\":true,\"Response\":{\"Score\":1234,\"BestScore\":2345,"
2067
+ "\"TopEntries\":[],"
2068
+ "\"RankInfo\":{\"Rank\":5,\"NumEntries\":\"17\"}}}";
2069
+
2070
+ memset(&submit_lb_entry_response, 0, sizeof(submit_lb_entry_response));
2071
+
2072
+ ASSERT_NUM_EQUALS(rc_api_process_submit_lboard_entry_response(&submit_lb_entry_response, server_response), RC_OK);
2073
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.response.succeeded, 1);
2074
+ ASSERT_PTR_NULL(submit_lb_entry_response.response.error_message);
2075
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.submitted_score, 1234);
2076
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.best_score, 2345);
2077
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.new_rank, 5);
2078
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_entries, 17);
2079
+
2080
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_top_entries, 0);
2081
+ ASSERT_PTR_NULL(submit_lb_entry_response.top_entries);
2082
+
2083
+ rc_api_destroy_submit_lboard_entry_response(&submit_lb_entry_response);
2084
+ }
2085
+
2086
+ static void test_process_submit_lb_entry_response_invalid_credentials() {
2087
+ rc_api_submit_lboard_entry_response_t submit_lb_entry_response;
2088
+ const char* server_response = "{\"Success\":false,\"Error\":\"Credentials invalid (0)\"}";
2089
+
2090
+ memset(&submit_lb_entry_response, 0, sizeof(submit_lb_entry_response));
2091
+
2092
+ ASSERT_NUM_EQUALS(rc_api_process_submit_lboard_entry_response(&submit_lb_entry_response, server_response), RC_OK);
2093
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.response.succeeded, 0);
2094
+ ASSERT_STR_EQUALS(submit_lb_entry_response.response.error_message, "Credentials invalid (0)");
2095
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.submitted_score, 0);
2096
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.best_score, 0);
2097
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.new_rank, 0);
2098
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_entries, 0);
2099
+
2100
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.num_top_entries, 0);
2101
+ ASSERT_PTR_NULL(submit_lb_entry_response.top_entries);
2102
+
2103
+ rc_api_destroy_submit_lboard_entry_response(&submit_lb_entry_response);
2104
+ }
2105
+
2106
+ static void test_process_submit_lb_entry_response_entries_not_array() {
2107
+ rc_api_submit_lboard_entry_response_t submit_lb_entry_response;
2108
+ const char* server_response = "{\"Success\":true,\"Response\":{\"Score\":1234,\"BestScore\":2345,"
2109
+ "\"TopEntries\":{\"User\":\"Player1\",\"Score\":8765,\"Rank\":1},"
2110
+ "\"RankInfo\":{\"Rank\":5,\"NumEntries\":\"17\"}}}";
2111
+
2112
+ memset(&submit_lb_entry_response, 0, sizeof(submit_lb_entry_response));
2113
+
2114
+ ASSERT_NUM_EQUALS(rc_api_process_submit_lboard_entry_response(&submit_lb_entry_response, server_response), RC_MISSING_VALUE);
2115
+ ASSERT_NUM_EQUALS(submit_lb_entry_response.response.succeeded, 0);
2116
+ ASSERT_STR_EQUALS(submit_lb_entry_response.response.error_message, "TopEntries not found in response");
2117
+
2118
+ rc_api_destroy_submit_lboard_entry_response(&submit_lb_entry_response);
2119
+ }
2120
+
2121
+ /* ----- harness ----- */
2122
+
2123
+ void test_rapi_runtime(void) {
2124
+ TEST_SUITE_BEGIN();
2125
+
2126
+ /* gameid */
2127
+ TEST(test_init_resolve_hash_request);
2128
+ TEST(test_init_resolve_hash_request_no_credentials);
2129
+ TEST(test_init_resolve_hash_request_no_hash);
2130
+ TEST(test_init_resolve_hash_request_empty_hash);
2131
+
2132
+ TEST(test_process_resolve_hash_response_match);
2133
+ TEST(test_process_resolve_hash_response_no_match);
2134
+
2135
+ /* patch */
2136
+ TEST(test_init_fetch_game_data_request);
2137
+ TEST(test_init_fetch_game_data_request_no_id);
2138
+ TEST(test_init_fetch_game_data_request_by_hash);
2139
+ TEST(test_init_fetch_game_data_request_by_id_and_hash);
2140
+
2141
+ TEST(test_process_fetch_game_data_response_empty);
2142
+ TEST(test_process_fetch_game_data_response_invalid_credentials);
2143
+ TEST(test_process_fetch_game_data_response_not_found);
2144
+ TEST(test_process_fetch_game_data_response_achievements);
2145
+ TEST(test_process_fetch_game_data_response_achievement_types);
2146
+ TEST(test_process_fetch_game_data_response_achievement_rarity);
2147
+ TEST(test_process_fetch_game_data_response_achievement_null_author);
2148
+ TEST(test_process_fetch_game_data_response_leaderboards);
2149
+ TEST(test_process_fetch_game_data_response_rich_presence);
2150
+ TEST(test_process_fetch_game_data_response_rich_presence_null);
2151
+ TEST(test_process_fetch_game_data_response_rich_presence_tab);
2152
+
2153
+ /* hashdata */
2154
+ TEST(test_init_fetch_game_sets_request);
2155
+ TEST(test_init_fetch_game_sets_request_no_hash);
2156
+ TEST(test_init_fetch_game_sets_request_by_id);
2157
+ TEST(test_init_fetch_game_sets_request_by_hash_and_id);
2158
+
2159
+ TEST(test_process_fetch_game_sets_response_empty);
2160
+ TEST(test_process_fetch_game_sets_response_invalid_credentials);
2161
+ TEST(test_process_fetch_game_sets_response_not_found);
2162
+ TEST(test_process_fetch_game_sets_response_achievements);
2163
+ TEST(test_process_fetch_game_sets_response_leaderboards);
2164
+ TEST(test_process_fetch_game_sets_response_rich_presence);
2165
+ TEST(test_process_fetch_game_sets_response_rich_presence_null);
2166
+ TEST(test_process_fetch_game_sets_response_specialty_subset);
2167
+ TEST(test_process_fetch_game_sets_response_exclusive_subset);
2168
+
2169
+ /* ping */
2170
+ TEST(test_init_ping_request);
2171
+ TEST(test_init_ping_request_no_game_id);
2172
+ TEST(test_init_ping_request_rich_presence);
2173
+ TEST(test_init_ping_request_rich_presence_unicode);
2174
+ TEST(test_init_ping_request_rich_presence_empty);
2175
+ TEST(test_init_ping_request_game_hash_softcore);
2176
+ TEST(test_init_ping_request_game_hash_hardcore);
2177
+
2178
+ TEST(test_process_ping_response);
2179
+
2180
+ /* awardachievement */
2181
+ TEST(test_init_award_achievement_request_hardcore);
2182
+ TEST(test_init_award_achievement_request_non_hardcore);
2183
+ TEST(test_init_award_achievement_request_no_hash);
2184
+ TEST(test_init_award_achievement_request_no_achievement_id);
2185
+ TEST(test_init_award_achievement_request_delayed);
2186
+
2187
+ TEST(test_process_award_achievement_response_success);
2188
+ TEST(test_process_award_achievement_response_hardcore_already_unlocked);
2189
+ TEST(test_process_award_achievement_response_non_hardcore_already_unlocked);
2190
+ TEST(test_process_award_achievement_response_generic_failure);
2191
+ TEST(test_process_award_achievement_response_empty);
2192
+ TEST(test_process_award_achievement_response_invalid_credentials);
2193
+ TEST(test_process_award_achievement_response_text);
2194
+ TEST(test_process_award_achievement_response_no_fields);
2195
+ TEST(test_process_award_achievement_response_429);
2196
+ TEST(test_process_award_achievement_response_429_json);
2197
+ TEST(test_process_award_achievement_response_503_fancy);
2198
+ TEST(test_process_award_achievement_response_522_simple);
2199
+
2200
+ /* submitlbentry */
2201
+ TEST(test_init_submit_lboard_entry_request);
2202
+ TEST(test_init_submit_lboard_entry_request_zero_value);
2203
+ TEST(test_init_submit_lboard_entry_request_negative_value);
2204
+ TEST(test_init_submit_lboard_entry_request_no_leaderboard_id);
2205
+ TEST(test_init_submit_lboard_entry_request_delayed);
2206
+
2207
+ TEST(test_process_submit_lb_entry_response_success);
2208
+ TEST(test_process_submit_lb_entry_response_no_entries);
2209
+ TEST(test_process_submit_lb_entry_response_invalid_credentials);
2210
+ TEST(test_process_submit_lb_entry_response_entries_not_array);
2211
+
2212
+ TEST_SUITE_END();
2213
+ }