savon 2.5.1 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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