open311-validator 0.0.1
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.
- data/LICENSE +14 -0
- data/README.markdown +7 -0
- data/bin/open311-validate +41 -0
- data/lib/client.rb +70 -0
- data/lib/resource.rb +98 -0
- data/lib/ruby_spec.rb +75 -0
- data/lib/session.rb +106 -0
- data/lib/test_helper.rb +37 -0
- data/lib/validate_311.rb +11 -0
- data/tests/create.rb +29 -0
- data/tests/discovery.rb +105 -0
- data/tests/service_definition.rb +11 -0
- data/tests/services.rb +18 -0
- metadata +106 -0
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright 2011 SeeClickFix
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
14
|
+
|
data/README.markdown
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
5
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
require 'validate_311'
|
9
|
+
|
10
|
+
options = { :discovery_url => 'http://seeclickfix.com/open311/discovery',
|
11
|
+
:production => false,
|
12
|
+
:write => false
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
op = OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: validate [options]"
|
18
|
+
opts.on('-u', '--url [discovery_url]','') do |url|
|
19
|
+
options[:discovery_url] = url if url
|
20
|
+
end
|
21
|
+
opts.on('-p', '--production [true/false]', 'Default: false') do |resp|
|
22
|
+
options[:production] = resp unless resp.nil?
|
23
|
+
end
|
24
|
+
opts.on('-k', '--api_key [key]', 'Default: none') do |resp|
|
25
|
+
options[:api_key] = resp unless resp.nil?
|
26
|
+
end
|
27
|
+
opts.on('-w', '--write [true/false]', 'Default: false') do |resp|
|
28
|
+
options[:write] = resp unless resp.nil?
|
29
|
+
end
|
30
|
+
opts.on('-j', '--jurisdiction_id [jurisdiction_id]', 'Default: none') do |resp|
|
31
|
+
options[:jurisdiction_id] = resp unless resp.nil?
|
32
|
+
end
|
33
|
+
opts.on('-a', '--address [address]', 'Default: none') do |resp|
|
34
|
+
options[:address] = resp unless resp.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
op.parse!
|
39
|
+
|
40
|
+
@session = Session.new(options)
|
41
|
+
@session.valid? ? @session.run_tests : (puts op)
|
data/lib/client.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Client
|
4
|
+
attr_accessor :raw, :base, :format, :unwrap
|
5
|
+
|
6
|
+
def initialize(base,format)
|
7
|
+
@base = base
|
8
|
+
@format = format
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_and_unwrap(url,unwrap)
|
12
|
+
@unwrap = unwrap
|
13
|
+
get(url)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(url)
|
17
|
+
@raw = HTTParty.get("#{@base}#{url}")
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def post(url,body)
|
22
|
+
# TODO: remove. This is simply for my testing.
|
23
|
+
url = 'http://localhost:3000/open311/requests.xml'
|
24
|
+
@raw = HTTParty.post(url, :body => body)
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def response
|
29
|
+
if @format == 'xml' and !@unwrap.nil?
|
30
|
+
Array(Session.unwrap(raw_response,@unwrap))
|
31
|
+
else
|
32
|
+
raw_response
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def raw_response
|
37
|
+
Client.hash2ostruct(@raw.parsed_response)
|
38
|
+
end
|
39
|
+
|
40
|
+
def headers
|
41
|
+
Client.hash2ostruct(@raw.headers)
|
42
|
+
end
|
43
|
+
|
44
|
+
def body
|
45
|
+
@raw.body
|
46
|
+
end
|
47
|
+
|
48
|
+
def request
|
49
|
+
@raw.request
|
50
|
+
end
|
51
|
+
|
52
|
+
# Recursively create ostruct obj from
|
53
|
+
# httparty's Hash/Array mess.
|
54
|
+
def self.hash2ostruct(object)
|
55
|
+
return case object
|
56
|
+
when Hash
|
57
|
+
object = object.clone
|
58
|
+
object.each do |key, value|
|
59
|
+
object[key] = Client.hash2ostruct(value)
|
60
|
+
end
|
61
|
+
OpenStruct.new(object)
|
62
|
+
when Array
|
63
|
+
object = object.clone
|
64
|
+
object.map! { |i| Client.hash2ostruct(i) }
|
65
|
+
else
|
66
|
+
object
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/resource.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
attr_accessor :options, :raw
|
5
|
+
|
6
|
+
def initialize(session,options)
|
7
|
+
@options = options
|
8
|
+
@session = session
|
9
|
+
@last_resource = session.resource
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_next
|
13
|
+
self.send @options[:with]
|
14
|
+
end
|
15
|
+
|
16
|
+
def discovery_url
|
17
|
+
@raw = OpenStruct.new
|
18
|
+
@raw.json = Client.new(@options[:discovery_url],'json').get(".json")
|
19
|
+
@raw.xml = Client.new(@options[:discovery_url],'xml').get(".xml")
|
20
|
+
end
|
21
|
+
|
22
|
+
def services_resource
|
23
|
+
@raw = []
|
24
|
+
@session.endpoint_array.each do |endpoint|
|
25
|
+
response = Client.new(endpoint[0],endpoint[1])
|
26
|
+
response.get_and_unwrap("/services.#{endpoint[1]}?jurisdiction_id=#{@options[:jurisdiction_id]}",'services.service')
|
27
|
+
@raw << response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def definition_resource
|
32
|
+
@raw = []
|
33
|
+
@session.raw_services.each do |raw_service|
|
34
|
+
raw_service.response.each do |service|
|
35
|
+
next if !service.metadata or service.metadata == 'false'
|
36
|
+
response = Client.new(raw_service.base,raw_service.format)
|
37
|
+
response.get_and_unwrap("/services/#{service.service_code}.#{raw_service.format}?jurisdiction_id=#{@options[:jurisdiction_id]}",'')
|
38
|
+
@raw << response
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Purpose: Create service requests
|
45
|
+
# URL: https://[API endpoint]/requests.[format]
|
46
|
+
# Sample URL: https://api.city.gov/dev/v2/requests.xml
|
47
|
+
# Format sent: Content-Type: application/x-www-form-urlencoded
|
48
|
+
# Formats returned: XML (JSON available if denoted by Service Discovery)
|
49
|
+
# HTTP Method: POST
|
50
|
+
# Requires API Key: Yes
|
51
|
+
#
|
52
|
+
#
|
53
|
+
# Required Arguments
|
54
|
+
# jurisdiction_id
|
55
|
+
# service_code (obtained from GET Service List method)
|
56
|
+
# location: either lat & long or address_string or address_id must be submitted
|
57
|
+
# attribute - only required if the service_code requires a service definition with required fields
|
58
|
+
# Explanation: An array of key/value responses based on Service Definitions. This takes the form of attribute[code]=value where multiple code/value pairs can be specified as well as multiple values for the same code in the case of a multivaluelist datatype (attribute[code1][]=value1&attribute[code1][]=value2&attribute[code1][]=value3) - see example
|
59
|
+
#
|
60
|
+
def create_resource_once
|
61
|
+
@raw.xml = []
|
62
|
+
@raw.json = []
|
63
|
+
# For each endpoint...
|
64
|
+
@session.discovery.xml.response.discovery.endpoints.endpoint.each do |endpoint|
|
65
|
+
next if type(endpoint) == 'production' and !@options.production
|
66
|
+
@raw.xml << Client.new.post("#{endpoint.url}/requests.xml",data_from_options)
|
67
|
+
end
|
68
|
+
|
69
|
+
@session.discovery.json.response.endpoints.each do |endpoint|
|
70
|
+
next if type(endpoint) == 'production' and !@options.production
|
71
|
+
@raw.json << Client.new.post("#{endpoint.url}/requests.json",data_from_options)
|
72
|
+
end if @options.json
|
73
|
+
|
74
|
+
@raw.options = @options
|
75
|
+
@raw
|
76
|
+
end
|
77
|
+
|
78
|
+
def data_from_options
|
79
|
+
## Converting @options back to a hash and merge them with user-supplied
|
80
|
+
# post data.
|
81
|
+
{ :api_key => @options.api_key,
|
82
|
+
:jurisdiction_id => @options.jurisdiction_id,
|
83
|
+
:service_code => first_service_code,
|
84
|
+
:address_string => @options.address
|
85
|
+
}.merge!(@options.post)
|
86
|
+
end
|
87
|
+
|
88
|
+
def first_service_code
|
89
|
+
@session.resources[1].xml.first.response.services.service.service_code
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
end
|
data/lib/ruby_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
# class PositiveSpec
|
3
|
+
# def initialize(obj,required)
|
4
|
+
# @obj = obj
|
5
|
+
# @required = required
|
6
|
+
# end
|
7
|
+
#
|
8
|
+
# def ==(other)
|
9
|
+
# if @obj != other
|
10
|
+
# raise Exception.new("#{requirement}: \"Expected: #{other} Got: #{@obj}\"")
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# def >(other)
|
15
|
+
# unless @obj > other
|
16
|
+
# raise Exception.new("#{requirement}: \"Expected: #{other} Got: #{@obj}\"")
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def requirement
|
21
|
+
# @required ? "REQUIRED" : "WARNING"
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
|
25
|
+
# class NegativeSpec
|
26
|
+
# def initialize(obj,required)
|
27
|
+
# @obj = obj
|
28
|
+
# @required = required
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def ==(other)
|
32
|
+
# if @obj == other
|
33
|
+
# raise Exception.new("#{requirement}: \"Expected: #{other} Got: #{@obj}\"")
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# def requirement
|
38
|
+
# @required ? "REQUIRED" : "WARNING"
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
|
42
|
+
# class Object
|
43
|
+
# def should
|
44
|
+
# PositiveSpec.new(self,false)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def should_not
|
48
|
+
# NegativeSpec.new(self,false)
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def must
|
52
|
+
# RequiredPositiveSpec.new(self,true)
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# def must_not
|
56
|
+
# RequiredNegativeSpec.new(self,true)
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
|
60
|
+
|
61
|
+
def rule(msg)
|
62
|
+
begin
|
63
|
+
yield
|
64
|
+
print " #{msg.to_s.lstrip.ljust(90)[0..70]}","PASSED"
|
65
|
+
rescue Exception => e
|
66
|
+
print " #{msg.to_s.lstrip.ljust(90)[0..70]}","FAILED #{e.to_s}"
|
67
|
+
end
|
68
|
+
puts ""
|
69
|
+
end
|
70
|
+
|
71
|
+
def test(msg,options)
|
72
|
+
puts " Testing - #{msg.to_s}"
|
73
|
+
@session.add_resource(options)
|
74
|
+
yield
|
75
|
+
end
|
data/lib/session.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
class Session
|
3
|
+
attr_accessor :options
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@resources = []
|
7
|
+
@options = {
|
8
|
+
:production => false,
|
9
|
+
:write => false
|
10
|
+
}.merge options
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_tests
|
14
|
+
load 'tests/discovery.rb'
|
15
|
+
load 'tests/services.rb'
|
16
|
+
load 'tests/service_definition.rb'
|
17
|
+
load 'tests/create.rb' if @options[:write]
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid?
|
21
|
+
@options[:discovery_url] &&
|
22
|
+
!@options[:production].nil? &&
|
23
|
+
!@options[:write].nil? &&
|
24
|
+
!@options[:production].nil? &&
|
25
|
+
(!@options[:write] || ( @options[:write] && !@options[:address].nil? ))
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Resource mgmt.
|
30
|
+
def add_resource(options)
|
31
|
+
resource = Resource.new(self,@options.merge(options))
|
32
|
+
resource.get_next
|
33
|
+
@resources << resource
|
34
|
+
end
|
35
|
+
|
36
|
+
def resources
|
37
|
+
@resources
|
38
|
+
end
|
39
|
+
|
40
|
+
def discovery
|
41
|
+
@resources.first
|
42
|
+
end
|
43
|
+
|
44
|
+
def resource
|
45
|
+
@resources.last
|
46
|
+
end
|
47
|
+
|
48
|
+
# Endpoint mgmt.
|
49
|
+
def endpoint_array
|
50
|
+
t = []
|
51
|
+
all_endpoints.each do |endpoint|
|
52
|
+
Session.endpoint_formats_as_array(endpoint).each do |format|
|
53
|
+
next if format =~ /^.*html$/i
|
54
|
+
t << [endpoint.url,format]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
t
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.endpoint_formats_as_array(endpoint)
|
61
|
+
Session.endpoint_formats(endpoint).map{|format| format.to_s.split('/')[1]}
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.endpoint_formats(endpoint)
|
65
|
+
endpoint.formats.is_a?(Array) ? endpoint.formats : Array(Session.unwrap(endpoint,'formats.format'))
|
66
|
+
end
|
67
|
+
|
68
|
+
def all_endpoints
|
69
|
+
json_endpoints + xml_endpoints
|
70
|
+
end
|
71
|
+
|
72
|
+
def json_endpoints
|
73
|
+
Session.unwrap(discovery.raw.json, 'response.endpoints').select{|endpoint| production_safe?(endpoint) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def xml_endpoints
|
77
|
+
Array(Session.unwrap(discovery.raw.xml,'response.discovery.endpoints.endpoint')).select{|endpoint| production_safe?(endpoint) }
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Services Lookup
|
82
|
+
#
|
83
|
+
def services
|
84
|
+
@resources[1].raw.map{|r| r.response }.flatten
|
85
|
+
end
|
86
|
+
|
87
|
+
def raw_services
|
88
|
+
@resources[1].raw
|
89
|
+
end
|
90
|
+
|
91
|
+
# Class Methods
|
92
|
+
def self.unwrap(obj,methods)
|
93
|
+
methods.split('.').each do |method|
|
94
|
+
obj = obj.send method.to_sym
|
95
|
+
end
|
96
|
+
obj
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# The marshal_dump is to avoid calling .type on the obj.
|
102
|
+
def production_safe?(endpoint)
|
103
|
+
endpoint.marshal_dump[:type] != 'production' or @options[:production]
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/lib/test_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module TestHelper
|
3
|
+
|
4
|
+
def validate_date_time(time)
|
5
|
+
time.is_a?(Time) ? time : Time.iso8601(time) rescue false
|
6
|
+
end
|
7
|
+
|
8
|
+
def resource
|
9
|
+
@session.resource
|
10
|
+
end
|
11
|
+
|
12
|
+
def xml_endpoints
|
13
|
+
@session.discovery.raw.xml.response.discovery.endpoints.endpoint
|
14
|
+
end
|
15
|
+
|
16
|
+
def json_endpoints
|
17
|
+
@session.discovery.raw.json.response.endpoints
|
18
|
+
end
|
19
|
+
|
20
|
+
def all_endpoints
|
21
|
+
xml_endpoints + json_endpoints
|
22
|
+
end
|
23
|
+
|
24
|
+
def v2_endpoints
|
25
|
+
all_endpoints.select{|endpoint| endpoint.specification =~ /^.*_v2$/i }
|
26
|
+
end
|
27
|
+
|
28
|
+
def xml_discovery
|
29
|
+
@session.discovery.raw.xml.response.discovery
|
30
|
+
end
|
31
|
+
|
32
|
+
def json_discovery
|
33
|
+
@session.discovery.raw.json.response
|
34
|
+
end
|
35
|
+
|
36
|
+
extend self
|
37
|
+
end
|
data/lib/validate_311.rb
ADDED
data/tests/create.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
# @session.resources = History of resources for entire session of tests.
|
4
|
+
# @resource = currently tested resource.
|
5
|
+
# @resource.options = options used for that resource
|
6
|
+
# @resource.json.response = objectified response
|
7
|
+
# @resource.json.headers = response headers
|
8
|
+
# @resource.json.body = response body
|
9
|
+
# @resource.json.request = httparty request object
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
data = { :email => 'foo@bar.com', :description => 'I know' }
|
14
|
+
|
15
|
+
test "Creating Client Once", { :with => :create_resource_once, :post => data } do
|
16
|
+
|
17
|
+
rule 'each should return something' do
|
18
|
+
@resource.xml.each do |request|
|
19
|
+
request.response.should_not == ''
|
20
|
+
end
|
21
|
+
|
22
|
+
if @resource.options.json
|
23
|
+
@resource.json.each do |request|
|
24
|
+
request.response.should_not == ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/tests/discovery.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'test_helper';include TestHelper
|
2
|
+
|
3
|
+
test "Service Discovery", :with => :discovery_url do
|
4
|
+
|
5
|
+
rule 'url should end with "discovery"' do
|
6
|
+
resource.options[:discovery_url][-9..-1].should == 'discovery'
|
7
|
+
end
|
8
|
+
|
9
|
+
rule 'both formats should return results' do
|
10
|
+
resource.raw.xml.to_s.strip.should_not == '' && resource.raw.json.to_s.strip.should_not == ''
|
11
|
+
end
|
12
|
+
|
13
|
+
rule 'both formats should have contacts' do
|
14
|
+
xml_discovery.contact.to_s.strip.should_not == ''
|
15
|
+
json_discovery.contact.to_s.strip.should_not == ''
|
16
|
+
end
|
17
|
+
|
18
|
+
rule 'both formats should have key_service information' do
|
19
|
+
xml_discovery.key_service.to_s.strip.should_not == ''
|
20
|
+
json_discovery.key_service.to_s.strip.should_not == ''
|
21
|
+
end
|
22
|
+
|
23
|
+
rule 'return valid DateTime objects' do
|
24
|
+
validate_date_time(xml_discovery.changeset).class.should == Time
|
25
|
+
validate_date_time(json_discovery.changeset).class.should == Time
|
26
|
+
end
|
27
|
+
|
28
|
+
rule "contacts should return same for both formats" do
|
29
|
+
xml_discovery.contacts.should == json_discovery.contacts
|
30
|
+
end
|
31
|
+
|
32
|
+
rule "xml endpoint should be an array" do
|
33
|
+
xml_endpoints.class.should == Array
|
34
|
+
end
|
35
|
+
|
36
|
+
rule "there should be at least one endpoint" do
|
37
|
+
xml_endpoints.size.should > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
rule "each endpoint should have a specification" do
|
41
|
+
all_endpoints.each do |endpoint|
|
42
|
+
endpoint.specification.should_not == ''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
rule "each endpoint should have a url" do
|
47
|
+
all_endpoints.each do |endpoint|
|
48
|
+
endpoint.url.should_not == ''
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
rule "each endpoint should have a changeset" do
|
53
|
+
all_endpoints.each do |endpoint|
|
54
|
+
endpoint.changeset.should_not == ''
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
rule "each endpoint should have a valid changeset" do
|
59
|
+
all_endpoints.each do |endpoint|
|
60
|
+
validate_date_time(endpoint.changeset).class.should == Time
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
rule "each endpoint should have a changeset in the past" do
|
65
|
+
all_endpoints.each do |endpoint|
|
66
|
+
validate_date_time(endpoint.changeset).should < Time.now
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
rule "each endpoint should have a type" do
|
71
|
+
all_endpoints.each do |endpoint|
|
72
|
+
endpoint.marshal_dump[:type].should_not == ''
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
rule "each endpoint should have an array of formats" do
|
77
|
+
xml_endpoints.each do |endpoint|
|
78
|
+
endpoint.formats.format.class.should == Array
|
79
|
+
end
|
80
|
+
json_endpoints.each do |endpoint|
|
81
|
+
endpoint.formats.class.should == Array
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
rule "each endpoint should have at least one supported format" do
|
86
|
+
all_endpoints.each do |endpoint|
|
87
|
+
Session.endpoint_formats(endpoint).size.should > 0
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
rule "all v2 endpoints should support xml" do
|
92
|
+
v2_endpoints.each do |endpoint|
|
93
|
+
Session.endpoint_formats(endpoint).select{|format| format == 'text/xml' }.size.should > 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test_helper';include TestHelper
|
2
|
+
|
3
|
+
test "Service Definitions", :with => :definition_resource do
|
4
|
+
|
5
|
+
rule 'test resource' do
|
6
|
+
# raise @session.resource.raw.inspect
|
7
|
+
# raise @session.prev_resource.inspect
|
8
|
+
# raise @resource.xml.inspect
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
data/tests/services.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_helper';include TestHelper
|
2
|
+
|
3
|
+
|
4
|
+
test "Services", :with => :services_resource do
|
5
|
+
|
6
|
+
rule 'there should be at least one service right?' do
|
7
|
+
@session.raw_services.each do |services|
|
8
|
+
services.response.size.should > 0
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
rule 'all services should have a service code' do
|
13
|
+
@session.services.each do |service|
|
14
|
+
service.service_code.should_not == nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: open311-validator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- SeeClickFix (Jeff Blasius)
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-11-14 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: httparty
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rspec
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: A command line Open311 validator. (http://open311.org)
|
49
|
+
email: dev@seeclickfix.com
|
50
|
+
executables:
|
51
|
+
- open311-validate
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
files:
|
57
|
+
- LICENSE
|
58
|
+
- README.markdown
|
59
|
+
- bin/open311-validate
|
60
|
+
- lib/client.rb
|
61
|
+
- lib/resource.rb
|
62
|
+
- lib/ruby_spec.rb
|
63
|
+
- lib/session.rb
|
64
|
+
- lib/test_helper.rb
|
65
|
+
- lib/validate_311.rb
|
66
|
+
- tests/create.rb
|
67
|
+
- tests/discovery.rb
|
68
|
+
- tests/service_definition.rb
|
69
|
+
- tests/services.rb
|
70
|
+
homepage: http://github.com/seeclickfix/open311-validator
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 17
|
93
|
+
segments:
|
94
|
+
- 1
|
95
|
+
- 3
|
96
|
+
- 5
|
97
|
+
version: 1.3.5
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.11
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Open311 Validator
|
105
|
+
test_files: []
|
106
|
+
|