# frozen_string_literal: true require "test_helper" class WiseItemsControllerTest < ActionDispatch::IntegrationTest setup do sign_in users(:family_admin) SyncJob.stubs(:perform_later) @family = families(:dylan_family) @wise_item = wise_items(:one) @valid_profiles = [ { "id" => "99999999", "type" => "personal", "details" => { "firstName" => "Jane", "lastName" => "Doe" } } ] end # create redirects to select_profiles (Turbo requires a redirect from a standard # form submission) — the encrypted token travels via the session, not the response body. test "create redirects to select_profiles and keeps raw token out of the session" do Provider::Wise.any_instance.stubs(:get_profiles).returns(@valid_profiles) post wise_items_url, params: { wise_item: { token: "live_token_abc" } } assert_redirected_to select_profiles_wise_items_path assert_nil session[:wise_pending_token], "raw API token must not be stored in the session" assert session[:wise_pending_encrypted_token].present? follow_redirect! assert_select "input[name='encrypted_pending_token']" end test "create stores an encrypted token that round-trips to the original value" do Provider::Wise.any_instance.stubs(:get_profiles).returns(@valid_profiles) post wise_items_url, params: { wise_item: { token: "live_token_abc" } } follow_redirect! encrypted = css_select("input[name='encrypted_pending_token']").first["value"] assert encrypted.present?, "hidden encrypted_pending_token field must be present" key = Rails.application.key_generator.generate_key("wise_pending_token", 32) decrypted = ActiveSupport::MessageEncryptor.new(key).decrypt_and_verify(encrypted) assert_equal "live_token_abc", decrypted end test "create redirects to providers on blank token" do post wise_items_url, params: { wise_item: { token: "" } } assert_redirected_to settings_providers_path assert_nil session[:wise_pending_token] end test "create redirects to providers when Wise API rejects the token" do Provider::Wise.any_instance.stubs(:get_profiles).raises( Provider::Wise::WiseError.new("unauthorized", :unauthorized) ) post wise_items_url, params: { wise_item: { token: "bad_token" } } assert_redirected_to settings_providers_path assert_nil session[:wise_pending_token] end # link_profiles reads the encrypted token from the session (set by create) — # the client no longer needs to (and cannot) supply or tamper with it via params. test "link_profiles creates WiseItems using the session-held encrypted token" do Provider::Wise.any_instance.stubs(:get_profiles).returns(@valid_profiles) post wise_items_url, params: { wise_item: { token: "live_token_abc" } } assert_difference "WiseItem.count", 1 do post link_profiles_wise_items_url, params: { profile_ids: [ "99999999" ] } end assert_redirected_to settings_providers_path assert_equal "live_token_abc", @family.wise_items.find_by!(profile_id: "99999999").token assert_nil session[:wise_pending_profiles] assert_nil session[:wise_pending_encrypted_token] end test "link_profiles redirects to providers when there is no pending session" do post link_profiles_wise_items_url, params: { profile_ids: [ "99999999" ] } assert_redirected_to settings_providers_path end test "link_profiles redirects to providers when the session token cannot be decrypted" do Provider::Wise.any_instance.stubs(:get_profiles).returns(@valid_profiles) post wise_items_url, params: { wise_item: { token: "live_token_abc" } } session[:wise_pending_encrypted_token] = "corrupted_garbage_value" post link_profiles_wise_items_url, params: { profile_ids: [ "99999999" ] } assert_redirected_to settings_providers_path end end