Add Stripe donation flow

This commit is contained in:
hz
2026-07-19 22:26:33 -05:00
parent f12904bf73
commit dec5e74aa7
30 changed files with 1053 additions and 1 deletions
+21
View File
@@ -0,0 +1,21 @@
extends SceneTree
const DonationAmount := preload("res://scripts/ui/donation_amount.gd")
var failures := 0
func _initialize() -> void:
_assert(DonationAmount.parse_cents("5") == 500, "whole dollars should parse")
_assert(DonationAmount.parse_cents("$25.50") == 2550, "dollars and cents should parse")
_assert(DonationAmount.parse_cents("4.999") == -1, "more than two decimal places should fail")
_assert(DonationAmount.parse_cents("10000.01") == -1, "amounts above the cap should fail")
_assert(DonationAmount.parse_cents("abc") == -1, "non-numeric values should fail")
quit(1 if failures > 0 else 0)
func _assert(condition: bool, message: String) -> void:
if condition:
return
failures += 1
push_error(message)
+1
View File
@@ -0,0 +1 @@
uid://d0ik8fhaa2u8w
+47
View File
@@ -0,0 +1,47 @@
extends SceneTree
var failures := 0
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var theme_service = root.get_node("UIThemeService")
var prior_dark_mode: bool = theme_service.is_dark_mode()
var host := Control.new()
host.size = Vector2(1280, 800)
root.add_child(host)
var screen = load("res://scripts/ui/donation_screen.gd").new()
screen.size = host.size
host.add_child(screen)
await process_frame
_assert(screen.content_grid.columns == 2, "wide donation layouts should use two columns")
_assert(screen.selected_amount_cents == 2500, "the default preset should be $25")
_assert(screen.donate_button.text.contains("$25.00"), "the donation action should state the selected amount")
screen.size = Vector2(760, 800)
screen._update_layout()
_assert(screen.content_grid.columns == 1, "narrow donation layouts should stack")
screen.size = Vector2(360, 800)
screen._update_layout()
_assert(screen.preset_grid.columns == 2, "phone donation layouts should use a two-column amount grid")
screen.custom_amount.text = "4"
screen._on_custom_amount_changed("4")
await process_frame
_assert(screen.donate_button.disabled, "amounts below $5 should disable checkout")
theme_service.set_dark_mode(false)
await process_frame
var light_box := screen.mission_panel.get_theme_stylebox("panel") as StyleBoxFlat
_assert(light_box.bg_color.is_equal_approx(Color.WHITE), "donation cards should use light surfaces in light mode")
host.queue_free()
await process_frame
theme_service.set_dark_mode(prior_dark_mode)
quit(1 if failures > 0 else 0)
func _assert(condition: bool, message: String) -> void:
if condition:
return
failures += 1
push_error(message)
+1
View File
@@ -0,0 +1 @@
uid://cfg0oxxrtumdj
+1
View File
@@ -19,6 +19,7 @@ func _initialize() -> void:
_assert(NavigationRoutes.key_for_screen("settings") == "settings", "settings should activate Settings")
_assert(NavigationRoutes.key_for_screen("notes") == "notes", "notes should activate Notes")
_assert(NavigationRoutes.key_for_screen("bookmarks") == "bookmarks", "bookmarks should activate Bookmarks")
_assert(NavigationRoutes.key_for_screen("donations") == "donations", "donations should activate Support MedMind")
quit(1 if failures > 0 else 0)
+2
View File
@@ -74,6 +74,8 @@ func _run() -> void:
_assert(main_screen.sidebar.find_child("NavPractice", true, false) == null, "the sidebar should not retain a Practice navigation item")
var profile_nav := main_screen.sidebar.find_child("NavPerformance", true, false) as Button
var settings_nav := main_screen.sidebar.find_child("NavSettings", true, false) as Button
var donation_nav := main_screen.sidebar.find_child("NavDonations", true, false) as Button
_assert(donation_nav != null and donation_nav.text == "Support MedMind", "the shell should expose donation navigation")
_assert(profile_nav != null and settings_nav != null and profile_nav.get_index() + 1 == settings_nav.get_index(), "Profile should sit directly above Settings in the lower navigation group")
var theme_service = root.get_node("UIThemeService")
var prior_dark_mode: bool = theme_service.is_dark_mode()