From 501c434fbaa07544f3dbb6b5c5ff81aa3afa96ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mugnolo?= Date: Thu, 11 Jun 2026 21:01:51 -0300 Subject: [PATCH] Add missing legal consent model for marketing forms --- ...ent_options_implicit_consent_to_process.rb | 111 ++++++++++++++++++ .../forms/hub_spot_form_definition_spec.rb | 25 ++++ 2 files changed, 136 insertions(+) create mode 100644 lib/hubspot/codegen/marketing/forms/models/one_of_legal_consent_options_none_legal_consent_options_legitimate_interest_legal_consent_options_explicit_consent_to_process_legal_consent_options_implicit_consent_to_process.rb create mode 100644 spec/discovery/marketing/forms/hub_spot_form_definition_spec.rb diff --git a/lib/hubspot/codegen/marketing/forms/models/one_of_legal_consent_options_none_legal_consent_options_legitimate_interest_legal_consent_options_explicit_consent_to_process_legal_consent_options_implicit_consent_to_process.rb b/lib/hubspot/codegen/marketing/forms/models/one_of_legal_consent_options_none_legal_consent_options_legitimate_interest_legal_consent_options_explicit_consent_to_process_legal_consent_options_implicit_consent_to_process.rb new file mode 100644 index 000000000..529876120 --- /dev/null +++ b/lib/hubspot/codegen/marketing/forms/models/one_of_legal_consent_options_none_legal_consent_options_legitimate_interest_legal_consent_options_explicit_consent_to_process_legal_consent_options_implicit_consent_to_process.rb @@ -0,0 +1,111 @@ +=begin +#Forms + +#No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +The version of the OpenAPI document: v3 + +Generated by: https://openapi-generator.tech +OpenAPI Generator version: 6.2.1 + +=end + +require 'date' +require 'time' + +module Hubspot + module Marketing + module Forms + module OneOfLegalConsentOptionsNoneLegalConsentOptionsLegitimateInterestLegalConsentOptionsExplicitConsentToProcessLegalConsentOptionsImplicitConsentToProcess + class << self + # List of class defined in oneOf (OpenAPI v3) + def openapi_one_of + [ + :'LegalConsentOptionsExplicitConsentToProcess', + :'LegalConsentOptionsImplicitConsentToProcess', + :'LegalConsentOptionsLegitimateInterest', + :'LegalConsentOptionsNone' + ] + end + + # Builds the object + # @param [Mixed] Data to be matched against the list of oneOf items + # @return [Object] Returns the model or the data itself + def build(data) + # Go through the list of oneOf items and attempt to identify the appropriate one. + # Note: + # - We do not attempt to check whether exactly one item matches. + # - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 }) + # due to the way the deserialization is made in the base_object template (it just casts without verifying). + # - TODO: scalar values are de facto behaving as if they were nullable. + # - TODO: logging when debugging is set. + openapi_one_of.each do |klass| + begin + next if klass == :AnyType # "nullable: true" + typed_data = find_and_cast_into_type(klass, data) + return typed_data if typed_data + rescue # rescue all errors so we keep iterating even if the current item lookup raises + end + end + + openapi_one_of.include?(:AnyType) ? data : nil + end + + private + + SchemaMismatchError = Class.new(StandardError) + + # Note: 'File' is missing here because in the regular case we get the data _after_ a call to JSON.parse. + def find_and_cast_into_type(klass, data) + return if data.nil? + + case klass.to_s + when 'Boolean' + return data if data.instance_of?(TrueClass) || data.instance_of?(FalseClass) + when 'Float' + return data if data.instance_of?(Float) + when 'Integer' + return data if data.instance_of?(Integer) + when 'Time' + return Time.parse(data) + when 'Date' + return Date.parse(data) + when 'String' + return data if data.instance_of?(String) + when 'Object' # "type: object" + return data if data.instance_of?(Hash) + when /\AArray<(?.+)>\z/ # "type: array" + if data.instance_of?(Array) + sub_type = Regexp.last_match[:sub_type] + return data.map { |item| find_and_cast_into_type(sub_type, item) } + end + when /\AHash.+)>\z/ # "type: object" with "additionalProperties: { ... }" + if data.instance_of?(Hash) && data.keys.all? { |k| k.instance_of?(Symbol) || k.instance_of?(String) } + sub_type = Regexp.last_match[:sub_type] + return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) } + end + else # model + const = Hubspot::Marketing::Forms.const_get(klass) + if const + if const.respond_to?(:openapi_one_of) # nested oneOf model + model = const.build(data) + return model if model + else + # raise if data contains keys that are not known to the model + raise unless (data.keys - const.acceptable_attributes).empty? + model = const.build_from_hash(data) + return model if model && model.valid? + end + end + end + + raise # if no match by now, raise + rescue + raise SchemaMismatchError, "#{data} doesn't match the #{klass} type" + end + end + end + + end + end +end diff --git a/spec/discovery/marketing/forms/hub_spot_form_definition_spec.rb b/spec/discovery/marketing/forms/hub_spot_form_definition_spec.rb new file mode 100644 index 000000000..45f0b1755 --- /dev/null +++ b/spec/discovery/marketing/forms/hub_spot_form_definition_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe 'Hubspot::Marketing::Forms::HubSpotFormDefinition' do + # Instantiating the codegen api installs the const_get hook that lazily + # requires model files, mirroring how deserialization resolves constants. + before { Hubspot::Client.new(access_token: 'test').marketing.forms.forms_api.api } + + let(:payload) do + { + id: '0d22e093-3b4f-4a4f-a5b8-3f4f6f5b8c01', + name: 'Contact Us', + formType: 'hubspot', + archived: false, + legalConsentOptions: { type: 'none' } + } + end + + it 'deserializes a form with legalConsentOptions' do + form = Hubspot::Marketing::Forms.const_get(:HubSpotFormDefinition).build_from_hash(payload) + + expect(form.name).to eq('Contact Us') + expect(form.legal_consent_options).to be_a(Hubspot::Marketing::Forms.const_get(:LegalConsentOptionsNone)) + expect(form.legal_consent_options.type).to eq('none') + end +end