web-ex-events 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +56 -0
- data/Rakefile +1 -0
- data/lib/web_ex/events.rb +10 -0
- data/lib/web_ex/events/configuration.rb +15 -0
- data/lib/web_ex/events/event.rb +43 -0
- data/lib/web_ex/events/event_list.rb +31 -0
- data/lib/web_ex/events/event_summary_request.rb +75 -0
- data/lib/web_ex/events/time_with_zone.rb +83 -0
- data/lib/web_ex/events/version.rb +5 -0
- data/spec/fixtures/responses/webex_events.xml +200 -0
- data/spec/fixtures/responses/webex_events_auth_error.xml +14 -0
- data/spec/fixtures/responses/webex_events_no_results.xml +14 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/web_ex/events/configuration_spec.rb +20 -0
- data/spec/web_ex/events/event_list_spec.rb +57 -0
- data/spec/web_ex/events/event_spec.rb +114 -0
- data/spec/web_ex/events/event_summary_request_spec.rb +137 -0
- data/web-ex-events.gemspec +30 -0
- metadata +186 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6313292bccf157b4ad36a2cbf03c81641e4bd024
|
4
|
+
data.tar.gz: 256e43c16759d10915bf1b80bf89ab29cb2404b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d39ebb09c79cb01a8f18a02efcfe5645c67c7fce0ecaf3e549fa858fb078c4228407f010d5b4d4c482ab37a4cd3316414c6d3beff31d518bb9a1c8b182f0f408
|
7
|
+
data.tar.gz: 17931565713e2273947abc0298abbe5e123eb83ec66afc78ba0ccf5e5e8f7774b1384cf3f9414a2e01251257b3f1b6d945fdb5a44509bfc58e4b64d9d3d336e5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Pete Nicholls
|
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,56 @@
|
|
1
|
+
# WebEx::Events
|
2
|
+
|
3
|
+
A library to read WebEx events through the WebEx API.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'web-ex-events'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install web-ex-events
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'web_ex/events'
|
23
|
+
|
24
|
+
# Set WebEx site name
|
25
|
+
ENV['WEB_EX_SITE_NAME'] = "…"
|
26
|
+
|
27
|
+
# Web Ex Site and Partner ID (available through WebEx support request)
|
28
|
+
ENV['WEB_EX_SITE_ID'] = "…"
|
29
|
+
ENV['WEB_EX_PARTNER_ID'] = "…"
|
30
|
+
|
31
|
+
# Your WebEx credentials
|
32
|
+
ENV['WEB_EX_USERNAME'] = "…"
|
33
|
+
ENV['WEB_EX_PASSWORD'] = "…"
|
34
|
+
|
35
|
+
next_30_days = 30 * 24 * 60 * 60
|
36
|
+
events = WebEx::Events::Event.fetch(next_30_days)
|
37
|
+
|
38
|
+
# Print event details
|
39
|
+
events.each do |event|
|
40
|
+
puts event.name
|
41
|
+
puts event.start_date
|
42
|
+
puts "#{event.duration} mins"
|
43
|
+
puts event.description
|
44
|
+
end
|
45
|
+
|
46
|
+
# Print all events as JSON
|
47
|
+
puts events.to_json
|
48
|
+
```
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httparty'
|
3
|
+
require 'tzinfo'
|
4
|
+
|
5
|
+
require "web_ex/events/version"
|
6
|
+
require "web_ex/events/configuration"
|
7
|
+
require "web_ex/events/event"
|
8
|
+
require "web_ex/events/event_list"
|
9
|
+
require "web_ex/events/event_summary_request"
|
10
|
+
require "web_ex/events/time_with_zone"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WebEx
|
2
|
+
module Events
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
%w( site_name site_id username password partner_id ).each do |name|
|
6
|
+
define_singleton_method(name) { ENV["WEBEX_#{name.upcase}"] }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.xml_service_url
|
10
|
+
"https://#{site_name}.webex.com/WBXService/XMLService"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module WebEx
|
2
|
+
module Events
|
3
|
+
class Event
|
4
|
+
attr_accessor :name, :start_date, :end_date, :key, :description, :duration
|
5
|
+
|
6
|
+
def initialize(attributes = {})
|
7
|
+
attributes.each do |k, v|
|
8
|
+
send("#{k}=", v)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_json(*args)
|
13
|
+
JSON.dump(
|
14
|
+
name: name,
|
15
|
+
start_date: start_date,
|
16
|
+
end_date: end_date,
|
17
|
+
key: key,
|
18
|
+
description: description,
|
19
|
+
duration: duration
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_xml(xml)
|
24
|
+
node = Nokogiri::XML(xml)
|
25
|
+
element = node.xpath('event')
|
26
|
+
|
27
|
+
self.new(
|
28
|
+
name: element.xpath('sessionName').text,
|
29
|
+
start_date: TimeWithZone.new(element.xpath('startDate').text, element.xpath('timeZoneID').text).to_datetime,
|
30
|
+
end_date: TimeWithZone.new(element.xpath('endDate').text, element.xpath('timeZoneID').text).to_datetime,
|
31
|
+
key: element.xpath('sessionKey').text,
|
32
|
+
description: element.xpath('description').text,
|
33
|
+
duration: element.xpath('duration').text.to_i
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.fetch(time_frame)
|
38
|
+
request = EventSummaryRequest.new(start_date: Time.now, end_date: Time.now + time_frame)
|
39
|
+
request.find_events!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module WebEx
|
2
|
+
module Events
|
3
|
+
class EventList
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def initialize(*events)
|
7
|
+
@events = events.flatten
|
8
|
+
end
|
9
|
+
|
10
|
+
def length
|
11
|
+
@events.length
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&block)
|
15
|
+
@events.each(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def last
|
19
|
+
@events.last
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
@events.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json
|
27
|
+
JSON.dump(@events)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module WebEx
|
2
|
+
module Events
|
3
|
+
class EventSummaryRequest
|
4
|
+
WEBEX_EMPTY_RESULTS_EXCEPTION_ID = "000015"
|
5
|
+
|
6
|
+
attr_accessor :start_date, :end_date
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@start_date, @end_date = options[:start_date], options[:end_date]
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_events!
|
13
|
+
events = xml_response.xpath('//event').map do |node|
|
14
|
+
Event.from_xml(node.to_xml)
|
15
|
+
end
|
16
|
+
|
17
|
+
EventList.new(events)
|
18
|
+
end
|
19
|
+
|
20
|
+
def payload
|
21
|
+
<<-XML
|
22
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
23
|
+
<message xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
24
|
+
<header>
|
25
|
+
<securityContext>
|
26
|
+
<webExID>#{Configuration.username}</webExID>
|
27
|
+
<password>#{Configuration.password}</password>
|
28
|
+
<siteID>#{Configuration.site_id}</siteID>
|
29
|
+
<partnerID>#{Configuration.partner_id}</partnerID>
|
30
|
+
</securityContext>
|
31
|
+
</header>
|
32
|
+
<body>
|
33
|
+
<bodyContent xsi:type="java:com.webex.service.binding.event.LstsummaryEvent">
|
34
|
+
<listControl>
|
35
|
+
<startFrom/>
|
36
|
+
</listControl>
|
37
|
+
<order>
|
38
|
+
<orderBy>STARTTIME</orderBy>
|
39
|
+
</order>
|
40
|
+
<dateScope>
|
41
|
+
<startDateStart>#{formatted_date start_date}</startDateStart>
|
42
|
+
<endDateEnd>#{formatted_date end_date}</endDateEnd>
|
43
|
+
<timeZoneID>#{TimeWithZone::UTC_ZONE_ID}</timeZoneID>
|
44
|
+
</dateScope>
|
45
|
+
</bodyContent>
|
46
|
+
</body>
|
47
|
+
</message>
|
48
|
+
XML
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def response
|
54
|
+
@response ||= HTTParty.post(Configuration.xml_service_url, body: payload)
|
55
|
+
end
|
56
|
+
|
57
|
+
def xml_response
|
58
|
+
@xml_response ||= begin
|
59
|
+
xml = Nokogiri::XML(response.body)
|
60
|
+
webex_exception = xml.at_xpath('//serv:exceptionID')
|
61
|
+
|
62
|
+
if webex_exception && webex_exception.content != WEBEX_EMPTY_RESULTS_EXCEPTION_ID
|
63
|
+
raise "WebEx Error: #{xml.at_xpath('//serv:reason').content}"
|
64
|
+
end
|
65
|
+
|
66
|
+
xml.remove_namespaces!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def formatted_date(date)
|
71
|
+
date.utc.strftime('%m/%d/%Y %H:%M:%S') if date
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module WebEx
|
2
|
+
module Events
|
3
|
+
class TimeWithZone
|
4
|
+
UTC_ZONE_ID = 21
|
5
|
+
|
6
|
+
TIME_ZONE_MAPPINGS = {
|
7
|
+
0 => "Pacific/Niue",
|
8
|
+
1 => "Pacific/Apia",
|
9
|
+
2 => "Pacific/Honolulu",
|
10
|
+
3 => "America/Juneau ",
|
11
|
+
4 => "America/Los_Angeles",
|
12
|
+
5 => "America/Phoenixr",
|
13
|
+
6 => "America/Denver",
|
14
|
+
7 => "America/Chicago",
|
15
|
+
8 => "America/Tegucigalpa",
|
16
|
+
9 => "America/Regina",
|
17
|
+
10 => "America/Bogota",
|
18
|
+
11 => "America/New_York",
|
19
|
+
12 => "America/Indiana/Indianapolis",
|
20
|
+
13 => "America/Halifax",
|
21
|
+
14 => "America/Caracas",
|
22
|
+
15 => "America/St_Johns",
|
23
|
+
16 => "America/Sao_Paulo",
|
24
|
+
17 => "America/Argentina/Buenos_Aires",
|
25
|
+
18 => "Atlantic/South_Georgia",
|
26
|
+
19 => "Atlantic/Azores",
|
27
|
+
20 => "Africa/Casablanca",
|
28
|
+
21 => "Europe/London",
|
29
|
+
22 => "Europe/Amsterdam",
|
30
|
+
23 => "Europe/Paris",
|
31
|
+
24 => "Europe/Paris",
|
32
|
+
25 => "Europe/Berlin",
|
33
|
+
26 => "Europe/Athens",
|
34
|
+
27 => "Europe/Athens",
|
35
|
+
28 => "Africa/Cairo",
|
36
|
+
29 => "Africa/Johannesburg",
|
37
|
+
30 => "Europe/Helsinki",
|
38
|
+
31 => "Asia/Amman",
|
39
|
+
32 => "Asia/Baghdad",
|
40
|
+
33 => "Europe/Moscow",
|
41
|
+
34 => "Africa/Nairobi",
|
42
|
+
35 => "Asia/Tehran",
|
43
|
+
36 => "Asia/Muscat",
|
44
|
+
37 => "Asia/Baku",
|
45
|
+
38 => "Asia/Kabul",
|
46
|
+
39 => "Asia/Yekaterinburg",
|
47
|
+
40 => "Asia/Karachi",
|
48
|
+
41 => "Asia/Kolkata",
|
49
|
+
42 => "Asia/Colombo",
|
50
|
+
43 => "Asia/Almaty",
|
51
|
+
44 => "Asia/Bangkok",
|
52
|
+
45 => "Asia/Shanghai",
|
53
|
+
46 => "Australia/Perth",
|
54
|
+
47 => "Asia/Singapore",
|
55
|
+
48 => "Asia/Taipei",
|
56
|
+
49 => "Asia/Tokyo",
|
57
|
+
50 => "Asia/Seoul",
|
58
|
+
51 => "Asia/Yakutsk",
|
59
|
+
52 => "Australia/Adelaide",
|
60
|
+
53 => "Australia/Darwin",
|
61
|
+
54 => "Australia/Brisbane",
|
62
|
+
55 => "Australia/Sydney",
|
63
|
+
56 => "Pacific/Guam",
|
64
|
+
57 => "Australia/Hobart",
|
65
|
+
58 => "Asia/Vladivostok",
|
66
|
+
59 => "Asia/Magadan",
|
67
|
+
60 => "Pacific/Auckland",
|
68
|
+
61 => "Pacific/Fiji"
|
69
|
+
}
|
70
|
+
|
71
|
+
def initialize(date_string, timezone_id)
|
72
|
+
@date_string = date_string
|
73
|
+
@timezone_id = timezone_id.to_i
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_datetime
|
77
|
+
month, day, year, hour, minute, second = @date_string.split(/[\/ :]/).map(&:to_i)
|
78
|
+
time_zone = TZInfo::Timezone.get(TIME_ZONE_MAPPINGS[@timezone_id])
|
79
|
+
time_zone.local_to_utc DateTime.new(year, month, day, hour, minute, second)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service" xmlns:com="http://www.webex.com/schemas/2002/06/common" xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
|
3
|
+
<serv:header>
|
4
|
+
<serv:response>
|
5
|
+
<serv:result>SUCCESS</serv:result>
|
6
|
+
<serv:gsbStatus>PRIMARY</serv:gsbStatus>
|
7
|
+
</serv:response>
|
8
|
+
</serv:header>
|
9
|
+
<serv:body>
|
10
|
+
<serv:bodyContent xsi:type="event:lstsummaryEventResponse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
11
|
+
<event:matchingRecords>
|
12
|
+
<serv:total>13</serv:total>
|
13
|
+
<serv:returned>13</serv:returned>
|
14
|
+
<serv:startFrom>1</serv:startFrom>
|
15
|
+
</event:matchingRecords>
|
16
|
+
<event:event>
|
17
|
+
<event:sessionKey>337167902</event:sessionKey>
|
18
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
19
|
+
<event:sessionType>220</event:sessionType>
|
20
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
21
|
+
<event:startDate>05/01/2013 05:00:00</event:startDate>
|
22
|
+
<event:endDate>05/01/2013 06:30:00</event:endDate>
|
23
|
+
<event:timeZoneID>4</event:timeZoneID>
|
24
|
+
<event:duration>90</event:duration>
|
25
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
26
|
+
<event:status>NOT_INPROGRESS</event:status>
|
27
|
+
<event:panelists></event:panelists>
|
28
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
29
|
+
</event:event>
|
30
|
+
<event:event>
|
31
|
+
<event:sessionKey>241299796</event:sessionKey>
|
32
|
+
<event:sessionName>Advanced Baking</event:sessionName>
|
33
|
+
<event:sessionType>220</event:sessionType>
|
34
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
35
|
+
<event:startDate>05/01/2013 08:00:00</event:startDate>
|
36
|
+
<event:endDate>05/01/2013 09:00:00</event:endDate>
|
37
|
+
<event:timeZoneID>4</event:timeZoneID>
|
38
|
+
<event:duration>60</event:duration>
|
39
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
40
|
+
<event:status>NOT_INPROGRESS</event:status>
|
41
|
+
<event:panelists>Satoshi Nakamoto</event:panelists>
|
42
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
43
|
+
</event:event>
|
44
|
+
<event:event>
|
45
|
+
<event:sessionKey>741475588</event:sessionKey>
|
46
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
47
|
+
<event:sessionType>220</event:sessionType>
|
48
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
49
|
+
<event:startDate>05/01/2013 11:00:00</event:startDate>
|
50
|
+
<event:endDate>05/01/2013 12:30:00</event:endDate>
|
51
|
+
<event:timeZoneID>4</event:timeZoneID>
|
52
|
+
<event:duration>90</event:duration>
|
53
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
54
|
+
<event:status>NOT_INPROGRESS</event:status>
|
55
|
+
<event:panelists></event:panelists>
|
56
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
57
|
+
</event:event>
|
58
|
+
<event:event>
|
59
|
+
<event:sessionKey>785125343</event:sessionKey>
|
60
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
61
|
+
<event:sessionType>220</event:sessionType>
|
62
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
63
|
+
<event:startDate>05/01/2013 13:00:00</event:startDate>
|
64
|
+
<event:endDate>05/01/2013 14:30:00</event:endDate>
|
65
|
+
<event:timeZoneID>4</event:timeZoneID>
|
66
|
+
<event:duration>90</event:duration>
|
67
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
68
|
+
<event:status>NOT_INPROGRESS</event:status>
|
69
|
+
<event:panelists></event:panelists>
|
70
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
71
|
+
</event:event>
|
72
|
+
<event:event>
|
73
|
+
<event:sessionKey>516377344</event:sessionKey>
|
74
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
75
|
+
<event:sessionType>220</event:sessionType>
|
76
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
77
|
+
<event:startDate>05/02/2013 05:00:00</event:startDate>
|
78
|
+
<event:endDate>05/02/2013 06:30:00</event:endDate>
|
79
|
+
<event:timeZoneID>4</event:timeZoneID>
|
80
|
+
<event:duration>90</event:duration>
|
81
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
82
|
+
<event:status>NOT_INPROGRESS</event:status>
|
83
|
+
<event:panelists></event:panelists>
|
84
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
85
|
+
</event:event>
|
86
|
+
<event:event>
|
87
|
+
<event:sessionKey>675735386</event:sessionKey>
|
88
|
+
<event:sessionName>Advanced Baking</event:sessionName>
|
89
|
+
<event:sessionType>220</event:sessionType>
|
90
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
91
|
+
<event:startDate>05/02/2013 08:00:00</event:startDate>
|
92
|
+
<event:endDate>05/02/2013 09:00:00</event:endDate>
|
93
|
+
<event:timeZoneID>4</event:timeZoneID>
|
94
|
+
<event:duration>60</event:duration>
|
95
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
96
|
+
<event:status>NOT_INPROGRESS</event:status>
|
97
|
+
<event:panelists>Satoshi Nakamoto</event:panelists>
|
98
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
99
|
+
</event:event>
|
100
|
+
<event:event>
|
101
|
+
<event:sessionKey>448544768</event:sessionKey>
|
102
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
103
|
+
<event:sessionType>220</event:sessionType>
|
104
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
105
|
+
<event:startDate>05/02/2013 11:00:00</event:startDate>
|
106
|
+
<event:endDate>05/02/2013 12:30:00</event:endDate>
|
107
|
+
<event:timeZoneID>4</event:timeZoneID>
|
108
|
+
<event:duration>90</event:duration>
|
109
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
110
|
+
<event:status>NOT_INPROGRESS</event:status>
|
111
|
+
<event:panelists></event:panelists>
|
112
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
113
|
+
</event:event>
|
114
|
+
<event:event>
|
115
|
+
<event:sessionKey>548465686</event:sessionKey>
|
116
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
117
|
+
<event:sessionType>220</event:sessionType>
|
118
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
119
|
+
<event:startDate>05/02/2013 13:00:00</event:startDate>
|
120
|
+
<event:endDate>05/02/2013 14:30:00</event:endDate>
|
121
|
+
<event:timeZoneID>4</event:timeZoneID>
|
122
|
+
<event:duration>90</event:duration>
|
123
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
124
|
+
<event:status>NOT_INPROGRESS</event:status>
|
125
|
+
<event:panelists></event:panelists>
|
126
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
127
|
+
</event:event>
|
128
|
+
<event:event>
|
129
|
+
<event:sessionKey>265268976</event:sessionKey>
|
130
|
+
<event:sessionName>Advanced Baking</event:sessionName>
|
131
|
+
<event:sessionType>220</event:sessionType>
|
132
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
133
|
+
<event:startDate>05/03/2013 08:00:00</event:startDate>
|
134
|
+
<event:endDate>05/03/2013 09:00:00</event:endDate>
|
135
|
+
<event:timeZoneID>4</event:timeZoneID>
|
136
|
+
<event:duration>60</event:duration>
|
137
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
138
|
+
<event:status>NOT_INPROGRESS</event:status>
|
139
|
+
<event:panelists>Satoshi Nakamoto</event:panelists>
|
140
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
141
|
+
</event:event>
|
142
|
+
<event:event>
|
143
|
+
<event:sessionKey>223574221</event:sessionKey>
|
144
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
145
|
+
<event:sessionType>220</event:sessionType>
|
146
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
147
|
+
<event:startDate>05/07/2013 05:00:00</event:startDate>
|
148
|
+
<event:endDate>05/07/2013 06:30:00</event:endDate>
|
149
|
+
<event:timeZoneID>4</event:timeZoneID>
|
150
|
+
<event:duration>90</event:duration>
|
151
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
152
|
+
<event:status>NOT_INPROGRESS</event:status>
|
153
|
+
<event:panelists></event:panelists>
|
154
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
155
|
+
</event:event>
|
156
|
+
<event:event>
|
157
|
+
<event:sessionKey>495477388</event:sessionKey>
|
158
|
+
<event:sessionName>Advanced Baking</event:sessionName>
|
159
|
+
<event:sessionType>220</event:sessionType>
|
160
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
161
|
+
<event:startDate>05/07/2013 11:00:00</event:startDate>
|
162
|
+
<event:endDate>05/07/2013 12:00:00</event:endDate>
|
163
|
+
<event:timeZoneID>4</event:timeZoneID>
|
164
|
+
<event:duration>60</event:duration>
|
165
|
+
<event:description>Learn advanced Japanese baking techniques in this hour-long webinar.</event:description>
|
166
|
+
<event:status>NOT_INPROGRESS</event:status>
|
167
|
+
<event:panelists></event:panelists>
|
168
|
+
<event:listStatus>PUBLIC</event:listStatus>
|
169
|
+
</event:event>
|
170
|
+
<event:event>
|
171
|
+
<event:sessionKey>252653476</event:sessionKey>
|
172
|
+
<event:sessionName>Baking Basics</event:sessionName>
|
173
|
+
<event:sessionType>220</event:sessionType>
|
174
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
175
|
+
<event:startDate>05/07/2013 11:00:00</event:startDate>
|
176
|
+
<event:endDate>05/07/2013 12:30:00</event:endDate>
|
177
|
+
<event:timeZoneID>4</event:timeZoneID>
|
178
|
+
<event:duration>90</event:duration>
|
179
|
+
<event:description>Learn the intricacies of Japanese baking in this 90 minute webinar.</event:description>
|
180
|
+
<event:status>NOT_INPROGRESS</event:status>
|
181
|
+
<event:panelists></event:panelists>
|
182
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
183
|
+
</event:event>
|
184
|
+
<event:event>
|
185
|
+
<event:sessionKey>356727241</event:sessionKey>
|
186
|
+
<event:sessionName>Baking Finale</event:sessionName>
|
187
|
+
<event:sessionType>220</event:sessionType>
|
188
|
+
<event:hostWebExID>bakery</event:hostWebExID>
|
189
|
+
<event:startDate>05/07/2013 13:00:00</event:startDate>
|
190
|
+
<event:endDate>05/07/2013 14:30:00</event:endDate>
|
191
|
+
<event:timeZoneID>4</event:timeZoneID>
|
192
|
+
<event:duration>90</event:duration>
|
193
|
+
<event:description>A 90 minute wrap-up event!</event:description>
|
194
|
+
<event:status>NOT_INPROGRESS</event:status>
|
195
|
+
<event:panelists></event:panelists>
|
196
|
+
<event:listStatus>UNLISTED</event:listStatus>
|
197
|
+
</event:event>
|
198
|
+
</serv:bodyContent>
|
199
|
+
</serv:body>
|
200
|
+
</serv:message>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service" xmlns:com="http://www.webex.com/schemas/2002/06/common" xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
|
3
|
+
<serv:header>
|
4
|
+
<serv:response>
|
5
|
+
<serv:result>FAILURE</serv:result>
|
6
|
+
<serv:reason>Corresponding User not found</serv:reason>
|
7
|
+
<serv:gsbStatus>PRIMARY</serv:gsbStatus>
|
8
|
+
<serv:exceptionID>030001</serv:exceptionID>
|
9
|
+
</serv:response>
|
10
|
+
</serv:header>
|
11
|
+
<serv:body>
|
12
|
+
<serv:bodyContent/>
|
13
|
+
</serv:body>
|
14
|
+
</serv:message>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service" xmlns:com="http://www.webex.com/schemas/2002/06/common" xmlns:event="http://www.webex.com/schemas/2002/06/service/event">
|
3
|
+
<serv:header>
|
4
|
+
<serv:response>
|
5
|
+
<serv:result>FAILURE</serv:result>
|
6
|
+
<serv:reason>Sorry, no record found</serv:reason>
|
7
|
+
<serv:gsbStatus>PRIMARY</serv:gsbStatus>
|
8
|
+
<serv:exceptionID>000015</serv:exceptionID>
|
9
|
+
</serv:response>
|
10
|
+
</serv:header>
|
11
|
+
<serv:body>
|
12
|
+
<serv:bodyContent/>
|
13
|
+
</serv:body>
|
14
|
+
</serv:message>
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Configuration do
|
4
|
+
context "with all environment variables present" do
|
5
|
+
before :each do
|
6
|
+
ENV.stub(:[]).with("WEBEX_SITE_NAME").and_return("bakeryevents")
|
7
|
+
ENV.stub(:[]).with("WEBEX_USERNAME").and_return("bakery")
|
8
|
+
ENV.stub(:[]).with("WEBEX_PASSWORD").and_return("secret")
|
9
|
+
ENV.stub(:[]).with("WEBEX_SITE_ID").and_return("358562")
|
10
|
+
ENV.stub(:[]).with("WEBEX_PARTNER_ID").and_return("123ab")
|
11
|
+
end
|
12
|
+
|
13
|
+
it { Configuration.site_name.should == "bakeryevents" }
|
14
|
+
it { Configuration.username.should == "bakery" }
|
15
|
+
it { Configuration.password.should == "secret" }
|
16
|
+
it { Configuration.site_id.should == "358562" }
|
17
|
+
it { Configuration.partner_id.should == "123ab" }
|
18
|
+
it { Configuration.xml_service_url.should == "https://bakeryevents.webex.com/WBXService/XMLService" }
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EventList do
|
4
|
+
let(:event_a) { stub }
|
5
|
+
let(:event_b) { stub }
|
6
|
+
let(:event_c) { stub }
|
7
|
+
|
8
|
+
describe "#each" do
|
9
|
+
let(:event_list) { EventList.new(event_a, event_b, event_c) }
|
10
|
+
|
11
|
+
it "iterates over each event" do
|
12
|
+
captured_events = []
|
13
|
+
event_list.each { |event| captured_events << event }
|
14
|
+
captured_events.should == [event_a, event_b, event_c]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#to_json" do
|
19
|
+
let(:event_list) { EventList.new(event_a, event_b) }
|
20
|
+
|
21
|
+
before :each do
|
22
|
+
event_a.stub(to_json: '{ "event": "a" }')
|
23
|
+
event_b.stub(to_json: '{ "event": "b" }')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns a JSON representation of all events" do
|
27
|
+
JSON.parse(event_list.to_json).should == [{ 'event' => 'a' }, { 'event' => 'b' }]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#length" do
|
32
|
+
it "returns the number of events" do
|
33
|
+
EventList.new(event_a, event_b).length.should == 2
|
34
|
+
EventList.new(event_a, event_b, event_c).length.should == 3
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with three events" do
|
39
|
+
let(:event_list) { EventList.new(event_a, event_b, event_c) }
|
40
|
+
|
41
|
+
describe "#first and #last" do
|
42
|
+
it { event_list.first.should == event_a }
|
43
|
+
it { event_list.last.should == event_c }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with no events" do
|
48
|
+
subject { EventList.new }
|
49
|
+
it { should be_empty }
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with at least one event" do
|
53
|
+
subject { EventList.new(event_a) }
|
54
|
+
it { should_not be_empty }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Event do
|
4
|
+
let(:valid_attributes) {
|
5
|
+
{
|
6
|
+
name: "Cupcake Giveaway",
|
7
|
+
start_date: DateTime.now,
|
8
|
+
end_date: DateTime.now + 3600,
|
9
|
+
key: "12345",
|
10
|
+
description: "Free cupcakes!",
|
11
|
+
duration: 60
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:event) { Event.new(valid_attributes) }
|
16
|
+
|
17
|
+
it "can has accessors for valid attributes" do
|
18
|
+
valid_attributes.each do |name, value|
|
19
|
+
event.send(name).should == value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#to_json" do
|
24
|
+
let(:json) { JSON.parse(event.to_json) }
|
25
|
+
|
26
|
+
it "contains all the valid attributes" do
|
27
|
+
json["name"].should == "Cupcake Giveaway"
|
28
|
+
json["start_date"].inspect.should == JSON.dump(DateTime.now)
|
29
|
+
json["end_date"].inspect.should == JSON.dump(DateTime.now + 3600)
|
30
|
+
json["key"].should == "12345"
|
31
|
+
json["duration"].should == 60
|
32
|
+
json["description"].should == "Free cupcakes!"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".from_xml" do
|
37
|
+
let(:xml) {
|
38
|
+
<<-XML
|
39
|
+
<event>
|
40
|
+
<sessionKey>662050914</sessionKey>
|
41
|
+
<sessionName>NE Utilities - Transition Webinar Navtrak to Fleet</sessionName>
|
42
|
+
<sessionType>220</sessionType>
|
43
|
+
<hostWebExID>bakery</hostWebExID>
|
44
|
+
<startDate>04/30/2013 05:00:00</startDate>
|
45
|
+
<endDate>04/30/2013 06:30:00</endDate>
|
46
|
+
<timeZoneID>4</timeZoneID>
|
47
|
+
<duration>90</duration>
|
48
|
+
<description>During this webinar you will be trained on the bakery Fleet application.</description>
|
49
|
+
<status>NOT_INPROGRESS</status>
|
50
|
+
<panelists></panelists>
|
51
|
+
<listStatus>UNLISTED</listStatus>
|
52
|
+
</event>
|
53
|
+
XML
|
54
|
+
}
|
55
|
+
|
56
|
+
let(:parsed_event) { Event.from_xml(xml) }
|
57
|
+
|
58
|
+
it "can parse an event" do
|
59
|
+
parsed_event.name.should == "NE Utilities - Transition Webinar Navtrak to Fleet"
|
60
|
+
parsed_event.key.should == "662050914"
|
61
|
+
parsed_event.duration.should == 90
|
62
|
+
parsed_event.description.should == "During this webinar you will be trained on the bakery Fleet application."
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with a timezone not in daylight savings" do
|
66
|
+
let(:xml) {
|
67
|
+
<<-XML
|
68
|
+
<event>
|
69
|
+
<startDate>02/15/2013 05:00:00</startDate>
|
70
|
+
<endDate>02/15/2013 06:30:00</endDate>
|
71
|
+
<timeZoneID>4</timeZoneID>
|
72
|
+
</event>
|
73
|
+
XML
|
74
|
+
}
|
75
|
+
|
76
|
+
it "parses the date correctly" do
|
77
|
+
parsed_event.start_date.should == DateTime.new(2013, 2, 15, 5, 0, 0, "-08:00")
|
78
|
+
parsed_event.end_date.should == DateTime.new(2013, 2, 15, 6, 30, 0, "-08:00")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with a timezone inside daylight savings" do
|
83
|
+
let(:xml) {
|
84
|
+
<<-XML
|
85
|
+
<event>
|
86
|
+
<startDate>04/30/2013 05:00:00</startDate>
|
87
|
+
<endDate>04/30/2013 06:30:00</endDate>
|
88
|
+
<timeZoneID>4</timeZoneID>
|
89
|
+
</event>
|
90
|
+
XML
|
91
|
+
}
|
92
|
+
|
93
|
+
it "corrects for daylight savings" do
|
94
|
+
parsed_event.start_date.should == DateTime.new(2013, 4, 30, 5, 0, 0, "-07:00")
|
95
|
+
parsed_event.end_date.should == DateTime.new(2013, 4, 30, 6, 30, 0, "-07:00")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe ".fetch" do
|
101
|
+
it "creates a new event summary request using the time frame" do
|
102
|
+
Timecop.freeze do
|
103
|
+
request = stub(find_events!: "events")
|
104
|
+
ten_days = 10 * 24 * 60 * 60
|
105
|
+
|
106
|
+
EventSummaryRequest.should_receive(:new)
|
107
|
+
.with(start_date: Time.now, end_date: Time.now + ten_days)
|
108
|
+
.and_return(request)
|
109
|
+
|
110
|
+
Event.fetch(ten_days).should == "events"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fakeweb'
|
3
|
+
|
4
|
+
describe EventSummaryRequest do
|
5
|
+
def fixture_path(name)
|
6
|
+
File.expand_path("../../../fixtures/#{name}", __FILE__)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "with a start date of a day ago and end date in a weeks' time" do
|
10
|
+
let(:one_second) { 1 }
|
11
|
+
let(:one_day_ago) { Time.now - (24 * 60 * 60) }
|
12
|
+
let(:seven_days_from_now) { Time.now + (7 * 24 * 60 * 60) }
|
13
|
+
|
14
|
+
let(:req) { EventSummaryRequest.new(start_date: one_day_ago, end_date: seven_days_from_now) }
|
15
|
+
|
16
|
+
describe "#start_date" do
|
17
|
+
subject { req.start_date }
|
18
|
+
it { should be_within(one_second).of(one_day_ago) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#end_date" do
|
22
|
+
subject { req.end_date }
|
23
|
+
it { should be_within(one_second).of(seven_days_from_now) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#payload" do
|
28
|
+
let(:req) { EventSummaryRequest.new }
|
29
|
+
let(:xml) { Nokogiri::XML(req.payload) }
|
30
|
+
|
31
|
+
describe "<?xml ?> processing instruction" do
|
32
|
+
subject { xml.at_xpath('/processing-instruction("xml")').content }
|
33
|
+
it { should include("UTF-8") }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "namespaces" do
|
37
|
+
let(:namespaces) { xml.collect_namespaces }
|
38
|
+
it { namespaces.should have_key('xmlns:xsi') }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "security context" do
|
42
|
+
before :each do
|
43
|
+
Configuration.stub(
|
44
|
+
site_name: "wafflehut",
|
45
|
+
site_id: "12345",
|
46
|
+
username: "bobwaffles",
|
47
|
+
password: "maplesyrup",
|
48
|
+
partner_id: "p4rtn3r"
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:security_context) { xml.at_xpath('/message/header/securityContext') }
|
53
|
+
it { security_context.at_xpath('./webExID').content.should == "bobwaffles" }
|
54
|
+
it { security_context.at_xpath('./password').content.should == "maplesyrup" }
|
55
|
+
it { security_context.at_xpath('./siteID').content.should == "12345" }
|
56
|
+
it { security_context.at_xpath('./partnerID').content.should == "p4rtn3r" }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "body content" do
|
60
|
+
let(:body_content) { xml.at_xpath('/message/body/bodyContent') }
|
61
|
+
it { body_content['xsi:type'].should include('LstsummaryEvent') }
|
62
|
+
it { body_content.at_xpath('./listControl/startFrom').should_not be_nil }
|
63
|
+
it { body_content.at_xpath('./order').should_not be_nil }
|
64
|
+
it { body_content.at_xpath('./dateScope').should_not be_nil }
|
65
|
+
end
|
66
|
+
|
67
|
+
context "with start and end dates in a time zone" do
|
68
|
+
before :each do
|
69
|
+
midday_pancake_tuesday = Time.new(2014, 3, 4, 12, 0, 0, "+02:00")
|
70
|
+
three_thirty_pm_pancake_tuesday = Time.new(2014, 3, 4, 15, 30, 0, "+02:00")
|
71
|
+
req.stub(start_date: midday_pancake_tuesday, end_date: three_thirty_pm_pancake_tuesday)
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "date scope" do
|
75
|
+
let(:date_scope) { xml.at_xpath('/message/body/bodyContent/dateScope') }
|
76
|
+
|
77
|
+
it "formats dates appropriately and in UTC time" do
|
78
|
+
date_scope.at_xpath('./startDateStart').content.should == "03/04/2014 10:00:00"
|
79
|
+
date_scope.at_xpath('./endDateEnd').content.should == "03/04/2014 13:30:00"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "uses the UTC time zone ID" do
|
83
|
+
date_scope.at_xpath('./timeZoneID').content.should == "21"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#find_events!" do
|
90
|
+
let(:req) { EventSummaryRequest.new }
|
91
|
+
|
92
|
+
before :each do
|
93
|
+
Configuration.stub(xml_service_url: "https://webex-api.example.com/service")
|
94
|
+
FakeWeb.register_uri(:post, "https://webex-api.example.com/service", body: response_body)
|
95
|
+
req.stub(payload: "XML")
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when the server responds with events" do
|
99
|
+
let(:response_body) { fixture_path("responses/webex_events.xml") }
|
100
|
+
|
101
|
+
it "creates a new event using from each event node" do
|
102
|
+
Event.should_receive(:from_xml).exactly(13).times
|
103
|
+
req.find_events!
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns the events in an event list" do
|
107
|
+
events = req.find_events!
|
108
|
+
events.should be_a(EventList)
|
109
|
+
events.length.should == 13
|
110
|
+
events.first.name.should == "Baking Basics"
|
111
|
+
events.last.name.should == "Baking Finale"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when the server responds without events" do
|
116
|
+
let(:response_body) { fixture_path("responses/webex_events_no_results.xml") }
|
117
|
+
|
118
|
+
it "returns an empty list" do
|
119
|
+
events = req.find_events!
|
120
|
+
events.should be_a(EventList)
|
121
|
+
events.should be_empty
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when the server responds with an authentication error" do
|
126
|
+
let(:response_body) { fixture_path("responses/webex_events_auth_error.xml") }
|
127
|
+
|
128
|
+
it "raises an error with the server's reason for the error" do
|
129
|
+
-> {
|
130
|
+
req.find_events!
|
131
|
+
}.should raise_error { |error|
|
132
|
+
error.message.should include('Corresponding User not found')
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -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 'web_ex/events/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "web-ex-events"
|
8
|
+
spec.version = WebEx::Events::VERSION
|
9
|
+
spec.authors = ["Pete Nicholls"]
|
10
|
+
spec.email = ["pete@metanation.com"]
|
11
|
+
spec.description = "Allows fetching and parsing WebEx events through the WebEx API. Events can be queried and converted into JSON."
|
12
|
+
spec.summary = "A library to read WebEx events through the WebEx API."
|
13
|
+
spec.homepage = "https://github.com/Aupajo/web-ex-events"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "timecop"
|
25
|
+
spec.add_development_dependency "fakeweb"
|
26
|
+
|
27
|
+
spec.add_dependency "tzinfo"
|
28
|
+
spec.add_dependency "httparty"
|
29
|
+
spec.add_dependency "nokogiri"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: web-ex-events
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pete Nicholls
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: timecop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fakeweb
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: tzinfo
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
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: httparty
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
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: nokogiri
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Allows fetching and parsing WebEx events through the WebEx API. Events
|
126
|
+
can be queried and converted into JSON.
|
127
|
+
email:
|
128
|
+
- pete@metanation.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- .gitignore
|
134
|
+
- Gemfile
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- lib/web_ex/events.rb
|
139
|
+
- lib/web_ex/events/configuration.rb
|
140
|
+
- lib/web_ex/events/event.rb
|
141
|
+
- lib/web_ex/events/event_list.rb
|
142
|
+
- lib/web_ex/events/event_summary_request.rb
|
143
|
+
- lib/web_ex/events/time_with_zone.rb
|
144
|
+
- lib/web_ex/events/version.rb
|
145
|
+
- spec/fixtures/responses/webex_events.xml
|
146
|
+
- spec/fixtures/responses/webex_events_auth_error.xml
|
147
|
+
- spec/fixtures/responses/webex_events_no_results.xml
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/web_ex/events/configuration_spec.rb
|
150
|
+
- spec/web_ex/events/event_list_spec.rb
|
151
|
+
- spec/web_ex/events/event_spec.rb
|
152
|
+
- spec/web_ex/events/event_summary_request_spec.rb
|
153
|
+
- web-ex-events.gemspec
|
154
|
+
homepage: https://github.com/Aupajo/web-ex-events
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.0.3
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: A library to read WebEx events through the WebEx API.
|
178
|
+
test_files:
|
179
|
+
- spec/fixtures/responses/webex_events.xml
|
180
|
+
- spec/fixtures/responses/webex_events_auth_error.xml
|
181
|
+
- spec/fixtures/responses/webex_events_no_results.xml
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
- spec/web_ex/events/configuration_spec.rb
|
184
|
+
- spec/web_ex/events/event_list_spec.rb
|
185
|
+
- spec/web_ex/events/event_spec.rb
|
186
|
+
- spec/web_ex/events/event_summary_request_spec.rb
|