queue_it 1.0.0 → 1.1.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 +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +87 -1
- data/lib/faraday/raise_http_exception.rb +48 -0
- data/lib/queue_it/api/client.rb +53 -0
- data/lib/queue_it/api/error.rb +20 -0
- data/lib/queue_it/api/event.rb +121 -0
- data/lib/queue_it/version.rb +1 -1
- data/lib/queue_it.rb +2 -0
- data/queue_it.gemspec +7 -4
- data/spec/queue_it/api/client_spec.rb +121 -0
- data/spec/queue_it/api/event_spec.rb +198 -0
- metadata +71 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8150d61b7d0ab15e25a4f0fab5c03c467971e3d2
|
4
|
+
data.tar.gz: 973591f75fa2065da623ffdde2ba528988d6c6c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64388a8c6c1491f80164f130450363fe307145857cef71fb4980c5ea9e7b6d378364649d149ad0d3d24706fae84b9ef2732039c14ac66213e106758da9eefb8f
|
7
|
+
data.tar.gz: caf23fffccda918e9f8c0f1dad37cd48b714c507d24afb43dc136d58830848bac51686a704820b888856b31d7e426197df28ce9114c20550d41ab6eca65a47d5
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
### 1.1.0 - 2015-05-07
|
2
|
+
|
3
|
+
* Basic Api 2.0.beta integration
|
4
|
+
* https://api2.queue-it.net
|
5
|
+
* `QueueIt::Api::Client`
|
6
|
+
* Allows to perform request with `JSON` encoded data to proper endpoint
|
7
|
+
* Debugging mode present
|
8
|
+
* `QueueIt::Api::Event`
|
9
|
+
* Creates or updates queue with some basic setup which fits our current needs
|
10
|
+
* Sets queue speed
|
11
|
+
|
12
|
+
### 1.0.0 - 2014-11-06
|
13
|
+
|
14
|
+
* Provides `#protect_with_queue!` method
|
15
|
+
* renders page which allows to redirect users to Queue-It
|
16
|
+
* handles KnowUserSecretKey verification
|
17
|
+
* Provides `#destroy_all_queue_it_sessions` method
|
18
|
+
* clears queue which pushes client from queue after successful purchase
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ $ gem install queue_it
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
We are using Queue-it on http://billetto.co.
|
27
|
+
We are using Queue-it on http://billetto.co.uk, and we create our queued events like this:
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
event = create(:event,
|
@@ -74,6 +74,92 @@ class EventsController < ApplicationController
|
|
74
74
|
end
|
75
75
|
```
|
76
76
|
|
77
|
+
### API
|
78
|
+
#### Client
|
79
|
+
|
80
|
+
Initialize client to pass it as a dependency to `Event` instance.
|
81
|
+
|
82
|
+
``` ruby
|
83
|
+
client = QueueIt::Api::Client.new(api_key: "SECRET_API_KEY")
|
84
|
+
```
|
85
|
+
|
86
|
+
#### Event
|
87
|
+
##### #create_or_update
|
88
|
+
Handles: https://api2.queue-it.net/Help/Api/PUT-2_0_beta-event-eventId
|
89
|
+
|
90
|
+
Basic usage
|
91
|
+
``` ruby
|
92
|
+
event = QueueIt::Api::Event.new(client)
|
93
|
+
|
94
|
+
event.create_or_update(event_id: 'justatestevent',
|
95
|
+
display_name: "Test event",
|
96
|
+
start_time: Time.now,
|
97
|
+
redirect_url: 'https://example.com/en/events/not-so-fancy-event/tickets')
|
98
|
+
# produces
|
99
|
+
{
|
100
|
+
"QueueUrl"=>"http://justatestevent-examplecom.queue-it.net/?c=examplecom&e=justatestevent",
|
101
|
+
"EventId"=>"justatestevent",
|
102
|
+
"PreQueueStartLocalTime"=>"2015-05-07T13:29:00.0000000Z",
|
103
|
+
"EventStartLocalTime"=>"2015-05-07T14:29:00.0000000Z",
|
104
|
+
"EventEndLocalTime"=>"2016-05-06T19:29:00.0000000Z",
|
105
|
+
"QueueStatus"=>"Running",
|
106
|
+
"LastPassedAutoTestRun"=>"",
|
107
|
+
"DisplayName"=>"Test event",
|
108
|
+
"RedirectUrl"=>"https://example.com/en/events/not-so-fancy-event/tickets",
|
109
|
+
"Description"=>"",
|
110
|
+
"TimeZone"=>"UTC",
|
111
|
+
"PreQueueStartTime"=>"2015-05-07T13:29:00.0000000Z",
|
112
|
+
"EventStartTime"=>"2015-05-07T14:29:00.0000000Z",
|
113
|
+
"EventEndTime"=>"2016-05-06T20:29:00.0000000Z",
|
114
|
+
"EventCulture"=>"en-US",
|
115
|
+
"MaxNoOfRedirectsPrQueueId"=>"1",
|
116
|
+
"QueueNumberValidityInMinutes"=>"15",
|
117
|
+
"AfterEventLogic"=>"RedirectUsersToTargetPage",
|
118
|
+
"AfterEventRedirectPage"=>"",
|
119
|
+
"UseSSL"=>"Auto",
|
120
|
+
"JavaScriptSupportEnabled"=>"False",
|
121
|
+
"TargetUrlSupportEnabled"=>"False",
|
122
|
+
"SafetyNetMode"=>"Disabled",
|
123
|
+
"KnowUserSecurity"=>"MD5Hash",
|
124
|
+
"KnowUserSecretKey"=>"SECRET",
|
125
|
+
"CustomLayout"=>"Default layout by Queue-it",
|
126
|
+
"XUsersInFrontOfYou"=>"0",
|
127
|
+
"TargetUrlValidationRegex"=>"",
|
128
|
+
"DomainAlias"=>"justatestevent-examplecom.queue-it.net",
|
129
|
+
"AllowedCustomLayouts"=>[],
|
130
|
+
"BrowserCultureEnabled"=>"True",
|
131
|
+
"IdleQueueLogic"=>"UseBeforePage",
|
132
|
+
"IdleQueueRedirectPage"=>""
|
133
|
+
}
|
134
|
+
```
|
135
|
+
|
136
|
+
Available named attributes
|
137
|
+
``` ruby
|
138
|
+
event_id:
|
139
|
+
display_name:
|
140
|
+
start_time:
|
141
|
+
end_time:
|
142
|
+
know_user_secret_key:
|
143
|
+
redirect_url:
|
144
|
+
description:
|
145
|
+
max_redirects_per_minute:
|
146
|
+
event_culture_name:
|
147
|
+
time_zone:
|
148
|
+
queue_number_validity_in_minutes:
|
149
|
+
```
|
150
|
+
|
151
|
+
##### #set_speed
|
152
|
+
|
153
|
+
Set redirect speed on an event queue.
|
154
|
+
|
155
|
+
See: https://api2.queue-it.net/Help/Api/PUT-2_0_beta-event-eventId-queue-speed
|
156
|
+
|
157
|
+
``` ruby
|
158
|
+
event = QueueIt::Api::Event.new(client)
|
159
|
+
|
160
|
+
event.set_speed(event_id: "justatestevent", max_redirects_per_minute: 15)
|
161
|
+
```
|
162
|
+
|
77
163
|
## Contributing
|
78
164
|
|
79
165
|
1. Fork it
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module FaradayMiddleware
|
5
|
+
class RaiseHttpException < Faraday::Middleware
|
6
|
+
def call(env)
|
7
|
+
@app.call(env).on_complete do |response|
|
8
|
+
case response[:status].to_i
|
9
|
+
when 400
|
10
|
+
raise QueueIt::Api::BadRequest.new(response.body, error_details(response))
|
11
|
+
when 403
|
12
|
+
raise QueueIt::Api::Forbidden.new(response.body, error_details(response))
|
13
|
+
when 404
|
14
|
+
raise QueueIt::Api::NotFound.new(response.body, error_details(response))
|
15
|
+
when 500
|
16
|
+
raise QueueIt::Api::InternalServerError.new(response.body, error_details(response))
|
17
|
+
when 503
|
18
|
+
raise QueueIt::Api::ServiceUnavailable.new(response.body, error_details(response))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def error_response_body(code, text)
|
26
|
+
{ "ErrorCode" => code, "ErrorText" => text }
|
27
|
+
end
|
28
|
+
|
29
|
+
def acts_like_json?(response_body)
|
30
|
+
!response_body.nil? && !response_body.empty? && response_body.kind_of?(String)
|
31
|
+
end
|
32
|
+
|
33
|
+
def parse_json(body)
|
34
|
+
JSON.parse(body)
|
35
|
+
rescue JSON::ParserError
|
36
|
+
error_response_body(nil, body)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_body(response_body)
|
40
|
+
acts_like_json?(response_body) ? parse_json(response_body) : error_response_body(nil, nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
def error_details(response)
|
44
|
+
response_body = parse_body(response.body)
|
45
|
+
{ status: response[:status].to_i, code: response_body["ErrorCode"], text: response_body["ErrorText"] }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
require 'faraday/raise_http_exception'
|
5
|
+
require 'queue_it/api/error'
|
6
|
+
|
7
|
+
module QueueIt
|
8
|
+
module Api
|
9
|
+
class Client
|
10
|
+
JSON_FORMAT = "application/json".freeze
|
11
|
+
ENDPOINT_URL = URI("https://api2.queue-it.net/2_0_beta/event").freeze
|
12
|
+
|
13
|
+
def initialize(api_key: api_key, debug: false)
|
14
|
+
self.api_key = api_key
|
15
|
+
self.debug = debug
|
16
|
+
end
|
17
|
+
|
18
|
+
def put(path, body)
|
19
|
+
connection.put(path, body)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_accessor :api_key, :debug
|
25
|
+
|
26
|
+
def options
|
27
|
+
{
|
28
|
+
url: ENDPOINT_URL.dup,
|
29
|
+
headers: {
|
30
|
+
accept: JSON_FORMAT,
|
31
|
+
content_type: JSON_FORMAT,
|
32
|
+
"Api-Key" => api_key,
|
33
|
+
},
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def debug?
|
38
|
+
debug
|
39
|
+
end
|
40
|
+
|
41
|
+
def connection
|
42
|
+
@connection ||= Faraday.new(options) do |builder|
|
43
|
+
builder.request :json
|
44
|
+
builder.response :logger, nil, { bodies: true } if debug?
|
45
|
+
builder.response :json, content_type: /\bjson$/
|
46
|
+
|
47
|
+
builder.adapter Faraday.default_adapter
|
48
|
+
builder.use FaradayMiddleware::RaiseHttpException
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module QueueIt
|
2
|
+
module Api
|
3
|
+
class Error < StandardError
|
4
|
+
attr_accessor :status, :code, :text
|
5
|
+
|
6
|
+
def initialize(msg = nil, status: nil, code: nil, text: nil)
|
7
|
+
self.code = code
|
8
|
+
self.text = text
|
9
|
+
self.status = status
|
10
|
+
super(msg)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
BadRequest = Class.new(Error)
|
15
|
+
Forbidden = Class.new(Error)
|
16
|
+
NotFound = Class.new(Error)
|
17
|
+
InternalServerError = Class.new(Error)
|
18
|
+
ServiceUnavailable = Class.new(Error)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module QueueIt
|
6
|
+
module Api
|
7
|
+
class Event
|
8
|
+
InvalidEventIdFormat = Class.new(StandardError)
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
self.client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_or_update(event_id:, display_name:, start_time:, know_user_secret_key: nil, redirect_url:, end_time: nil, description: "", event_culture_name: "en-US", time_zone: "UTC", queue_number_validity_in_minutes: 15)
|
15
|
+
raise InvalidEventIdFormat unless valid_event_id_format?(event_id)
|
16
|
+
|
17
|
+
attributes = queue_attributes(
|
18
|
+
start_time: start_time,
|
19
|
+
end_time: end_time,
|
20
|
+
know_user_secret_key: know_user_secret_key,
|
21
|
+
redirect_url: redirect_url,
|
22
|
+
description: description,
|
23
|
+
display_name: display_name,
|
24
|
+
event_culture_name: event_culture_name,
|
25
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes,
|
26
|
+
time_zone: time_zone)
|
27
|
+
|
28
|
+
perform_request(:put, event_id, attributes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_speed(event_id:, max_redirects_per_minute:)
|
32
|
+
raise InvalidEventIdFormat unless valid_event_id_format?(event_id)
|
33
|
+
|
34
|
+
number_of_redirects = [max_redirects_per_minute.to_i, QUEUE_IT_MINIMAL_NUMBER_OF_REDIRECTS_PER_MINUTE].max
|
35
|
+
attributes = { "MaxRedirectsPerMinute" => "#{number_of_redirects}" }
|
36
|
+
|
37
|
+
perform_request(:put, "#{event_id}/queue/speed", attributes)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_accessor :client
|
43
|
+
|
44
|
+
ONE_YEAR = 31557600
|
45
|
+
ONE_HOUR = 3600
|
46
|
+
|
47
|
+
MICROSOFT_TIME_ZONE_INDEX_VALUES = {
|
48
|
+
"Europe/Copenhagen" => "Romance Standard Time",
|
49
|
+
"Europe/Helsinki" => "FLE Standard Time",
|
50
|
+
"Europe/London" => "GMT Standard Time",
|
51
|
+
"Europe/Paris" => "GMT Standard Time",
|
52
|
+
"Paris" => "Romance Standard Time",
|
53
|
+
"Stockholm" => "W. Europe Standard Time",
|
54
|
+
}.freeze
|
55
|
+
|
56
|
+
EVENT_ID_FORMAT = /\A[a-zA-z0-9]{1,20}\z/.freeze
|
57
|
+
QUEUE_IT_ISO8601_TIME_PRECISION = 7
|
58
|
+
QUEUE_IT_MINIMAL_NUMBER_OF_REDIRECTS_PER_MINUTE = 5
|
59
|
+
|
60
|
+
def valid_event_id_format?(event_id)
|
61
|
+
"#{event_id}".match(EVENT_ID_FORMAT)
|
62
|
+
end
|
63
|
+
|
64
|
+
def utc_start_time(start_time)
|
65
|
+
start_time.utc
|
66
|
+
end
|
67
|
+
|
68
|
+
def utc_end_time(start_time, end_time)
|
69
|
+
end_time && end_time.utc || utc_start_time(start_time) + ONE_YEAR
|
70
|
+
end
|
71
|
+
|
72
|
+
def pre_queue_start_time(start_time)
|
73
|
+
start_time.utc - ONE_HOUR
|
74
|
+
end
|
75
|
+
|
76
|
+
def format_time(time)
|
77
|
+
time.iso8601(QUEUE_IT_ISO8601_TIME_PRECISION)
|
78
|
+
end
|
79
|
+
|
80
|
+
def translate_time_zone(time_zone)
|
81
|
+
MICROSOFT_TIME_ZONE_INDEX_VALUES.fetch(time_zone, time_zone)
|
82
|
+
end
|
83
|
+
|
84
|
+
def queue_attributes(start_time:, end_time:, know_user_secret_key:, redirect_url:, description:, display_name:, event_culture_name:, queue_number_validity_in_minutes:, time_zone:)
|
85
|
+
{
|
86
|
+
"DisplayName" => display_name,
|
87
|
+
"RedirectUrl" => URI(redirect_url).to_s,
|
88
|
+
"Description" => description,
|
89
|
+
"TimeZone" => translate_time_zone(time_zone),
|
90
|
+
"PreQueueStartTime" => format_time( pre_queue_start_time(start_time) ),
|
91
|
+
"EventStartTime" => format_time( utc_start_time(start_time) ),
|
92
|
+
"EventEndTime" => format_time( utc_end_time(start_time, end_time) ),
|
93
|
+
"EventCulture" => event_culture_name,
|
94
|
+
"MaxNoOfRedirectsPrQueueId" => "1",
|
95
|
+
"QueueNumberValidityInMinutes" => "#{queue_number_validity_in_minutes}",
|
96
|
+
"AfterEventLogic" => "RedirectUsersToTargetPage",
|
97
|
+
"AfterEventRedirectPage" => "",
|
98
|
+
"UseSSL" => "Auto",
|
99
|
+
"JavaScriptSupportEnabled" => "False",
|
100
|
+
"TargetUrlSupportEnabled" => "False",
|
101
|
+
"SafetyNetMode" => "Disabled",
|
102
|
+
"KnowUserSecurity" => "MD5Hash",
|
103
|
+
"KnowUserSecretKey" => know_user_secret_key,
|
104
|
+
"CustomLayout" => "Default layout by Queue-it",
|
105
|
+
"XUsersInFrontOfYou" => nil,
|
106
|
+
"TargetUrlValidationRegex" => "",
|
107
|
+
"DomainAlias" => "",
|
108
|
+
"AllowedCustomLayouts" => [],
|
109
|
+
"BrowserCultureEnabled" => "True",
|
110
|
+
"IdleQueueLogic" => "UseBeforePage",
|
111
|
+
"IdleQueueRedirectPage" => ""
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def perform_request(method, path, body = {})
|
116
|
+
json_response = client.public_send(method, path, body)
|
117
|
+
json_response.body
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/queue_it/version.rb
CHANGED
data/lib/queue_it.rb
CHANGED
data/queue_it.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'queue_it/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "queue_it"
|
8
8
|
spec.version = QueueIt::VERSION
|
9
|
-
spec.authors = ["
|
10
|
-
spec.email = ["
|
9
|
+
spec.authors = ["Billetto"]
|
10
|
+
spec.email = ["development@billetto.dk"]
|
11
11
|
spec.description = %q{Gem to handle the implementation of http://queue-it.net!}
|
12
12
|
spec.summary = %q{Gem to handle the implementation of http://queue-it.net}
|
13
13
|
spec.homepage = "https://github.com/gfish/queue_it"
|
@@ -18,8 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_runtime_dependency
|
21
|
+
spec.add_runtime_dependency "addressable", "~> 2.3"
|
22
|
+
spec.add_runtime_dependency "faraday", "~> 0.9"
|
23
|
+
spec.add_runtime_dependency "faraday_middleware", "~> 0.9"
|
22
24
|
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
-
spec.add_development_dependency "
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
27
|
+
spec.add_development_dependency "webmock", "~> 1.21"
|
25
28
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'queue_it/api/client'
|
4
|
+
|
5
|
+
module QueueIt
|
6
|
+
module Api
|
7
|
+
describe Client do
|
8
|
+
subject(:client) { described_class.new(api_key: "SECURE_KEY") }
|
9
|
+
|
10
|
+
specify "PUT data under given endpoint & path in JSON format" do
|
11
|
+
request_hash = { "Request" => true }
|
12
|
+
response_hash = { "Response" => true }
|
13
|
+
|
14
|
+
stub_successful_put(request_hash, response_hash)
|
15
|
+
|
16
|
+
expect( client.put("fancy_event", request_hash).body ).to eq(response_hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "authentication error handling" do
|
20
|
+
stub_unauthorized
|
21
|
+
|
22
|
+
expect{ client.put("fancy_event", {}) }.to raise_error(Forbidden)
|
23
|
+
end
|
24
|
+
|
25
|
+
specify "error details are being parsed" do
|
26
|
+
stub_unauthorized
|
27
|
+
|
28
|
+
begin
|
29
|
+
client.put("fancy_event", {})
|
30
|
+
rescue Forbidden => e
|
31
|
+
expect(e.status).to eq(403)
|
32
|
+
expect(e.code).to eq(4000)
|
33
|
+
expect(e.text).to eq("Authentication failed. Supply valid API key to access this operation")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
specify "server error with html body" do
|
38
|
+
stub_internal_server_error
|
39
|
+
|
40
|
+
expect{ client.put("fancy_event", "{}") }.to raise_error(InternalServerError)
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "error without a body" do
|
44
|
+
stub_internal_server_error
|
45
|
+
|
46
|
+
begin
|
47
|
+
client.put("fancy_event", "{}")
|
48
|
+
rescue InternalServerError => e
|
49
|
+
expect(e.status).to eq(500)
|
50
|
+
expect(e.code).to be_nil
|
51
|
+
expect(e.text).to eq("<html>Internal Server Error<\/html>")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
specify "bad request error handling" do
|
56
|
+
stub_bad_request
|
57
|
+
|
58
|
+
expect{ client.put("fancy_event", "{}") }.to raise_error(BadRequest)
|
59
|
+
end
|
60
|
+
|
61
|
+
specify "not found error handling" do
|
62
|
+
stub_not_found
|
63
|
+
|
64
|
+
expect{ client.put("fancy_event", "{}") }.to raise_error(NotFound)
|
65
|
+
end
|
66
|
+
|
67
|
+
specify "service unavailable error handling" do
|
68
|
+
stub_service_unavailable
|
69
|
+
|
70
|
+
expect{ client.put("fancy_event", "{}") }.to raise_error(ServiceUnavailable)
|
71
|
+
end
|
72
|
+
|
73
|
+
specify "debugging mode puts to STDOUT" do
|
74
|
+
client = Client.new(api_key: "SECURE_KEY", debug: true)
|
75
|
+
|
76
|
+
request_hash = { "Request" => true }
|
77
|
+
|
78
|
+
stub_successful_put(request_hash, {})
|
79
|
+
|
80
|
+
expect { client.put("fancy_event", request_hash) }.to output(/request: {"Request":true}/).to_stdout_from_any_process
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def endpoint_url
|
86
|
+
Client::ENDPOINT_URL.to_s + "/fancy_event"
|
87
|
+
end
|
88
|
+
|
89
|
+
def stub_request_factory(method: :put, status: 200, request_body: "{}", response_body: "{}", content_type: "application/json")
|
90
|
+
stub_request(method, endpoint_url)
|
91
|
+
.with(:body => request_body, :headers => {'Accept'=>'application/json', 'Api-Key'=>'SECURE_KEY', 'Content-Type'=>'application/json'})
|
92
|
+
.to_return(:status => status, :body => response_body, :headers => { 'Content-Type' => content_type })
|
93
|
+
end
|
94
|
+
|
95
|
+
def stub_unauthorized
|
96
|
+
body = "{\"ErrorCode\":4000,\"ErrorText\":\"Authentication failed. Supply valid API key to access this operation\"}"
|
97
|
+
stub_request_factory(status: 403, response_body: body)
|
98
|
+
end
|
99
|
+
|
100
|
+
def stub_internal_server_error
|
101
|
+
stub_request_factory(status: 500, response_body: "<html>Internal Server Error</html>", content_type: "text/html")
|
102
|
+
end
|
103
|
+
|
104
|
+
def stub_successful_put(request_body, response_body)
|
105
|
+
stub_request_factory(request_body: JSON.generate(request_body), response_body: JSON.generate(response_body))
|
106
|
+
end
|
107
|
+
|
108
|
+
def stub_bad_request
|
109
|
+
stub_request_factory(status: 400)
|
110
|
+
end
|
111
|
+
|
112
|
+
def stub_not_found
|
113
|
+
stub_request_factory(status: 404)
|
114
|
+
end
|
115
|
+
|
116
|
+
def stub_service_unavailable
|
117
|
+
stub_request_factory(status: 503)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'queue_it/api/event'
|
2
|
+
require 'queue_it/api/client'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
module QueueIt
|
6
|
+
module Api
|
7
|
+
describe Event do
|
8
|
+
let(:event_id) { "fancyevent" }
|
9
|
+
|
10
|
+
subject(:event_adapter) { Event.new(client) }
|
11
|
+
|
12
|
+
context "#create_or_update" do
|
13
|
+
let(:client) { double(:api_client) }
|
14
|
+
let(:know_user_secret_key) { "930f42ca-d9e7-4202-bff4-606e127b1c103980c131-cd8a-4e35-a945-50f7b5102ad6" }
|
15
|
+
let(:display_name) { "Fancy Event 2015" }
|
16
|
+
let(:description) { "Foo" }
|
17
|
+
let(:redirect_url) { "https://example.com/en/events/fancy_event/tickets" }
|
18
|
+
let(:time_zone) { "Europe/Copenhagen" }
|
19
|
+
let(:event_culture_name) { "en-US" }
|
20
|
+
let(:queue_number_validity_in_minutes) { 15 }
|
21
|
+
|
22
|
+
specify "Submits proper request" do
|
23
|
+
expect(client).to receive(:put).with(event_id, valid_create_body).and_return(double(body:{}))
|
24
|
+
|
25
|
+
event_adapter.create_or_update(event_id: event_id,
|
26
|
+
display_name: display_name,
|
27
|
+
description: description,
|
28
|
+
redirect_url: redirect_url,
|
29
|
+
start_time: Time.new(2015,04,28,17,25,46, "+02:00"),
|
30
|
+
end_time: Time.new(2015,04,28,21,25,46, "+02:00"),
|
31
|
+
event_culture_name: event_culture_name,
|
32
|
+
know_user_secret_key: know_user_secret_key,
|
33
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes)
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "Minimum viable attributes for creating event" do
|
37
|
+
body = valid_create_body.merge({
|
38
|
+
"Description" => "",
|
39
|
+
"EventEndTime" => "2016-04-27T21:25:46.0000000Z",
|
40
|
+
"EventCulture" => event_culture_name,
|
41
|
+
"KnowUserSecretKey" => nil,
|
42
|
+
})
|
43
|
+
|
44
|
+
expect(client).to receive(:put).with(event_id, body).and_return(double(body:{}))
|
45
|
+
|
46
|
+
event_adapter.create_or_update(event_id: event_id,
|
47
|
+
display_name: display_name,
|
48
|
+
redirect_url: redirect_url,
|
49
|
+
start_time: Time.utc(2015,04,28,15,25,46),)
|
50
|
+
end
|
51
|
+
|
52
|
+
specify "Set custom time zone in the ruby way" do
|
53
|
+
body = valid_create_body.merge({
|
54
|
+
"TimeZone" => "Romance Standard Time",
|
55
|
+
})
|
56
|
+
|
57
|
+
expect(client).to receive(:put).with(event_id, body).and_return(double(body:{}))
|
58
|
+
|
59
|
+
event_adapter.create_or_update(event_id: event_id,
|
60
|
+
display_name: display_name,
|
61
|
+
description: description,
|
62
|
+
redirect_url: redirect_url,
|
63
|
+
start_time: Time.new(2015,04,28,17,25,46, "+02:00"),
|
64
|
+
end_time: Time.new(2015,04,28,21,25,46, "+02:00"),
|
65
|
+
know_user_secret_key: know_user_secret_key,
|
66
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes,
|
67
|
+
time_zone: time_zone,)
|
68
|
+
end
|
69
|
+
|
70
|
+
specify "Event id must have proper format" do
|
71
|
+
invalid_event_id = "/fancyevent"
|
72
|
+
|
73
|
+
expect do
|
74
|
+
event_adapter.create_or_update(event_id: invalid_event_id,
|
75
|
+
display_name: display_name,
|
76
|
+
description: description,
|
77
|
+
redirect_url: redirect_url,
|
78
|
+
start_time: Time.new(2015,04,28,17,25,46, "+02:00"),
|
79
|
+
end_time: Time.new(2015,04,28,21,25,46, "+02:00"),
|
80
|
+
know_user_secret_key: know_user_secret_key,
|
81
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes,
|
82
|
+
time_zone: time_zone,)
|
83
|
+
end.to raise_error(Event::InvalidEventIdFormat)
|
84
|
+
end
|
85
|
+
|
86
|
+
specify "Event id has to be no longer than 20 characters" do
|
87
|
+
too_long_event_id = "fancyeventnametoolong"
|
88
|
+
|
89
|
+
expect do
|
90
|
+
event_adapter.create_or_update(event_id: too_long_event_id,
|
91
|
+
display_name: display_name,
|
92
|
+
description: description,
|
93
|
+
redirect_url: redirect_url,
|
94
|
+
start_time: Time.new(2015,04,28,17,25,46, "+02:00"),
|
95
|
+
end_time: Time.new(2015,04,28,21,25,46, "+02:00"),
|
96
|
+
know_user_secret_key: know_user_secret_key,
|
97
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes,
|
98
|
+
time_zone: time_zone,)
|
99
|
+
end.to raise_error(Event::InvalidEventIdFormat)
|
100
|
+
end
|
101
|
+
|
102
|
+
specify "Request hits proper endpoint" do
|
103
|
+
client = Client.new(api_key: "SECURE_KEY")
|
104
|
+
event_adapter = Event.new(client)
|
105
|
+
|
106
|
+
body = JSON.generate(valid_create_body)
|
107
|
+
|
108
|
+
stub = stub_request(:put, "https://api2.queue-it.net/2_0_beta/event/fancyevent")
|
109
|
+
.with(body: body, headers: headers)
|
110
|
+
|
111
|
+
event_adapter.create_or_update(event_id: event_id,
|
112
|
+
display_name: display_name,
|
113
|
+
description: description,
|
114
|
+
redirect_url: redirect_url,
|
115
|
+
start_time: Time.new(2015,04,28,17,25,46, "+02:00"),
|
116
|
+
end_time: Time.new(2015,04,28,21,25,46, "+02:00"),
|
117
|
+
event_culture_name: event_culture_name,
|
118
|
+
know_user_secret_key: know_user_secret_key,
|
119
|
+
queue_number_validity_in_minutes: queue_number_validity_in_minutes)
|
120
|
+
|
121
|
+
expect(stub).to have_been_requested
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
let(:valid_create_body) do
|
127
|
+
{
|
128
|
+
"DisplayName" => display_name,
|
129
|
+
"RedirectUrl" => redirect_url,
|
130
|
+
"Description" => description,
|
131
|
+
"TimeZone" => "UTC",
|
132
|
+
"PreQueueStartTime" => "2015-04-28T14:25:46.0000000Z",
|
133
|
+
"EventStartTime" => "2015-04-28T15:25:46.0000000Z",
|
134
|
+
"EventEndTime" => "2015-04-28T19:25:46.0000000Z",
|
135
|
+
"EventCulture" => event_culture_name,
|
136
|
+
"MaxNoOfRedirectsPrQueueId" => "1",
|
137
|
+
"QueueNumberValidityInMinutes" => "#{queue_number_validity_in_minutes}",
|
138
|
+
"AfterEventLogic" => "RedirectUsersToTargetPage",
|
139
|
+
"AfterEventRedirectPage" => "",
|
140
|
+
"UseSSL" => "Auto",
|
141
|
+
"JavaScriptSupportEnabled" => "False",
|
142
|
+
"TargetUrlSupportEnabled" => "False",
|
143
|
+
"SafetyNetMode" => "Disabled",
|
144
|
+
"KnowUserSecurity" => "MD5Hash",
|
145
|
+
"KnowUserSecretKey" => know_user_secret_key,
|
146
|
+
"CustomLayout" => "Default layout by Queue-it",
|
147
|
+
"XUsersInFrontOfYou" => nil,
|
148
|
+
"TargetUrlValidationRegex" => "",
|
149
|
+
"DomainAlias" => "",
|
150
|
+
"AllowedCustomLayouts" => [],
|
151
|
+
"BrowserCultureEnabled" => "True",
|
152
|
+
"IdleQueueLogic" => "UseBeforePage",
|
153
|
+
"IdleQueueRedirectPage" => ""
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "#set_speed" do
|
159
|
+
let(:client) { Client.new(api_key: "SECURE_KEY") }
|
160
|
+
let(:max_redirects_per_minute) { 15 }
|
161
|
+
|
162
|
+
specify "Proper speed value is set" do
|
163
|
+
body = { "MaxRedirectsPerMinute" => "15" }
|
164
|
+
|
165
|
+
stub = stub_request(:put, "https://api2.queue-it.net/2_0_beta/event/fancyevent/queue/speed")
|
166
|
+
.with(body: body, headers: headers)
|
167
|
+
|
168
|
+
event_adapter.set_speed(event_id: event_id, max_redirects_per_minute: max_redirects_per_minute)
|
169
|
+
|
170
|
+
expect(stub).to have_been_requested
|
171
|
+
end
|
172
|
+
|
173
|
+
specify "Speed must be greater than 5 so we send at least 5" do
|
174
|
+
expected_body = { "MaxRedirectsPerMinute" => "5" }
|
175
|
+
|
176
|
+
stub = stub_request(:put, "https://api2.queue-it.net/2_0_beta/event/fancyevent/queue/speed")
|
177
|
+
.with(body: expected_body, headers: headers)
|
178
|
+
|
179
|
+
event_adapter.set_speed(event_id: event_id, max_redirects_per_minute: 1)
|
180
|
+
|
181
|
+
expect(stub).to have_been_requested
|
182
|
+
end
|
183
|
+
|
184
|
+
specify "Event id must have proper format" do
|
185
|
+
invalid_event_id = "/fancyevent"
|
186
|
+
|
187
|
+
expect do
|
188
|
+
event_adapter.set_speed(event_id: invalid_event_id, max_redirects_per_minute: max_redirects_per_minute)
|
189
|
+
end.to raise_error(Event::InvalidEventIdFormat)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
let(:headers) { {'Accept' =>'application/json', 'Content-Type' =>'application/json', 'Api-Key' =>'SECURE_KEY'} }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
metadata
CHANGED
@@ -1,78 +1,127 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue_it
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Billetto
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.9'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday_middleware
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.9'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- - ~>
|
59
|
+
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
61
|
version: '1.3'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- - ~>
|
66
|
+
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '1.3'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
44
86
|
requirements:
|
45
|
-
- -
|
87
|
+
- - "~>"
|
46
88
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
89
|
+
version: '1.21'
|
48
90
|
type: :development
|
49
91
|
prerelease: false
|
50
92
|
version_requirements: !ruby/object:Gem::Requirement
|
51
93
|
requirements:
|
52
|
-
- -
|
94
|
+
- - "~>"
|
53
95
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
96
|
+
version: '1.21'
|
55
97
|
description: Gem to handle the implementation of http://queue-it.net!
|
56
98
|
email:
|
57
|
-
-
|
99
|
+
- development@billetto.dk
|
58
100
|
executables: []
|
59
101
|
extensions: []
|
60
102
|
extra_rdoc_files: []
|
61
103
|
files:
|
62
|
-
- .gitignore
|
104
|
+
- ".gitignore"
|
105
|
+
- CHANGELOG.md
|
63
106
|
- Gemfile
|
64
107
|
- LICENSE.txt
|
65
108
|
- README.md
|
66
109
|
- Rakefile
|
67
110
|
- app/views/queue_it/cheating_queue.html.erb
|
68
111
|
- app/views/queue_it/enter_queue.html.erb
|
112
|
+
- lib/faraday/raise_http_exception.rb
|
69
113
|
- lib/queue_it.rb
|
114
|
+
- lib/queue_it/api/client.rb
|
115
|
+
- lib/queue_it/api/error.rb
|
116
|
+
- lib/queue_it/api/event.rb
|
70
117
|
- lib/queue_it/known_user_checker.rb
|
71
118
|
- lib/queue_it/queueable.rb
|
72
119
|
- lib/queue_it/railtie.rb
|
73
120
|
- lib/queue_it/url_builder.rb
|
74
121
|
- lib/queue_it/version.rb
|
75
122
|
- queue_it.gemspec
|
123
|
+
- spec/queue_it/api/client_spec.rb
|
124
|
+
- spec/queue_it/api/event_spec.rb
|
76
125
|
homepage: https://github.com/gfish/queue_it
|
77
126
|
licenses:
|
78
127
|
- GNU/GPLv3
|
@@ -83,18 +132,20 @@ require_paths:
|
|
83
132
|
- lib
|
84
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
85
134
|
requirements:
|
86
|
-
- -
|
135
|
+
- - ">="
|
87
136
|
- !ruby/object:Gem::Version
|
88
137
|
version: '0'
|
89
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
139
|
requirements:
|
91
|
-
- -
|
140
|
+
- - ">="
|
92
141
|
- !ruby/object:Gem::Version
|
93
142
|
version: '0'
|
94
143
|
requirements: []
|
95
144
|
rubyforge_project:
|
96
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.2.2
|
97
146
|
signing_key:
|
98
147
|
specification_version: 4
|
99
148
|
summary: Gem to handle the implementation of http://queue-it.net
|
100
|
-
test_files:
|
149
|
+
test_files:
|
150
|
+
- spec/queue_it/api/client_spec.rb
|
151
|
+
- spec/queue_it/api/event_spec.rb
|