lce 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +21 -0
  8. data/README.md +98 -0
  9. data/Rakefile +5 -0
  10. data/lce.gemspec +30 -0
  11. data/lib/lce.rb +72 -0
  12. data/lib/lce/client.rb +34 -0
  13. data/lib/lce/client/connection.rb +23 -0
  14. data/lib/lce/client/errors.rb +25 -0
  15. data/lib/lce/client/request.rb +80 -0
  16. data/lib/lce/offer.rb +25 -0
  17. data/lib/lce/order.rb +51 -0
  18. data/lib/lce/quote.rb +34 -0
  19. data/lib/lce/version.rb +4 -0
  20. data/lib/paginated_array.rb +25 -0
  21. data/spec/fixtures/access_denied +20 -0
  22. data/spec/fixtures/account_disabled +20 -0
  23. data/spec/fixtures/check +464 -0
  24. data/spec/fixtures/offers/available_delivery_locations/found +785 -0
  25. data/spec/fixtures/offers/find/found +66 -0
  26. data/spec/fixtures/offers/find/not_found +15 -0
  27. data/spec/fixtures/order_params +23 -0
  28. data/spec/fixtures/orders/all/page_1 +111 -0
  29. data/spec/fixtures/orders/find/found +106 -0
  30. data/spec/fixtures/orders/find/not_found +15 -0
  31. data/spec/fixtures/orders/labels/labels.pdf +0 -0
  32. data/spec/fixtures/orders/labels/response +0 -0
  33. data/spec/fixtures/orders/place/created +106 -0
  34. data/spec/fixtures/orders/place/empty_params +15 -0
  35. data/spec/fixtures/orders/place/missing_params +15 -0
  36. data/spec/fixtures/orders/tracking +30 -0
  37. data/spec/fixtures/quote_params +25 -0
  38. data/spec/fixtures/quotes/all/page_1 +11594 -0
  39. data/spec/fixtures/quotes/all/page_2 +1665 -0
  40. data/spec/fixtures/quotes/find/found +492 -0
  41. data/spec/fixtures/quotes/find/not_found +15 -0
  42. data/spec/fixtures/quotes/request/created +492 -0
  43. data/spec/fixtures/quotes/request/empty_quote +15 -0
  44. data/spec/fixtures/quotes/request/missing_params +15 -0
  45. data/spec/lce/client_spec.rb +41 -0
  46. data/spec/lce/offer_spec.rb +85 -0
  47. data/spec/lce/order_spec.rb +136 -0
  48. data/spec/lce/quote_spec.rb +111 -0
  49. data/spec/lce_spec.rb +109 -0
  50. data/spec/paginated_array_spec.rb +55 -0
  51. data/spec/spec_helper.rb +17 -0
  52. data/tasks/rspec.rake +3 -0
  53. metadata +239 -0
