VAPI-3162-REFER#211
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
stampercasey
left a comment
There was a problem hiding this comment.
Review from Claude Code — see inline comments for individual findings. Two blockers; the callback model and enums are solid.
| require 'bandwidth-sdk/models/recording_transcriptions' | ||
| require 'bandwidth-sdk/models/redirect_callback' | ||
| require 'bandwidth-sdk/models/redirect_method_enum' | ||
| require 'bandwidth-sdk/models/refer' |
There was a problem hiding this comment.
[BLOCKER] Bandwidth::Bxml::Refer BXML builder is missing
This require loads a data model (Bandwidth::Refer < ApiModelBase), not a BXML verb. Every other verb has two layers:
lib/bandwidth-sdk/models/bxml/verbs/transfer.rb→Bandwidth::Bxml::Transfer < NestableVerb(generates<Transfer>XML)lib/bandwidth-sdk/models/transfer_complete_callback.rb→Bandwidth::TransferCompleteCallback(deserializes the callback)
This PR adds the callback model but not the verb builder. A require 'bandwidth-sdk/models/bxml/verbs/refer' line should also appear around line 258 (alongside the other BXML verbs), wiring in a Bandwidth::Bxml::Refer < Bandwidth::Bxml::NestableVerb that can produce <Refer>...</Refer> XML.
Expected pattern (mirrors Transfer):
# lib/bandwidth-sdk/models/bxml/verbs/refer.rb
module Bandwidth
module Bxml
class Refer < Bandwidth::Bxml::NestableVerb
def initialize(sip_uri, attributes = {})
super('Refer', nil, [sip_uri], attributes)
@attribute_map = {
refer_complete_url: 'referCompleteUrl',
refer_complete_method: 'referCompleteMethod',
tag: 'tag'
}
end
end
end
endThe Bandwidth::Bxml::SipUri for Refer should also be its own minimal class (no Transfer-specific attributes) — see Python SDK's ReferSipUri for rationale.
| # Nested SIP URI destination model used by <Refer>. | ||
| class SipUri < ApiModelBase | ||
| # SIP URI destination (e.g. sip:alice@atlanta.example.com) | ||
| attr_accessor :sip_uri |
There was a problem hiding this comment.
[MINOR] SipUri wraps the URI in a property also named sip_uri — double indirection
This produces:
model.sip_uri.sip_uri # => "sip:alice@atlanta.example.com"And serializes as { sipUri: { sipUri: "sip:alice@..." } }. The outer key is the attribute name on Refer; the inner key is this property — both end up as sipUri.
The C# SDK's nested Refer.SipUri class uses Uri (just the URI string); the Python SDK's ReferSipUri uses uri. A single field named uri would be cleaner and consistent:
attr_accessor :uri
def self.attribute_map
{ :'uri' => :'uri' } # serialized as element text, not a nested object
end| }) | ||
| end | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
[MINOR] Missing NOTIFY timeout scenario test
The spec defines four referComplete outcomes. Three are covered here (success, REFER rejected 405, destination unreachable 202+notifySipResponseCode). The fourth is missing:
NOTIFY timeout — REFER accepted (202) but the remote endpoint never sent a final NOTIFY within 30 seconds. referCallStatus=failure, referSipResponseCode=202, notifySipResponseCode absent.
it 'handles NOTIFY timeout (202 accepted, no NOTIFY received)' do
callback = Bandwidth::ReferCompleteCallback.build_from_hash({
...,
referCallStatus: 'failure',
referSipResponseCode: 202
})
expect(callback.refer_call_status).to eq(Bandwidth::ReferCallStatusEnum::FAILURE)
expect(callback.refer_sip_response_code).to eq(202)
expect(callback.notify_sip_response_code).to be_nil
end| expect(model.refer_complete_method).to eq('GET') | ||
| expect(model.sip_uri.sip_uri).to eq('sip:alice@atlanta.example.com') | ||
| end | ||
| end No newline at end of file |
There was a problem hiding this comment.
[MINOR] Missing tag max-length validation test
Refer#initialize raises ArgumentError when tag.length > 256, but there's no test exercising that guard. Add:
it 'rejects a tag exceeding 256 characters' do
expect {
Bandwidth::Refer.new(sip_uri: sip_uri, tag: 'x' * 257)
}.to raise_error(ArgumentError)
end
No description provided.