savon 2.5.1 → 2.6.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.
@@ -25,7 +25,7 @@ describe "Email example" do
25
25
  pending "API limit exceeded"
26
26
  else
27
27
  # The expected result. We unfortunately don't have a license key for this service.
28
- response_text.should == "Email Domain Not Found"
28
+ expect(response_text).to eq("Email Domain Not Found")
29
29
  end
30
30
  end
31
31
 
@@ -15,8 +15,8 @@ describe 'rpc/encoded binding test' do
15
15
  rescue Savon::SOAPFault => e
16
16
  $stderr.puts e.to_hash.inspect
17
17
  f_c = e.to_hash[:fault][:faultstring]
18
- f_c.should_not == 'No such operation \'getQuoteRequest\''
19
- f_c.should == 'soapenv:Server.userException'
18
+ expect(f_c).not_to eq('No such operation \'getQuoteRequest\'')
19
+ expect(f_c).to eq('soapenv:Server.userException')
20
20
  pending e
21
21
  end
22
22
  end
@@ -22,7 +22,7 @@ describe "Stockquote example" do
22
22
  nori_options = { :convert_tags_to => lambda { |tag| tag.snakecase.to_sym } }
23
23
  result = Nori.new(nori_options).parse(cdata)
24
24
 
25
- result[:stock_quotes][:stock][:symbol].should == "AAPL"
25
+ expect(result[:stock_quotes][:stock][:symbol]).to eq("AAPL")
26
26
  end
27
27
 
28
28
  end
@@ -36,7 +36,7 @@ describe "ZIP code example" do
36
36
  threads.each(&:kill)
37
37
  values = threads.map { |thr| thr[:value] }.compact
38
38
 
39
- values.uniq.size.should == values.size
39
+ expect(values.uniq.size).to eq(values.size)
40
40
  end
41
41
 
42
42
  end
@@ -83,4 +83,9 @@ describe Savon::Builder do
83
83
  end
84
84
  end
85
85
 
86
+ describe '#body_attributes' do
87
+ it 'should not be nil' do
88
+ expect(builder.body_attributes).to eq({})
89
+ end
90
+ end
86
91
  end
@@ -65,7 +65,7 @@ describe Savon::Client do
65
65
 
66
66
  fit "defaults :log to false" do
67
67
  client = Savon.client(:wsdl => Fixture.wsdl(:authentication))
68
- expect(client.globals[:log]).to be_false
68
+ expect(client.globals[:log]).to be_falsey
69
69
  end
70
70
  end
71
71
 
@@ -4,33 +4,33 @@ describe String do
4
4
 
5
5
  describe "snakecase" do
6
6
  it "lowercases one word CamelCase" do
7
- "Merb".snakecase.should == "merb"
7
+ expect("Merb".snakecase).to eq("merb")
8
8
  end
9
9
 
10
10
  it "makes one underscore snakecase two word CamelCase" do
11
- "MerbCore".snakecase.should == "merb_core"
11
+ expect("MerbCore".snakecase).to eq("merb_core")
12
12
  end
13
13
 
14
14
  it "handles CamelCase with more than 2 words" do
15
- "SoYouWantContributeToMerbCore".snakecase.should == "so_you_want_contribute_to_merb_core"
15
+ expect("SoYouWantContributeToMerbCore".snakecase).to eq("so_you_want_contribute_to_merb_core")
16
16
  end
17
17
 
18
18
  it "handles CamelCase with more than 2 capital letter in a row" do
19
- "CNN".snakecase.should == "cnn"
20
- "CNNNews".snakecase.should == "cnn_news"
21
- "HeadlineCNNNews".snakecase.should == "headline_cnn_news"
19
+ expect("CNN".snakecase).to eq("cnn")
20
+ expect("CNNNews".snakecase).to eq("cnn_news")
21
+ expect("HeadlineCNNNews".snakecase).to eq("headline_cnn_news")
22
22
  end
23
23
 
24
24
  it "does NOT change one word lowercase" do
25
- "merb".snakecase.should == "merb"
25
+ expect("merb".snakecase).to eq("merb")
26
26
  end
27
27
 
28
28
  it "leaves snake_case as is" do
29
- "merb_core".snakecase.should == "merb_core"
29
+ expect("merb_core".snakecase).to eq("merb_core")
30
30
  end
31
31
 
32
32
  it "converts period characters to underscores" do
33
- "User.GetEmail".snakecase.should == "user_get_email"
33
+ expect("User.GetEmail".snakecase).to eq("user_get_email")
34
34
  end
35
35
  end
36
36
 
@@ -11,11 +11,11 @@ describe Savon::HTTPError do
11
11
  describe ".present?" do
