ls_linkdirect_api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5321f05c60a0c21073823cbb981ed34ce7492439
4
+ data.tar.gz: b118e82ea754f7e80d43dca2beca6757fcaec427
5
+ SHA512:
6
+ metadata.gz: ff02cf9f6d5833634f9f2fcce3a4f831703cb017922a8101e37757349bafd0fad1f696e0e747c839fb093357003028879db73b98bb0183b0b204d58a7a0a3958
7
+ data.tar.gz: a5839df1bdebcb6b2100281d4e7e6affd660458b92452778eda35882c142258337c26a645e5e871c306eba8afe4da8283727d9a19f3231123c91f1d05fa441f8
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ls_linkdirect_api.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Kirk Jarvis
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,89 @@
1
+ # LsLinkdirectAPI
2
+
3
+ Ruby wrapper for [LinkShare LinkLocator Direct](http://helpcenter.linkshare.com/publisher/questions.php?questionid=50).
4
+ Supported web services:
5
+ * [TextLinks]
6
+ * [BannerLinks]
7
+ * [DRMLinks]
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'ls_linkdirect_api'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ls_linkdirect_api
22
+
23
+ ## Usage
24
+
25
+ Before using **LsLinkdirectAPI** you need to set up your publisher token first. If you use Ruby on Rails, the token can be set in a configuration file (i.e. `app/config/initializers/linkshare_api.rb`), otherwise just set it in your script. The token can be found on LinkShare's Web Services page under the Links tab.
26
+
27
+ Currently there are three services that can be used with this gem. To use those services, you name the service as the class when you declare a new instance of the class (i.e. `LsLinkdirectAPI::TextLinks.new`) see examples below.
28
+
29
+ ```ruby
30
+ require "ls_linkdirect_api" # no need for RoR
31
+ LsLinkdirectAPI.token = ENV["LINKSHARE_TOKEN"]
32
+ ```
33
+ ### Text Link Request
34
+
35
+ This request gives you the available text links. To specify the links your request returns, you can filter it using these parameters: MID, Category, Start Date, and End Date.
36
+
37
+ ```ruby
38
+ textlinks = LsLinkdirectAPI::TextLinks.new
39
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014 }
40
+ # all params are optional gem will add defaults where required
41
+ response = textlinks.get(params)
42
+ response.data.each do |item|
43
+ puts "Name: #{item.linkName}"
44
+ puts "Click URL: #{item.clickURL}"
45
+ puts "Tracking Pixil : #{item.showURL}"
46
+ puts "Text Display: #{item.textDisplay}"
47
+ end
48
+ ```
49
+ ### Banner Link Request
50
+
51
+ This feed gives you the available banner links. To obtain specific banner links, you can filter this request using these parameters: MID, Category, Size, Start Date, and End Date.
52
+
53
+ [LinkLocator Direct: Banner Size Codes](http://helpcenter.linkshare.com/publisher/questions.php?questionid=907)
54
+
55
+ ```ruby
56
+ bannerlinks = LsLinkdirectAPI:: BannerLinks.new
57
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014, size: 1 }
58
+ # all params are optional gem will add defaults where required
59
+ response = bannerlinks.get(params)
60
+ response.data.each do |item|
61
+ puts "Name: #{item.linkName}"
62
+ puts "Click URL: #{item.clickURL}"
63
+ puts "Tracking Pixil : #{item.showURL}"
64
+ puts "Text Display: #{item.textDisplay}"
65
+ puts "Image URL: #{item.imgURL}"
66
+ end
67
+ ```
68
+
69
+ ### DRM Link Request
70
+ This feed gives you the available DRM links. To obtain specific DRM links, you can filter it using these parameters: MID, Category, Start Date, and End Date.
71
+
72
+ ```ruby
73
+ drmlinks = LsLinkdirectAPI:: DRMLinks.new
74
+ params = { mid: -1, cat: -1, startDate: 01012014, endDate: 05012014 }
75
+ # all params are optional gem will add defaults where required
76
+ response = drmlinks.get(params)
77
+ response.data.each do |item|
78
+ puts "Name: #{item.linkName}"
79
+ puts "Code: #{item.code}"
80
+ end
81
+ ```
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork it ( https://github.com/[my-github-username]/ls_linkdirect_api/fork )
86
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
87
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
88
+ 4. Push to the branch (`git push origin my-new-feature`)
89
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,38 @@
1
+ require "addressable/uri"
2
+ require "cgi"
3
+ require "htmlentities"
4
+ require "httparty"
5
+ #require "net/http"
6
+ require "recursive_open_struct"
7
+ require "uri"
8
+
9
+ require "ls_linkdirect_api/api_resource"
10
+ require "ls_linkdirect_api/api_response"
11
+ require "ls_linkdirect_api/version"
12
+ require "ls_linkdirect_api/text_links"
13
+ require "ls_linkdirect_api/banner_links"
14
+ require "ls_linkdirect_api/drm_links"
15
+
16
+ require "ls_linkdirect_api/errors/error"
17
+ require "ls_linkdirect_api/errors/authentication_error"
18
+ require "ls_linkdirect_api/errors/argument_error"
19
+ require "ls_linkdirect_api/errors/not_implemented_error"
20
+ require "ls_linkdirect_api/errors/invalid_request_error"
21
+
22
+
23
+
24
+ module LsLinkdirectAPI
25
+ @api_base_url = "http://lld2.linksynergy.com/services/restLinks"
26
+ @api_timeout = 30
27
+
28
+ class << self
29
+ attr_accessor :token, :api_base_url
30
+ attr_reader :api_timeout
31
+ end
32
+
33
+ def self.api_timeout=(timeout)
34
+ raise ArgumentError, "Timeout must be a Fixnum; got #{timeout.class} instead" unless timeout.is_a? Fixnum
35
+ raise ArgumentError, "Timeout must be > 0; got #{timeout} instead" unless timeout > 0
36
+ @api_timeout = timeout
37
+ end
38
+ end
@@ -0,0 +1,104 @@
1
+ module LsLinkdirectAPI
2
+ class APIResource
3
+ include HTTParty
4
+
5
+ def class_name
6
+ self.class.name.split('::')[-1]
7
+ end
8
+
9
+ def base_path
10
+ if self.class == LsLinkdirectAPI::APIResource
11
+ raise NotImplementedError.new(
12
+ "APIResource is an abstract class. You should perform actions on its subclasses (i.e. TextLinks)"
13
+ )
14
+ end
15
+ "/get#{CGI.escape(class_name)}/"
16
+ end
17
+
18
+ def get(params = {})
19
+
20
+ unless token ||= LsLinkdirectAPI.token
21
+ raise AuthenticationError.new(
22
+ "No token provided. Set your token key using: LsLinkdirectAPI.token = 'TOKEN' " +
23
+ "You can retrieve your Your Web Services Token from the Linkshare web interface. " +
24
+ "http://helpcenter.linkshare.com/publisher/questions.php?questionid=58 for details."
25
+ )
26
+ end
27
+
28
+ if token =~ /\s/
29
+ raise AuthenticationError.new(
30
+ "Your token looks invalid. " +
31
+ "Double-check your token at http://linkshare.com"
32
+ )
33
+ end
34
+
35
+ raise ArgumentError, "Params must be a Hash; got #{params.class} instead" unless params.is_a? Hash
36
+
37
+ params.merge!({
38
+ token: token,
39
+ })
40
+ make_params_valid(params)
41
+ resource_url = LsLinkdirectAPI.api_base_url + base_path + self.params_path(params)
42
+ request(resource_url, params)
43
+ end
44
+
45
+ def request(resource_url, params)
46
+ timeout = LsLinkdirectAPI.api_timeout
47
+ begin
48
+ response = self.class.get(resource_url, query: nil, timeout: timeout)
49
+ rescue Timeout::Error
50
+ raise ConnectionError.new("Timeout error (#{timeout}s)")
51
+ end
52
+ process(response, "#{class_name}", params)
53
+ end
54
+
55
+ private
56
+
57
+ def process(response, response_name, params)
58
+ case response.code
59
+ when 200, 201, 204
60
+ APIResponse.new(response, response_name, params)
61
+ when 400, 404
62
+ raise InvalidRequestError.new(response.message, response.code)
63
+ when 401
64
+ raise AuthenticationError.new(response.message, response.code)
65
+ else
66
+ raise Error.new(response.message, response.code)
67
+ end
68
+ end
69
+
70
+ def check_date_format(date)
71
+ if date
72
+ if date =~ /(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])(19|20)\d\d/
73
+ date
74
+ else
75
+ raise ArgumentError, "Data format needs to be MMDDYYYY."
76
+ end
77
+ else
78
+ ''
79
+ end
80
+ end
81
+
82
+ def make_params_valid(params)
83
+ unless params[:mid]
84
+ params[:mid] = -1
85
+ end
86
+
87
+ unless params[:cat]
88
+ params[:cat] = -1
89
+ end
90
+
91
+ unless params[:page]
92
+ params[:page] = 1
93
+ end
94
+
95
+ unless params[:campaignID]
96
+ params[:campaignID] = -1
97
+ end
98
+
99
+ unless params[:size]
100
+ params[:size] = -1
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,36 @@
1
+ require "recursive_open_struct"
2
+
3
+ module LsLinkdirectAPI
4
+ class APIResponse
5
+ attr_reader :data, :request
6
+
7
+ def initialize(response, response_name, params)
8
+ @request = response.request
9
+ @response_name = response_name
10
+ @params = params
11
+ result = response[ "get#{response_name}Response" ]
12
+ @data = parse(result["return"])
13
+ end
14
+
15
+ def all
16
+ get_next_page = true
17
+ while get_next_page
18
+ cls = Object.const_get('LsLinkdirectAPI').const_get(@response_name)
19
+ @params[:page] += 1
20
+ next_page_response = cls.new.get(@params)
21
+ @data += next_page_response.data
22
+ get_next_page = false if next_page_response.data == []
23
+ end
24
+ @data
25
+ end
26
+
27
+ private
28
+
29
+ def parse(raw_data)
30
+ data = []
31
+ data = [RecursiveOpenStruct.new(raw_data)] if raw_data.is_a?(Hash) # If we got exactly one result, put it in an array.
32
+ raw_data.each { |i| data << RecursiveOpenStruct.new(i) } if raw_data.is_a?(Array)
33
+ data
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class BannerLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:size]}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class DRMLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class ArgumentError < Error
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class AuthenticationError < Error
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module LsLinkdirectAPI
2
+ class Error < StandardError
3
+ attr_reader :message, :code
4
+
5
+ def initialize(message = nil, code = nil)
6
+ @message = message
7
+ @code = code
8
+ end
9
+
10
+ def to_s
11
+ code_string = code.nil? ? "" : " (Code #{code})"
12
+ "#{message}#{code_string}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class InvalidRequestError < Error
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LsLinkdirectAPI
2
+ class NotImplementedError < Error
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module LsLinkdirectAPI
2
+ class TextLinks < APIResource
3
+ def params_path(params)
4
+ "#{params[:token]}/#{params[:mid]}/#{params[:cat]}/#{check_date_format(params[:startDate])}/#{check_date_format(params[:endDate])}/#{params[:campaignID]}/#{params[:page]}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module LsLinkdirectAPI
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ls_linkdirect_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ls_linkdirect_api"
8
+ spec.version = LsLinkdirectAPI::VERSION
9
+ spec.authors = ["Kirk Jarvis"]
10
+ spec.email = ["zuuzlo@yahoo.com"]
11
+ spec.summary = %q{Ruby wrapper for accessing Linkshare LinkLocator Direct API using REST. }
12
+ spec.description = %q{This wrapper will access the Linkshare LinkLocator Direct Web Service, which is available to all publishers. The authentication of a publisher is done using the publisher’s Web services token. Publishers that do not have a Web services token, can go to Web Services under the Links tab on the Publisher Dashboard and click the button to generate a token. Since the token is used for authentication, it is a required parameter for all requests.}
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 "addressable", "~> 2.3.5"
22
+ spec.add_dependency "htmlentities", "~> 4.3.1"
23
+ spec.add_dependency "httparty", "~> 0.11.0"
24
+ spec.add_dependency "recursive-open-struct", "~> 0.4.3"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.6"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "webmock"
30
+ spec.add_development_dependency "pry"
31
+ end
@@ -0,0 +1,239 @@
1
+ require 'spec_helper'
2
+
3
+ describe LsLinkdirectAPI do
4
+ context "errors" do
5
+
6
+ it "raise connection error if times out" do
7
+ expect{ LsLinkdirectAPI.api_timeout = "" }.to raise_error(LsLinkdirectAPI::ArgumentError,"Timeout must be a Fixnum; got String instead")
8
+ end
9
+
10
+ it "raise connection error if times out" do
11
+ expect{ LsLinkdirectAPI.api_timeout = 0 }.to raise_error(LsLinkdirectAPI::ArgumentError,"Timeout must be > 0; got 0 instead")
12
+ end
13
+
14
+
15
+ it "raises authenication if token not present" do
16
+ textlinks = LsLinkdirectAPI::TextLinks.new
17
+ expect{ textlinks.get({})}.to raise_error(LsLinkdirectAPI::AuthenticationError)
18
+ end
19
+
20
+ it "raises authenication if token has spaces" do
21
+ LsLinkdirectAPI.token = 'afajfdafd dfjaskdfk'
22
+ textlinks = LsLinkdirectAPI::TextLinks.new
23
+ expect{ textlinks.get({})}.to raise_error(LsLinkdirectAPI::AuthenticationError)
24
+ end
25
+
26
+ it "raises ArgumentError if params is not a hash" do
27
+ LsLinkdirectAPI.token = 'afajfdafddfjaskdfk'
28
+ textlinks = LsLinkdirectAPI::TextLinks.new
29
+ expect{ textlinks.get('text')}.to raise_error(LsLinkdirectAPI::ArgumentError)
30
+ end
31
+
32
+ it "base_path for TextLinks is getTextLinks" do
33
+ textlinks = LsLinkdirectAPI::TextLinks.new
34
+ expect(textlinks.base_path).to eq("/getTextLinks/")
35
+ end
36
+
37
+ it "raises Not Implemented Error if APIResource is accessed" do
38
+ textlinks = LsLinkdirectAPI::APIResource.new
39
+ expect{ textlinks.base_path }.to raise_error(LsLinkdirectAPI::NotImplementedError)
40
+ end
41
+
42
+ it "raises ArgumentError on wrong date format" do
43
+ LsLinkdirectAPI.token = 'afajfdafddfjaskdfk'
44
+ textlinks = LsLinkdirectAPI::TextLinks.new
45
+ params = { endDate: 'dec 10'}
46
+ expect{ textlinks.get(params)}.to raise_error(LsLinkdirectAPI::ArgumentError)
47
+ end
48
+ end
49
+
50
+ context "response code is not 200, 201, 204" do
51
+ it "raise Invalid Request Error if response is 400" do
52
+ LsLinkdirectAPI.token = '400'
53
+ xml_response = <<-XML
54
+ <?xml version="1.0" encoding="UTF-8"?>
55
+ <ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat"><ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat">Invalid URL/Verb combination. Verb: GET Path: /etTextLinks/06a400a42d5ee2822cc4342b7cedf714bffa542768b1c06d571c0ebe8aa85203/38605/-1//05162014/-1/1</ns1:faultstring></ns1:XMLFault>
56
+ XML
57
+ stub_request(
58
+ :get,
59
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/400/-1/-1//05162014/-1/1"
60
+ ).
61
+ to_return(
62
+ status: 400,
63
+ body: xml_response,
64
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
65
+ )
66
+ textlinks = LsLinkdirectAPI::TextLinks.new
67
+ params = { endDate: '05162014'}
68
+ expect { textlinks.get(params) }.to raise_error(LsLinkdirectAPI::InvalidRequestError)
69
+ end
70
+ end
71
+ context "response code is 200 TextLinks" do
72
+ before do
73
+ LsLinkdirectAPI.token = '200'
74
+ xml_response = <<-XML
75
+ <?xml version="1.0" encoding="UTF-8"?>
76
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200321300</ns1:categoryID><ns1:categoryName>Toys</ns1:categoryName><ns1:linkID>3997</ns1:linkID><ns1:linkName>5/15-5/18 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3997&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>www.kohls.com/catalog.jsp?N=3000060558</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3997&amp;type=3</ns1:showURL><ns1:startDate>May 15, 2014</ns1:startDate><ns1:textDisplay>Extra 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:textDisplay></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3986</ns1:linkID><ns1:linkName>Free Shipping $50+ with Code FREE50MAY</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3986&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3986&amp;type=3</ns1:showURL><ns1:startDate>May 16, 2014</ns1:startDate><ns1:textDisplay>Free Shipping $50+ with Code FREE50MAY. Valid 5/16-5/18.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
77
+ XML
78
+ stub_request(
79
+ :get,
80
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/1"
81
+ ).
82
+ to_return(
83
+ status: 200,
84
+ body: xml_response,
85
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
86
+ )
87
+ end
88
+
89
+ let(:textlinks) { LsLinkdirectAPI::TextLinks.new }
90
+ let(:params) { { endDate: '05162014'} }
91
+ let(:response) { textlinks.get(params) }
92
+
93
+ it "first record linkid is 3997" do
94
+ expect(response.data.first.linkID).to eq("3997")
95
+ end
96
+
97
+ it "last record linkid is 3986" do
98
+ expect(response.data.last.linkID).to eq("3986")
99
+ end
100
+ end
101
+
102
+ context "response code is 200 BannerLinks" do
103
+ before do
104
+ LsLinkdirectAPI.token = '200'
105
+ xml_response = <<-XML
106
+ <?xml version="1.0" encoding="UTF-8"?>
107
+ <ns1:getBannerLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3</ns1:linkID><ns1:linkName>Candie's</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3&amp;type=4</ns1:clickURL><ns1:endDate>Dec 31, 2019</ns1:endDate><ns1:height>31</ns1:height><ns1:iconURL>http://merchant.linksynergy.com/fs/banners/38605/38605_3.jpg</ns1:iconURL><ns1:imgURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3&amp;type=4</ns1:imgURL><ns1:landURL>http://www.kohls.com/catalog/juniors-candie-s-clothing.jsp?CN=4294719935+4294875004+4294719810</ns1:landURL><ns1:serverType>4</ns1:serverType><ns1:size>7</ns1:size><ns1:startDate>Jul 18, 2013</ns1:startDate><ns1:width>88</ns1:width></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>4</ns1:linkID><ns1:linkName>Candie's</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.4&amp;type=4</ns1:clickURL><ns1:endDate>Dec 31, 2019</ns1:endDate><ns1:height>90</ns1:height><ns1:iconURL>http://merchant.linksynergy.com/fs/banners/38605/38605_4.jpg</ns1:iconURL><ns1:imgURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.4&amp;type=4</ns1:imgURL><ns1:landURL>http://www.kohls.com/catalog/juniors-candie-s-clothing.jsp?CN=4294719935+4294875004+4294719810</ns1:landURL><ns1:serverType>4</ns1:serverType><ns1:size>5</ns1:size><ns1:startDate>Jul 18, 2013</ns1:startDate><ns1:width>120</ns1:width></ns1:return></ns1:getBannerLinksResponse>
108
+ XML
109
+ stub_request(
110
+ :get,
111
+ "http://lld2.linksynergy.com/services/restLinks/getBannerLinks/200/-1/-1//05162014/-1/-1/1"
112
+ ).
113
+ to_return(
114
+ status: 200,
115
+ body: xml_response,
116
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
117
+ )
118
+ end
119
+
120
+ let(:bannerlinks) { LsLinkdirectAPI::BannerLinks.new }
121
+ let(:params) { { endDate: '05162014'} }
122
+ let(:response) { bannerlinks.get(params) }
123
+
124
+ it "first record linkid is 3" do
125
+ expect(response.data.first.linkID).to eq("3")
126
+ end
127
+
128
+ it "last record linkid is 4" do
129
+ expect(response.data.last.linkID).to eq("4")
130
+ end
131
+ end
132
+
133
+ context "response code is 200 DRMLinks" do
134
+ before do
135
+ LsLinkdirectAPI.token = '200'
136
+ xml_response = <<-XML
137
+ <?xml version="1.0" encoding="UTF-8"?>
138
+ <ns1:getDRMLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>78</ns1:categoryID><ns1:categoryName>Dynamic Media - Banners</ns1:categoryName><ns1:linkID>6885</ns1:linkID><ns1:linkName>Banner 300x250</ns1:linkName><ns1:mid>14028</ns1:mid><ns1:nid>1</ns1:nid><ns1:code>&lt;script src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.6885&amp;catid=78&amp;gridnum=13&amp;type=14'>&lt;/script>&lt;noscript>&lt;a href='http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=299527&amp;type=4&amp;subid='>&lt;img src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527&amp;subid=&amp;type=4&amp;gridnum=13'>&lt;/a>&lt;/noscript></ns1:code><ns1:endDate>Oct 13, 2017</ns1:endDate><ns1:height>250</ns1:height><ns1:serverType>4</ns1:serverType><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.6885&amp;catid=78&amp;gridnum=13&amp;type=14</ns1:showURL><ns1:size>13</ns1:size><ns1:startDate>Oct 13, 2011</ns1:startDate><ns1:width>300</ns1:width></ns1:return><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>78</ns1:categoryID><ns1:categoryName>Dynamic Media - Banners</ns1:categoryName><ns1:linkID>4027</ns1:linkID><ns1:linkName>Banner 120x240</ns1:linkName><ns1:mid>14028</ns1:mid><ns1:nid>1</ns1:nid><ns1:code>&lt;script src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.4027&amp;catid=78&amp;gridnum=8&amp;type=14'>&lt;/script>&lt;noscript>&lt;a href='http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=299527&amp;type=4&amp;subid='>&lt;img src='http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527&amp;subid=&amp;type=4&amp;gridnum=8'>&lt;/a>&lt;/noscript></ns1:code><ns1:endDate>Feb 28, 2017</ns1:endDate><ns1:height>240</ns1:height><ns1:serverType>4</ns1:serverType><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=299527.4027&amp;catid=78&amp;gridnum=8&amp;type=14</ns1:showURL><ns1:size>8</ns1:size><ns1:startDate>Feb 27, 2007</ns1:startDate><ns1:width>120</ns1:width></ns1:return></ns1:getDRMLinksResponse>
139
+ XML
140
+ stub_request(
141
+ :get,
142
+ "http://lld2.linksynergy.com/services/restLinks/getDRMLinks/200/-1/-1//05162014/-1/1"
143
+ ).
144
+ to_return(
145
+ status: 200,
146
+ body: xml_response,
147
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
148
+ )
149
+ end
150
+
151
+ let(:drmlinks) { LsLinkdirectAPI::DRMLinks.new }
152
+ let(:params) { { endDate: '05162014'} }
153
+ let(:response) { drmlinks.get(params) }
154
+
155
+ it "first record linkid is 6885" do
156
+ expect(response.data.first.linkID).to eq("6885")
157
+ end
158
+
159
+ it "last record linkid is 4027" do
160
+ expect(response.data.last.linkID).to eq("4027")
161
+ end
162
+ end
163
+ context "multi page using all" do
164
+ before do
165
+ LsLinkdirectAPI.token = '200'
166
+ xml_response0 = <<-XML
167
+ <?xml version="1.0" encoding="UTF-8"?>
168
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200321300</ns1:categoryID><ns1:categoryName>Toys</ns1:categoryName><ns1:linkID>3997</ns1:linkID><ns1:linkName>5/15-5/18 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3997&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>www.kohls.com/catalog.jsp?N=3000060558</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3997&amp;type=3</ns1:showURL><ns1:startDate>May 15, 2014</ns1:startDate><ns1:textDisplay>Extra 10% off Outdoor Toys. Promo Code OUTDOOR10</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
169
+ XML
170
+ stub_request(
171
+ :get,
172
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/1"
173
+ ).
174
+ to_return(
175
+ status: 200,
176
+ body: xml_response0,
177
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
178
+ )
179
+
180
+ xml_response1 = <<-XML
181
+ <?xml version="1.0" encoding="UTF-8"?>
182
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>0</ns1:categoryID><ns1:categoryName>Default</ns1:categoryName><ns1:linkID>3986</ns1:linkID><ns1:linkName>Free Shipping $50+ with Code FREE50MAY</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3986&amp;type=3</ns1:clickURL><ns1:endDate>May 19, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3986&amp;type=3</ns1:showURL><ns1:startDate>May 16, 2014</ns1:startDate><ns1:textDisplay>Free Shipping $50+ with Code FREE50MAY. Valid 5/16-5/18.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
183
+ XML
184
+ stub_request(
185
+ :get,
186
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/2"
187
+ ).
188
+ to_return(
189
+ status: 200,
190
+ body: xml_response1,
191
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
192
+ )
193
+
194
+ xml_response2 = <<-XML
195
+ <?xml version="1.0" encoding="UTF-8"?>
196
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"><ns1:return><ns1:campaignID>0</ns1:campaignID><ns1:categoryID>200334761</ns1:categoryID><ns1:categoryName>Jewelry</ns1:categoryName><ns1:linkID>3961</ns1:linkID><ns1:linkName>Get Set for Summer Sale</ns1:linkName><ns1:mid>38605</ns1:mid><ns1:nid>1</ns1:nid><ns1:clickURL>http://click.linksynergy.com/fs-bin/click?id=V8uMkWlCTes&amp;offerid=328293.3961&amp;type=3</ns1:clickURL><ns1:endDate>May 21, 2014</ns1:endDate><ns1:landURL>http://www.kohls.com/catalog/jewelry.jsp?CN=4294719765&amp;N=4294719765+3000060490</ns1:landURL><ns1:showURL>http://ad.linksynergy.com/fs-bin/show?id=V8uMkWlCTes&amp;bids=328293.3961&amp;type=3</ns1:showURL><ns1:startDate>May 14, 2014</ns1:startDate><ns1:textDisplay>$1599.99 14k gold certified 1-ct. T.W. diamond solitaire rings. Select styles. reg. $4250. Valid 5/14-5/20.</ns1:textDisplay></ns1:return></ns1:getTextLinksResponse>
197
+ XML
198
+ stub_request(
199
+ :get,
200
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/3"
201
+ ).
202
+ to_return(
203
+ status: 200,
204
+ body: xml_response2,
205
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
206
+ )
207
+
208
+ xml_response3 = <<-XML
209
+ <?xml version="1.0" encoding="UTF-8"?>
210
+ <ns1:getTextLinksResponse xmlns:ns1="http://endpoint.linkservice.linkshare.com/"></ns1:getTextLinksResponse>
211
+ XML
212
+ stub_request(
213
+ :get,
214
+ "http://lld2.linksynergy.com/services/restLinks/getTextLinks/200/-1/-1//05162014/-1/4"
215
+ ).
216
+ to_return(
217
+ status: 200,
218
+ body: xml_response3,
219
+ headers: { "Content-type" => "text/xml; charset=UTF-8" }
220
+ )
221
+ end
222
+
223
+ let(:textlinks) { LsLinkdirectAPI::TextLinks.new }
224
+ let(:params) { { endDate: '05162014'} }
225
+ let(:response) { textlinks.get(params) }
226
+
227
+ it "first record linkid is 3997" do
228
+ expect(response.all.first.linkID).to eq("3997")
229
+ end
230
+
231
+ it "last record linkid is 3961" do
232
+ expect(response.all.last.linkID).to eq("3961")
233
+ end
234
+
235
+ it "has 3 text links" do
236
+ expect(response.all.size).to eq(3)
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'webmock/rspec'
4
+ require 'ls_linkdirect_api'
5
+ #require_relative './support/fake_pepperjam_api'
6
+
7
+ RSpec.configure do |config|
8
+ =begin
9
+ config.before(:each) do
10
+ stub_request(:any, /api.pepperjamnetwork.com/ ).to_rack( FakePepperjamApi )
11
+ end
12
+ =end
13
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ls_linkdirect_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Kirk Jarvis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: addressable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: htmlentities
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 4.3.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 4.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: httparty
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.11.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.11.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: recursive-open-struct
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: This wrapper will access the Linkshare LinkLocator Direct Web Service,
140
+ which is available to all publishers. The authentication of a publisher is done
141
+ using the publisher’s Web services token. Publishers that do not have a Web services
142
+ token, can go to Web Services under the Links tab on the Publisher Dashboard and
143
+ click the button to generate a token. Since the token is used for authentication,
144
+ it is a required parameter for all requests.
145
+ email:
146
+ - zuuzlo@yahoo.com
147
+ executables: []
148
+ extensions: []
149
+ extra_rdoc_files: []
150
+ files:
151
+ - .gitignore
152
+ - .rspec
153
+ - Gemfile
154
+ - LICENSE.txt
155
+ - README.md
156
+ - Rakefile
157
+ - lib/ls_linkdirect_api.rb
158
+ - lib/ls_linkdirect_api/api_resource.rb
159
+ - lib/ls_linkdirect_api/api_response.rb
160
+ - lib/ls_linkdirect_api/banner_links.rb
161
+ - lib/ls_linkdirect_api/drm_links.rb
162
+ - lib/ls_linkdirect_api/errors/argument_error.rb
163
+ - lib/ls_linkdirect_api/errors/authentication_error.rb
164
+ - lib/ls_linkdirect_api/errors/error.rb
165
+ - lib/ls_linkdirect_api/errors/invalid_request_error.rb
166
+ - lib/ls_linkdirect_api/errors/not_implemented_error.rb
167
+ - lib/ls_linkdirect_api/text_links.rb
168
+ - lib/ls_linkdirect_api/version.rb
169
+ - ls_linkdirect_api.gemspec
170
+ - spec/ls_linkdirect_api_spec.rb
171
+ - spec/spec_helper.rb
172
+ homepage: ''
173
+ licenses:
174
+ - MIT
175
+ metadata: {}
176
+ post_install_message:
177
+ rdoc_options: []
178
+ require_paths:
179
+ - lib
180
+ required_ruby_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ required_rubygems_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ requirements: []
191
+ rubyforge_project:
192
+ rubygems_version: 2.0.3
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: Ruby wrapper for accessing Linkshare LinkLocator Direct API using REST.
196
+ test_files:
197
+ - spec/ls_linkdirect_api_spec.rb
198
+ - spec/spec_helper.rb