@@ -0,0 +1,15 @@
1
+ HTTP/1.1 500 Internal Server Error
2
+ Server: nginx/1.6.0
3
+ Date: Tue, 12 Aug 2014 12:59:10 GMT
4
+ Content-Type: application/json
5
+ Content-Length: 471
6
+ Connection: keep-alive
7
+
8
+ {
9
+ "status":"failure",
10
+ "error":{
11
+ "type":"internal",
12
+ "message":"quote[shipper] is missing, quote[shipper][country] is missing, quote[shipper][postal_code] is missing, quote[shipper][city] is missing, quote[recipient] is missing, quote[recipient][country] is missing, quote[recipient][is_a_company] is missing, quote[recipient][postal_code] is missing, quote[recipient][city] is missing, quote[parcels] is missing"
13
+ },
14
+ "self":"https://test.lce.io/v1/quotes"
15
+ }
@@ -0,0 +1,15 @@
1
+ HTTP/1.1 500 Internal Server Error
2
+ Server: nginx/1.6.0
3
+ Date: Wed, 13 Aug 2014 12:47:00 GMT
4
+ Content-Type: application/json
5
+ Content-Length: 156
6
+ Connection: keep-alive
7
+
8
+ {
9
+ "status":"failure",
10
+ "error":{
11
+ "type":"internal",
12
+ "message":"quote[recipient][city] is missing"
13
+ },
14
+ "self":"https://test.lce.io/v1/quotes"
15
+ }
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Client do
4
+ describe "#http_adapter" do
5
+ it "uses default faraday's adapter as a default" do
6
+ expect(subject.http_adapter).to be(Faraday.default_adapter)
7
+
8
+ end
9
+ end
10
+ describe "#host" do
11
+ it 'returns the correct host for the staging environment' do
12
+ expect(subject.host).to eql('https://test.lce.io')
13
+ end
14
+
15
+ it 'returns the correct host for the production environment' do
16
+ Lce.configuration.environment = :production
17
+ expect(subject.host).to eql('https://api.lce.io')
18
+ end
19
+ end
20
+ describe "#api version" do
21
+ it 'returns a string of the API version' do
22
+ expect(subject.api_version).to eql('v1')
23
+ end
24
+ it 'needs a valid version' do
25
+ Lce.configuration.api_version = 'api_version'
26
+ expect { subject.api_version }.to raise_error(Lce::Client::Errors::VersionError)
27
+ end
28
+ end
29
+ describe "#path" do
30
+ it 'returns a root path as default' do
31
+ expect(subject.send(:path).to_s).to eql('/')
32
+ end
33
+ context 'with a resource' do
34
+ it 'returns a path with aversion and a resource' do
35
+ Lce.configuration.api_version = 1
36
+ expect(subject.send(:path, :quotes).to_s).to eql('/v1/quotes')
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Offer do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+ describe ".find" do
13
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
14
+ it 'returns an offer' do
15
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
16
+ .to_return(fixture('offers/find/found'))
17
+ expect(Lce::Offer.find(id).id).to eql(id)
18
+ end
19
+ context 'inexistant offer' do
20
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90d'}
21
+ it 'raise an exception' do
22
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
23
+ .to_return(fixture('offers/find/not_found'))
24
+ expect{Lce::Offer.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Offer not found')
25
+ end
26
+ end
27
+ end
28
+ describe "#place_order" do
29
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
30
+ let(:params) {
31
+ {
32
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
33
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
34
+ parcels: []
35
+ }
36
+ }
37
+ let(:request_params) {
38
+ params.merge(offer_id: id)
39
+ }
40
+ it 'places an order for this offer' do
41
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
42
+ .to_return(fixture('offers/find/found'))
43
+
44
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
45
+ .with(:body => {order: request_params})
46
+ .to_return(fixture('orders/place/created'))
47
+ offer = Lce::Offer.find(id)
48
+ order = offer.place_order(params)
49
+ expect(order).to be_a(Lce::Order)
50
+ end
51
+ end
52
+
53
+ describe "#available_delivery_locations" do
54
+ let(:params) {
55
+ {
56
+ street: "37 Avenue Jean Médecin",
57
+ city: "Nice"
58
+ }
59
+ }
60
+ context 'when the product doesn\'t support preset delivery locations' do
61
+ let(:id) {'ff75b691-a2e0-46b0-9909-d529b2dbb90c'}
62
+ it 'returns an empty array' do
63
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}")
64
+ .to_return(fixture('offers/find/found'))
65
+
66
+ offer = Lce::Offer.find(id)
67
+ expect(offer.available_delivery_locations(params).count).to eql(0)
68
+ end
69
+ end
70
+ context 'when the product support preset delivery locations' do
71
+ let(:id) {'563aeac0-4a88-4269-b9b7-48964a8678f0'}
72
+ let(:quote_id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7199'}
73
+
74
+ it 'looks for available delivery locations for delivery in shop' do
75
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{quote_id}")
76
+ .to_return(fixture('quotes/find/found'))
77
+ stub_request(:get, "https://login:password@test.lce.io/v1/offers/#{id}/available_delivery_locations?location%5Bcity%5D=Nice&location%5Bstreet%5D=37%20Avenue%20Jean%20M%C3%A9decin")
78
+ .to_return(fixture('offers/available_delivery_locations/found'))
79
+ offer = Lce::Quote.find(quote_id).offers.select{|o| o.id == id}.first
80
+ expect(offer.available_delivery_locations(params).count).to eql(23)
81
+ end
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Order do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+
13
+ describe '.place' do
14
+ context "with invalid parameters" do
15
+ it "raises an error on an empty order" do
16
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
17
+ .with(:body => '{"order":{}}')
18
+ .to_return(fixture('orders/place/empty_params'))
19
+
20
+ expect{ Lce::Order.place({})}.to raise_error(Lce::Client::Errors::LceError)
21
+ end
22
+
23
+ it "raises an error with missing params" do
24
+ params = {
25
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
26
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
27
+ parcels: []
28
+ }
29
+
30
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
31
+ .with(:body => {order: params})
32
+ .to_return(fixture('orders/place/missing_params'))
33
+
34
+ expect{ Lce::Order.place(params)}.to raise_error(Lce::Client::Errors::LceError, 'order[offer_id] is missing')
35
+ end
36
+ end
37
+ context "with valid parameters" do
38
+ let(:params) {
39
+ {
40
+ offer_id: "ff75b691-a2e0-46b0-9909-d529b2dbb90c",
41
+ shipper: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
42
+ recipient: {name: "Firstname Lastname", street: "street", phone: "+33699999999", email: "support@lce.io"},
43
+ parcels: []
44
+ }
45
+ }
46
+ it "creates an order" do
47
+ stub_request(:post, "https://login:password@test.lce.io/v1/orders")
48
+ .with(:body => {order: params})
49
+ .to_return(fixture('orders/place/created'))
50
+ expect(Lce::Order.place(params)).to be_a(Lce::Order)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe ".find" do
56
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
57
+ it 'returns an order' do
58
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
59
+ .to_return(fixture('orders/find/found'))
60
+ expect(Lce::Order.find(id).id).to eql(id)
61
+ end
62
+ context 'inexistant order' do
63
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc29'}
64
+ it 'raises an error' do
65
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
66
+ .to_return(fixture('orders/find/not_found'))
67
+ expect{Lce::Order.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Order not found')
68
+ end
69
+ end
70
+ end
71
+ describe ".all" do
72
+ before do
73
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders")
74
+ .to_return(fixture('orders/all/page_1'))
75
+ end
76
+ it 'returns all orders' do
77
+ expect(Lce::Order.all.size).to eql(1)
78
+ end
79
+
80
+ it 'returns order object' do
81
+ expect(Lce::Order.all.first).to be_a(Lce::Order)
82
+ end
83
+
84
+ it 'returns a paginated array' do
85
+ expect(Lce::Order.all).to be_a(PaginatedArray)
86
+ end
87
+ it 'returns total count' do
88
+ expect(Lce::Order.all.total_count).to eql(1)
89
+ end
90
+ it 'returns current_page' do
91
+ expect(Lce::Order.all.current_page).to eql(1)
92
+ end
93
+ it 'returns page size' do
94
+ expect(Lce::Order.all.per_page).to eql(25)
95
+ end
96
+
97
+ end
98
+
99
+ describe "#labels" do
100
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
101
+ it 'returns the labels for this order' do
102
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
103
+ .to_return(fixture('orders/find/found'))
104
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}/labels.pdf")
105
+ .to_return(fixture('orders/labels/response'))
106
+
107
+ order = Lce::Order.find(id)
108
+ labels_file = File.read('spec/fixtures/orders/labels/labels.pdf', {mode: 'rb' })
109
+ expect(order.labels).to eql(labels_file)
110
+ end
111
+ end
112
+
113
+ describe "#tracking" do
114
+ let(:id) {'8c43a2e1-a7ff-49fd-807e-3877d6dadc28'}
115
+ it 'returns the tracking for this order' do
116
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}")
117
+ .to_return(fixture('orders/find/found'))
118
+ stub_request(:get, "https://login:password@test.lce.io/v1/orders/#{id}/tracking")
119
+ .to_return(fixture('orders/tracking'))
120
+
121
+ tracking_events_by_parcel = [{
122
+ "parcel_index"=>0,
123
+ "events"=> [{
124
+ "code"=>"shipment_created",
125
+ "happened_at"=>"2014-08-19T16:41:00+02:00",
126
+ "label"=>{"fr"=>"Expédition créée", "en"=>"Shipment created"},
127
+ "location"=>{"name"=>"Web Services"}
128
+ }]
129
+ }]
130
+
131
+ order = Lce::Order.find(id)
132
+ expect(order.tracking).to eql(tracking_events_by_parcel)
133
+ end
134
+ end
135
+
136
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce::Quote do
4
+ before do
5
+ Lce.configure do |config|
6
+ config.environment = :staging
7
+ config.login = 'login'
8
+ config.password = 'password'
9
+ config.logger.level = Logger::FATAL
10
+ end
11
+ end
12
+ describe ".request" do
13
+ context "with invalid parameters" do
14
+ it "raises an error on an empty quote" do
15
+
16
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
17
+ .with(:body => '{"quote":{}}')
18
+ .to_return(fixture('quotes/request/empty_quote'))
19
+
20
+ expect{ Lce::Quote.request({})}.to raise_error(Lce::Client::Errors::LceError)
21
+ end
22
+
23
+ it "raises an error with missing params" do
24
+
25
+ params = {
26
+ shipper: {country: 'FR', postal_code: '31300', city: 'Toulouse'},
27
+ recipient: {country: 'FR', postal_code: '06000', is_a_company: true},
28
+ parcels: [{length: 15, width: 15, height: 15, weight: 2}]
29
+ }
30
+
31
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
32
+ .with(:body => {quote: params})
33
+ .to_return(fixture('quotes/request/missing_params'))
34
+
35
+ expect{ Lce::Quote.request(params)}.to raise_error(Lce::Client::Errors::LceError, 'quote[recipient][city] is missing')
36
+ end
37
+ end
38
+ context "with valid parameters" do
39
+ let(:params) {
40
+ {
41
+ shipper: {country: 'FR', postal_code: '31300', city: 'Toulouse'},
42
+ recipient: {country: 'FR', postal_code: '06000', city: 'Nice',is_a_company: true},
43
+ parcels: [{length: 15, width: 15, height: 15, weight: 2}]
44
+ }
45
+ }
46
+ it "creates a quote" do
47
+ stub_request(:post, "https://login:password@test.lce.io/v1/quotes")
48
+ .with(:body => {quote: params})
49
+ .to_return(fixture('quotes/request/created'))
50
+ expect(Lce::Quote.request(params)).to be_a(Lce::Quote)
51
+ end
52
+ end
53
+ end
54
+ describe ".find" do
55
+ let(:id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7199'}
56
+ it 'returns a quote' do
57
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{id}")
58
+ .to_return(fixture('quotes/find/found'))
59
+ expect(Lce::Quote.find(id).id).to eql(id)
60
+ end
61
+ context 'inexistant quote' do
62
+ let(:id) {'cd8d1a03-bfec-4115-87ef-8f8ba91a7198'}
63
+ it 'returns a quote' do
64
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes/#{id}")
65
+ .to_return(fixture('quotes/find/not_found'))
66
+ expect{Lce::Quote.find(id).id}.to raise_error(Lce::Client::Errors::LceError, 'Quote not found')
67
+ end
68
+ end
69
+ end
70
+ describe ".all" do
71
+ before do
72
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes")
73
+ .to_return(fixture('quotes/all/page_1'))
74
+ end
75
+ it 'returns all quotes' do
76
+ expect(Lce::Quote.all.size).to eql(25)
77
+ end
78
+
79
+ it 'returns quote object' do
80
+ expect(Lce::Quote.all.first).to be_a(Lce::Quote)
81
+ end
82
+
83
+ it 'returns a paginated array' do
84
+ expect(Lce::Quote.all).to be_a(PaginatedArray)
85
+ end
86
+ it 'returns total count' do
87
+ expect(Lce::Quote.all.total_count).to eql(29)
88
+ end
89
+ it 'returns current_page' do
90
+ expect(Lce::Quote.all.current_page).to eql(1)
91
+ end
92
+ it 'returns page size' do
93
+ expect(Lce::Quote.all.per_page).to eql(25)
94
+ end
95
+ context 'with a second page' do
96
+ before do
97
+ stub_request(:get, "https://login:password@test.lce.io/v1/quotes?page=2")
98
+ .to_return(fixture('quotes/all/page_2'))
99
+ end
100
+ it 'returns all quotes' do
101
+ expect(Lce::Quote.all(2).size).to eql(4)
102
+ end
103
+ it 'returns total count' do
104
+ expect(Lce::Quote.all(2).total_count).to eql(29)
105
+ end
106
+ it 'returns current_page' do
107
+ expect(Lce::Quote.all(2).current_page).to eql(2)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lce do
4
+ describe ".configure" do
5
+
6
+ it 'has a configuration' do
7
+ Lce.reset
8
+ expect(Lce.configuration).to be_a(Lce::Configuration)
9
+ end
10
+
11
+ it 'has a default environment' do
12
+ Lce.reset
13
+ expect(Lce.configuration.environment).to be :staging
14
+ end
15
+
16
+ it 'raises an exception when an environment is not supported' do
17
+ expect { Lce.configuration.environment = :jungle }.to raise_error
18
+ end
19
+
20
+ it 'doesn\'t have a default login'do
21
+ Lce.reset
22
+ expect(Lce.configuration.login).to be_nil
23
+ end
24
+
25
+ it 'has a default application name' do
26
+ Lce.reset
27
+ expect(Lce.configuration.application).to eql 'ruby-lce'
28
+ end
29
+
30
+ it 'uses the gem\'s version as its default' do
31
+ Lce.reset
32
+ expect(Lce.configuration.version).to be Lce::VERSION
33
+ end
34
+
35
+
36
+ it 'doesn\'t have a default password' do
37
+ Lce.reset
38
+ expect(Lce.configuration.password).to be_nil
39
+ end
40
+
41
+ context 'when configuration is overridden locally' do
42
+ before do
43
+ Lce.configure do |config|
44
+ config.environment = :production
45
+ config.login = 'login'
46
+ config.password = 'password'
47
+ config.application = 'My Great App'
48
+ config.version = 'E.32.R526'
49
+ end
50
+ end
51
+
52
+ it 'can override default values' do
53
+ expect(Lce.configuration.environment).to be :production
54
+ end
55
+
56
+ it 'can set a login' do
57
+ expect(Lce.configuration.login).to eq('login')
58
+ end
59
+
60
+ it 'can set a password' do
61
+ expect(Lce.configuration.password).to eq('password')
62
+ end
63
+
64
+ it 'customizes app name but retains the gem\'s name' do
65
+ expect(Lce.configuration.application).to eq("My Great App (ruby-lce)")
66
+ end
67
+
68
+ it 'customizes app version but retains the gem\'s version' do
69
+ expect(Lce.configuration.version).to eq("E.32.R526 (#{Lce::VERSION})")
70
+ end
71
+
72
+ end
73
+ end
74
+ describe '.check' do
75
+ context 'without authentication' do
76
+ before do
77
+ Lce.configure do |config|
78
+ config.environment = :staging
79
+ config.login = nil
80
+ config.password = nil
81
+ config.logger.level = Logger::FATAL
82
+ end
83
+ end
84
+ it 'raises an AccessDenied exception when not authenticated properly' do
85
+ stub_request(:get, "https://test.lce.io/").to_return(fixture('access_denied'))
86
+ expect {Lce.check}.to raise_error Lce::Client::Errors::AccessDenied
87
+ end
88
+ end
89
+ context 'with authentication' do
90
+ before do
91
+ Lce.configure do |config|
92
+ config.environment = :staging
93
+ config.login = 'login'
94
+ config.password = 'password'
95
+ config.logger.level = Logger::FATAL
96
+ end
97
+ end
98
+ it 'raises an AccountDisabled exception when account is disabled' do
99
+ stub_request(:get, "https://login:password@test.lce.io/").to_return(fixture('account_disabled'))
100
+ expect {Lce.check}.to raise_error Lce::Client::Errors::AccountDisabled
101
+ end
102
+ it 'return a description of the service' do
103
+ stub_request(:get, "https://login:password@test.lce.io/").to_return(fixture('check'))
104
+ expect(Lce.check.host).to eql('test.lce.io')
105
+ end
106
+ end
107
+
108
+ end
109
+ end