12
12
  it "returns true if there was an HTTP error" do
13
13
  http = new_response(:code => 404, :body => "Not Found")
14
- expect(Savon::HTTPError.present? http).to be_true
14
+ expect(Savon::HTTPError.present? http).to be_truthy
15
15
  end
16
16
 
17
17
  it "returns false unless there was an HTTP error" do
18
- expect(Savon::HTTPError.present? new_response).to be_false
18
+ expect(Savon::HTTPError.present? new_response).to be_falsey
19
19
  end
20
20
  end
21
21
 
@@ -45,6 +45,35 @@ describe "Options" do
45
45
  end
46
46
  end
47
47
 
48
+ context "global: :no_message_tag" do
49
+ it "omits the 'message tag' encapsulation step" do
50
+ client = new_client(:endpoint => @server.url(:repeat), :no_message_tag => true,
51
+ :wsdl => Fixture.wsdl(:no_message_tag))
52
+ msg = {'extLoginData' => {'Login' => 'test.user', 'Password' => 'secret', 'FacilityID' => 1,
53
+ 'ThreePLKey' => '{XXXX-XXXX-XXXX-XXXX}', 'ThreePLID' => 1},
54
+ 'Items' => ['Item' => {'SKU' => '001002003A', 'CustomerID' => 1,
55
+ 'InventoryMethod' => 'FIFO', 'UPC' => '001002003A'}]}
56
+ response = client.call(:create_items, :message => msg)
57
+
58
+ expect(response.http.body.scan(/<tns:extLoginData>/).count).to eq(1)
59
+ end
60
+
61
+ it "includes the 'message tag' encapsulation step" do
62
+ # This test is probably just exposing a bug while the previous
63
+ # test is using a workaround fix.
64
+ # That is just a guess though. I don't really have to properly debug the WSDL parser.
65
+ client = new_client(:endpoint => @server.url(:repeat), :no_message_tag => false,
66
+ :wsdl => Fixture.wsdl(:no_message_tag))
67
+ msg = {'extLoginData' => {'Login' => 'test.user', 'Password' => 'secret', 'FacilityID' => 1,
68
+ 'ThreePLKey' => '{XXXX-XXXX-XXXX-XXXX}', 'ThreePLID' => 1},
69
+ 'Items' => ['Item' => {'SKU' => '001002003A', 'CustomerID' => 1,
70
+ 'InventoryMethod' => 'FIFO', 'UPC' => '001002003A'}]}
71
+ response = client.call(:create_items, :message => msg)
72
+
73
+ expect(response.http.body.scan(/<tns:extLoginData>/).count).to eq(2)
74
+ end
75
+ end
76
+
48
77
  context "global :namespaces" do
49
78
  it "adds additional namespaces to the SOAP envelope" do
50
79
  namespaces = { "xmlns:whatever" => "http://whatever.example.com" }
@@ -55,6 +84,24 @@ describe "Options" do
55
84
  end
56
85
  end
57
86
 
87
+ context 'global :follow_redirects' do
88
+ it 'sets whether or not request should follow redirects' do
89
+ client = new_client(:endpoint => @server.url, :follow_redirects => true)
90
+
91
+ HTTPI::Request.any_instance.expects(:follow_redirect=).with(true)
92
+
93
+ response = client.call(:authenticate)
94
+ end
95
+
96
+ it 'defaults to false' do
97
+ client = new_client(:endpoint => @server.url)
98
+
99
+ HTTPI::Request.any_instance.expects(:follow_redirect=).with(false)
100
+
101
+ response = client.call(:authenticate)
102
+ end
103
+ end
104
+
58
105
  context "global :proxy" do
59
106
  it "sets the proxy server to use" do
60
107
  proxy_url = "http://example.com"
@@ -457,80 +504,215 @@ describe "Options" do
457
504
  end
458
505
  end
459
506
 
460
- context "global :wsse_auth" do
461
- it "adds WSSE basic auth information to the request" do
462
- client = new_client(:endpoint => @server.url(:repeat), :wsse_auth => ["luke", "secret"])
463
- response = client.call(:authenticate)
507
+ context ":wsse_auth" do
508
+ let(:username) { "luke" }
509
+ let(:password) { "secret" }
510
+ let(:request) { response.http.body }
464
511
 
