sendcloud-ruby 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 925c78de85ca4fb2cf19a3c3f3c405bd75317b99
4
+ data.tar.gz: 6ac99e7ad7e5afbbfd070fedb88df7e67548352b
5
+ SHA512:
6
+ metadata.gz: f05aa4716beacaaf2918fd93b2aa02d45c1b69d7e3ff2553a766d9cadfcc1e77fec8479928a2d3036c4010a6bd4d9d16b30f3a71201ea22bd91c0d5b9e671541
7
+ data.tar.gz: 3edc1714714bf6477ff289078e74075a99a084068c47eade006a159f5e89163ae00f8b81c5d16d1bc464222f170353f6af0af84936f3bfe43cd1d68594948413
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/**
19
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "codeclimate-test-reporter", group: :test, require: nil
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014-2015 PeRo ICT Solutions
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Sendcloud
2
+
3
+ ***WORK IN PROGRESS***
4
+
5
+ [![wercker status](https://app.wercker.com/status/03866f33222cc05a0e18eb2aac723f5c/m "wercker status")](https://app.wercker.com/project/bykey/03866f33222cc05a0e18eb2aac723f5c)
6
+ [![Gem Version](https://badge.fury.io/rb/sendcloud.svg)](http://badge.fury.io/rb/sendcloud)
7
+ [![Code Climate](https://codeclimate.com/github/pero-ict-solutions/sendcloud/badges/gpa.svg)](https://codeclimate.com/github/pero-ict-solutions/sendcloud)
8
+ [![Test Coverage](https://codeclimate.com/github/pero-ict-solutions/sendcloud/badges/coverage.svg)](https://codeclimate.com/github/pero-ict-solutions/sendcloud)
9
+
10
+ Documentation on [RubyDoc](http://www.rubydoc.info/github/pero-ict-solutions/sendcloud/master)
11
+
12
+ Ruby API Client for the [SendCloud](https://www.sendcloud.nl) delivery platform.
13
+
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'sendcloud-ruby'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install sendcloud-ruby
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it ( http://github.com/pero-ict-solutions/sendcloud/fork )
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
36
+
37
+
38
+ Copyright (c) 2014-2015 PeRo ICT Solutions
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/sendcloud.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "sendcloud/version"
2
+ require "sendcloud/base"
3
+ require "sendcloud/shipping_method"
4
+ require "sendcloud/parcel_resource"
5
+ require "sendcloud/shipment_address"
@@ -0,0 +1,30 @@
1
+ require 'httparty'
2
+
3
+ module Sendcloud
4
+ class Base
5
+ include HTTParty
6
+ format :json
7
+ base_uri 'https://panel.sendcloud.nl/api/v2/'
8
+
9
+ attr_accessor :api_key, :api_secret
10
+
11
+ #
12
+ # @param api_key [String] the `apikey` from your account settings
13
+ # @param api_secret [String] the `apisecret` from your account settings
14
+ def initialize(api_key, api_secret)
15
+ self.api_key = api_key
16
+ self.api_secret = api_secret
17
+ end
18
+
19
+ # get the auth hash to use for all the requests
20
+ # since the sendcloud api uses basic authentication
21
+ # it will be used in the subclasses like this:
22
+ # `HTTParty.get("http://twitter.com/statuses/public_timeline.json", :basic_auth => auth)`
23
+ #
24
+ # @return [Hash] the basic auth hash based on the api_key and api_secret
25
+ def auth
26
+ { username: api_key, password: api_secret}
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,61 @@
1
+ module Sendcloud
2
+ class ParcelResourceException < StandardError; end
3
+
4
+ class ParcelResource < Base
5
+ def create_parcel(name, shipment_address, shipment = {id: 1, options: []}, method_params = {})
6
+ response = self.class.post('/parcels',
7
+ body: {
8
+ parcel: {
9
+ name: name,
10
+ address: shipment_address.address,
11
+ city: shipment_address.city,
12
+ postal_code: shipment_address.postal_code,
13
+ country: shipment_address.country,
14
+ shipment: shipment,
15
+ requestShipment: false
16
+ }.merge(method_params).
17
+ merge(telephone: '', email: '', data: [])
18
+ }.to_json,
19
+ basic_auth: auth,
20
+ headers: {'Content-Type' => 'application/json'}
21
+ )
22
+ handle_response_error(response)
23
+ response['parcel']
24
+ end
25
+
26
+ def adjust_parcel(parcel_id)
27
+ response = self.class.put('/parcels',
28
+ body: {
29
+ parcel: {
30
+ id: parcel_id,
31
+ requestShipment: true
32
+ }
33
+ }.to_json,
34
+ basic_auth: auth,
35
+ headers: {'Content-Type' => 'application/json'}
36
+ )
37
+ handle_response_error(response)
38
+ response['parcel']
39
+ end
40
+
41
+ def show_parcel(parcel_id)
42
+ response = self.class.get("/parcels/#{parcel_id}", basic_auth: auth)
43
+ handle_response_error(response)
44
+ response['parcel']
45
+ end
46
+
47
+ def get_label_parcel(parcel_id)
48
+ response = self.class.get("/labels/#{parcel_id}", basic_auth: auth,
49
+ headers: {'Content-Type' => 'application/json'})
50
+ handle_response_error(response)
51
+ response['label']
52
+ end
53
+
54
+ private
55
+ def handle_response_error(response)
56
+ if response['error']
57
+ raise ParcelResourceException.new(response['error']['message'])
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ module Sendcloud
2
+ class ShipmentAddress < Struct.new(:address, :city, :postal_code, :country)
3
+
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ module Sendcloud
2
+ class ShippingMethodException < StandardError; end
3
+
4
+ class ShippingMethod < Base
5
+ def list
6
+ response = self.class.get("/shipping_methods", :basic_auth => auth)
7
+ response["shipping_methods"]
8
+ end
9
+
10
+ def get(shipping_id)
11
+ response = self.class.get("/shipping_methods/#{shipping_id}", :basic_auth => auth)
12
+ if response["error"]
13
+ raise ShippingMethodException.new(response["error"]["message"])
14
+ end
15
+ response["shipping_method"]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Sendcloud
2
+ VERSION = "1.0.0"
3
+ end
data/sendcloud.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sendcloud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sendcloud-ruby"
8
+ spec.version = Sendcloud::VERSION
9
+ spec.authors = ["Peter Berkenbosch"]
10
+ spec.email = ["peter@pero-ict.nl"]
11
+ spec.summary = %q{ruby client for the sendcloud api}
12
+ spec.description = spec.summary
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "httparty"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'vcr'
27
+ spec.add_development_dependency 'webmock'
28
+ spec.add_development_dependency 'pry'
29
+ spec.add_development_dependency 'yard'
30
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::Base do
4
+
5
+ context ".auth" do
6
+ it "returns a hash for basic_auth with api key and secret" do
7
+ basic_auth_hash = {username: "key", password: "secret"}
8
+ expect(Sendcloud::Base.new("key","secret").auth).to eql basic_auth_hash
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::ParcelResource do
4
+ let!(:new_parcel){
5
+ {
6
+ "name"=>"Rob van den Heuvel",
7
+ "shipment_address" => Sendcloud::ShipmentAddress.new('Torenallee', 'Eindhoven', '5617BC', 'NL')
8
+ }
9
+ }
10
+ context 'create Parcel' do
11
+
12
+ it 'with valid params' do
13
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
14
+ VCR.use_cassette('create_parcel') do
15
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
16
+ expect(parcel).not_to be_empty
17
+ expect(parcel).to include('name'=>'Rob van den Heuvel')
18
+ expect(parcel).to include('id')
19
+ end
20
+ end
21
+
22
+ context 'without name' do
23
+ it 'will return a error' do
24
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
25
+ VCR.use_cassette('wrong_create_parcel_without_name') do
26
+ expect{pr.create_parcel(nil, new_parcel['shipment_address'], {id: 1})}.
27
+ to raise_error(Sendcloud::ParcelResourceException, 'Name is required')
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'adjust Parcel' do
34
+ it 'with valid parcel_id' do
35
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
36
+ VCR.use_cassette('adjust_parcel') do
37
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
38
+ adjust_parcel = pr.adjust_parcel(parcel['id'])
39
+ expect(adjust_parcel).not_to be_empty
40
+ expect(adjust_parcel['status']).not_to be_empty
41
+ expect(adjust_parcel).to include('id')
42
+ end
43
+ end
44
+ it 'with invalid parcel_id' do
45
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
46
+ VCR.use_cassette('adjust_with_wrong_parcel_id') do
47
+ parcel_id = 123456
48
+ expect{pr.adjust_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
49
+ "Parcel is not found with ID: #{parcel_id}")
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'get parcel' do
55
+ it 'with valid parcel_id' do
56
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
57
+ VCR.use_cassette('get_parcel_info') do
58
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
59
+ info = pr.show_parcel(parcel['id'])
60
+ expect(info).not_to be_empty
61
+ expect(info['id']).to eql(parcel['id'])
62
+ end
63
+ end
64
+
65
+ it 'with invalid parcel_id' do
66
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
67
+ VCR.use_cassette('get_parcel_error_with_invalid_pracel_id') do
68
+ parcel_id = 123456
69
+ expect{pr.show_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
70
+ "You aren't authorized to get this parcel")
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'get label' do
76
+ it 'with valid parcel_id' do
77
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
78
+ VCR.use_cassette('get_label_for_parcel') do
79
+ parcel = pr.create_parcel(new_parcel['name'], new_parcel['shipment_address'], {id: 1})
80
+ adjust_parcel = pr.adjust_parcel(parcel['id'])
81
+ label = pr.get_label_parcel(adjust_parcel['id'])
82
+ expect(label['normal_printer']).not_to be_empty
83
+ expect(label['label_printer']).not_to be_empty
84
+ end
85
+ end
86
+
87
+ it 'with invalid parcel_id' do
88
+ pr = Sendcloud::ParcelResource.new('D74gAPTNto4N28N', 'Yb6m0YVBXtWm2zTdk')
89
+ VCR.use_cassette('get_label_for_parcel_with_invalid_id') do
90
+ parcel_id = 123456
91
+ expect{pr.get_label_parcel(parcel_id)}.to raise_error(Sendcloud::ParcelResourceException,
92
+ "Cannot find parcel with given Parcel ID (#{parcel_id})")
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sendcloud::ShippingMethod do
4
+
5
+ context ".list" do
6
+ it "returns the list of available shipping methods" do
7
+ sm = Sendcloud::ShippingMethod.new("key", "secret")
8
+ VCR.use_cassette('get_shipping_methods') do
9
+ methods = sm.list
10
+ expect(methods).to_not be_empty
11
+ end
12
+ end
13
+ end
14
+
15
+ context ".get" do
16
+
17
+ context "with correct shipping_method id" do
18
+
19
+ let(:post_nl_shipping_method_hash) {
20
+ {
21
+ "id"=>1,
22
+ "name"=>"Pakket Nederland (PostNL)",
23
+ "countries"=>[
24
+ {
25
+ "id"=>2,
26
+ "iso_3"=>"NLD",
27
+ "iso_2"=>"NL",
28
+ "name"=>"Nederland",
29
+ "price"=>5.8
30
+ }
31
+ ],
32
+ "price"=>5.8,
33
+ "options"=>[],
34
+ "combinations"=>[{"id"=>1, "name"=>"Normaal pakket"}]
35
+ }
36
+ }
37
+
38
+ it "will return the shipping method details" do
39
+ sm = Sendcloud::ShippingMethod.new("D74gAPTNto4N28N", "Yb6m0YVBXtWm2zTdk")
40
+ VCR.use_cassette('get_shipping_method') do
41
+ shipping_method = sm.get(1)
42
+ expect(shipping_method).to eql post_nl_shipping_method_hash
43
+ end
44
+ end
45
+ end
46
+
47
+ context "with invalid shipping_method id" do
48
+ it "will return a proper message" do
49
+ sm = Sendcloud::ShippingMethod.new("key", "secret")
50
+ VCR.use_cassette('get_wrong_shipping_method') do
51
+ expect{sm.get(99)}.to raise_error(Sendcloud::ShippingMethodException, "Can't find shipping method with given ID (99)")
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,30 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'sendcloud'
5
+ require 'pry'
6
+ require 'vcr'
7
+ require 'webmock'
8
+
9
+ # This file was generated by the `rspec --init` command. Conventionally, all
10
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
11
+ # Require this file using `require "spec_helper"` to ensure that it is only
12
+ # loaded once.
13
+ #
14
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
15
+ RSpec.configure do |config|
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+ end
25
+
26
+ VCR.configure do |c|
27
+ c.cassette_library_dir = 'spec/vcr_cassettes'
28
+ c.hook_into :webmock # or :fakeweb
29
+ c.ignore_hosts 'codeclimate.com'
30
+ end