465
- request = response.http.body
512
+ shared_examples "WSSE basic auth" do
513
+ it "adds WSSE basic auth information to the request" do
514
+ # the header and wsse security node
515
+ wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
516
+ expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
517
+
518
+ # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
519
+ expect(request).to include("<wsse:UsernameToken")
520
+ expect(request).to include("wsu:Id=\"UsernameToken-1\"")
521
+ expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
522
+
523
+ # the username and password node with type attribute
524
+ expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
525
+ password_text = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
526
+ expect(request).to include("<wsse:Password Type=\"#{password_text}\">#{password}</wsse:Password>")
527
+ end
528
+ end
529
+
530
+ shared_examples "WSSE digest auth" do
531
+ it "adds WSSE digest auth information to the request" do
532
+ # the header and wsse security node
533
+ wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
534
+ expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
535
+
536
+ # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
537
+ expect(request).to include("<wsse:UsernameToken")
538
+ expect(request).to include("wsu:Id=\"UsernameToken-1\"")
539
+ expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
540
+
541
+ # the username node
542
+ expect(request).to include("<wsse:Username>#{username}</wsse:Username>")
543
+
544
+ # the nonce node
545
+ expect(request).to match(/<wsse:Nonce.*>.+\n<\/wsse:Nonce>/)
466
546
 
467
- # the header and wsse security node
468
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
469
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
547
+ # the created node with a timestamp
548
+ expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
470
549
 
471
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
472
- expect(request).to include("<wsse:UsernameToken")
473
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
474
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
550
+ # the password node contains the encrypted value
551
+ password_digest = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
552
+ expect(request).to match(/<wsse:Password Type=\"#{password_digest}\">.+<\/wsse:Password>/)
553
+ expect(request).to_not include(password)
554
+ end
555
+ end
475
556
 
476
- # the username and password node with type attribute
477
- expect(request).to include("<wsse:Username>luke</wsse:Username>")
478
- password_text = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"
479
- expect(request).to include("<wsse:Password Type=\"#{password_text}\">secret</wsse:Password>")
557
+ shared_examples "no WSSE auth" do
558
+ it "does not add WSSE auth to the request" do
559
+ expect(request).not_to include("<wsse:UsernameToken")
560
+ end
480
561
  end
481
562
 
482
- it "adds WSSE digest auth information to the request" do
483
- client = new_client(:endpoint => @server.url(:repeat), :wsse_auth => ["lea", "top-secret", :digest])
484
- response = client.call(:authenticate)
563
+ describe "global" do
564
+ context "enabled" do
565
+ context "without digest" do
566
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password]) }
567
+ let(:response) { client.call(:authenticate) }
568
+ include_examples "WSSE basic auth"
569
+ end
485
570
 
486
- request = response.http.body
571
+ context "with digest" do
572
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
573
+ let(:response) { client.call(:authenticate) }
574
+ include_examples "WSSE digest auth"
575
+ end
487
576
 
488
- # the header and wsse security node
489
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
490
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
577
+ context "local override" do
578
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => ["luke", "secret"]) }
579
+
580
+ context "enabled" do
581
+ let(:username) { "lea" }
582
+ let(:password) { "top-secret" }
583
+
584
+ context "without digest" do
585
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password)} }
586
+ include_examples "WSSE basic auth"
587
+ end
588
+
589
+ context "with digest" do
590
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
591
+ include_examples "WSSE digest auth"
592
+ end
593
+ end
594
+
595
+ context "disabled" do
596
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(false)} }
597
+ include_examples "no WSSE auth"
598
+ end
599
+
600
+ context "set to nil" do
601
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(nil)} }
602
+ include_examples "WSSE basic auth"
603
+ end
604
+ end
491
605
 
492
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
493
- expect(request).to include("<wsse:UsernameToken")
494
- expect(request).to include("wsu:Id=\"UsernameToken-1\"")
495
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
606
+ context "global" do
607
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_auth => [username, password, :digest]) }
608
+ let(:response) { client.call(:authenticate) }
609
+ include_examples "WSSE digest auth"
610
+ end
611
+ end
496
612
 
497
- # the username node
498
- expect(request).to include("<wsse:Username>lea</wsse:Username>")
613
+ context "not enabled" do
614
+ let(:client) { new_client(:endpoint => @server.url(:repeat)) }
499
615
 
500
- # the nonce node
501
- expect(request).to match(/<wsse:Nonce.*>.+\n<\/wsse:Nonce>/)
616
+ describe "local" do
617
+ context "enabled" do
618
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_auth(username, password, :digest)} }
619
+ include_examples "WSSE digest auth"
620
+ end
502
621
 
503
- # the created node with a timestamp
504
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
622
+ context "disabled" do
623
+ let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(false)} }
624
+ include_examples "no WSSE auth"
625
+ end
505
626
 
506
- # the password node contains the encrypted value
507
- password_digest = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
508
- expect(request).to match(/<wsse:Password Type=\"#{password_digest}\">.+<\/wsse:Password>/)
509
- expect(request).to_not include("top-secret")
627
+ context "set to nil" do
628
+ let(:response) { client.call(:authenticate) { |locals| locals.wsse_auth(nil)} }
629
+ include_examples "no WSSE auth"
630
+ end
631
+ end
632
+ end
510
633
  end
511
634
  end
512
635
 
513
- context "global :wsse_timestamp" do
514
- it "adds WSSE timestamp auth information to the request" do
515
- client = new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true)
516
- response = client.call(:authenticate)
636
+ context ":wsse_timestamp" do
637
+ let(:request) { response.http.body }
517
638
 
518
- request = response.http.body
639
+ shared_examples "WSSE timestamp" do
640
+ it "adds WSSE timestamp auth information to the request" do
641
+ # the header and wsse security node
642
+ wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
643
+ expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
519
644
 
520
- # the header and wsse security node
521
- wsse_namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
522
- expect(request).to include("<env:Header><wsse:Security xmlns:wsse=\"#{wsse_namespace}\">")
645
+ # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
646
+ expect(request).to include("<wsu:Timestamp")
647
+ expect(request).to include("wsu:Id=\"Timestamp-1\"")
648
+ expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
523
649
 
524
- # split up to prevent problems with unordered Hash attributes in 1.8 [dh, 2012-12-13]
525
- expect(request).to include("<wsu:Timestamp")
526
- expect(request).to include("wsu:Id=\"Timestamp-1\"")
527
- expect(request).to include("xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"")
650
+ # the created node with a timestamp
651
+ expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
528
652
 
529
- # the created node with a timestamp
530
- expect(request).to match(/<wsu:Created>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Created>/)
653
+ # the expires node with a timestamp
654
+ expect(request).to match(/<wsu:Expires>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Expires>/)
655
+ end
656
+ end
657
+
658
+ shared_examples "no WSSE timestamp" do
659
+ it "does not add WSSE timestamp to the request" do
660
+ expect(request).not_to include("<wsu:Timestamp")
661
+ end
662
+ end
663
+
664
+ describe "global" do
665
+ context "enabled" do
666
+ context "through block without arguments" do
667
+ let(:client) do
668
+ new_client(:endpoint => @server.url(:repeat)) do |globals|
669
+ globals.wsse_timestamp
670
+ end
671
+ end
672
+ let(:response) { client.call(:authenticate) }
673
+ include_examples "WSSE timestamp"
674
+ end
531
675
 
532
- # the expires node with a timestamp
533
- expect(request).to match(/<wsu:Expires>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*<\/wsu:Expires>/)
676
+ context "through initializer options" do
677
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
678
+ let(:response) { client.call(:authenticate) }
679
+ include_examples "WSSE timestamp"
680
+ end
681
+
682
+ context "with local override" do
683
+ let(:client) { new_client(:endpoint => @server.url(:repeat), :wsse_timestamp => true) }
684
+ context "enabled" do
685
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
686
+ include_examples "WSSE timestamp"
687
+ end
688
+ context "disabled" do
689
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
690
+ include_examples "no WSSE timestamp"
691
+ end
692
+ context "set to nil" do
693
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
694
+ include_examples "WSSE timestamp"
695
+ end
696
+ end
697
+ end
698
+
699
+ context "not enabled" do
700
+ let(:client) { new_client(:endpoint => @server.url(:repeat)) }
701
+ describe "local" do
702
+ context "enabled" do
703
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp} }
704
+ include_examples "WSSE timestamp"
705
+ end
706
+ context "disabled" do
707
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(false) } }
708
+ include_examples "no WSSE timestamp"
709
+ end
710
+ context "set to nil" do
711
+ let(:response) { client.call(:authenticate) {|locals| locals.wsse_timestamp(nil) } }
712
+ include_examples "no WSSE timestamp"
713
+ end
714
+ end
715
+ end
534
716
  end
535
717
  end
536
718
 
@@ -129,7 +129,7 @@ describe Savon::WSDLRequest do
129
129
 
130
130
  new_wsdl_request.build
131
131
 
132
- expect { http_request.auth.ssl.cert_key }.to raise_error(OpenSSL::PKey::RSAError)
132
+ expect { http_request.auth.ssl.cert_key }.to raise_error
133
133
  end
134
134
  end
135
135
 
@@ -145,7 +145,7 @@ describe Savon::WSDLRequest do
145
145
 
146
146
  new_wsdl_request.build
147
147
 
148
- http_request.auth.ssl.cert_key.to_s.should =~ /BEGIN RSA PRIVATE KEY/
148
+ expect(http_request.auth.ssl.cert_key.to_s).to match(/BEGIN RSA PRIVATE KEY/)
149
149
  end
150
150
  end
151
151
  end