atdis 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +0 -1
- data/Gemfile +1 -1
- data/README.md +25 -2
- data/Rakefile +1 -1
- data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).doc +0 -0
- data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).pdf +0 -0
- data/lib/atdis.rb +2 -7
- data/lib/atdis/feed.rb +80 -8
- data/lib/atdis/model.rb +74 -128
- data/lib/atdis/models/address.rb +17 -0
- data/lib/atdis/models/application.rb +31 -0
- data/lib/atdis/models/authority.rb +19 -0
- data/lib/atdis/models/document.rb +16 -0
- data/lib/atdis/models/event.rb +16 -0
- data/lib/atdis/models/info.rb +81 -0
- data/lib/atdis/models/land_title_ref.rb +26 -0
- data/lib/atdis/models/location.rb +23 -0
- data/lib/atdis/models/page.rb +56 -0
- data/lib/atdis/models/pagination.rb +68 -0
- data/lib/atdis/models/person.rb +14 -0
- data/lib/atdis/models/reference.rb +13 -0
- data/lib/atdis/models/response.rb +16 -0
- data/lib/atdis/models/torrens_title.rb +24 -0
- data/lib/atdis/validators.rb +26 -10
- data/lib/atdis/version.rb +1 -1
- data/spec/atdis/feed_spec.rb +78 -22
- data/spec/atdis/model_spec.rb +80 -131
- data/spec/atdis/models/address_spec.rb +22 -0
- data/spec/atdis/models/application_spec.rb +246 -0
- data/spec/atdis/models/authority_spec.rb +34 -0
- data/spec/atdis/models/document_spec.rb +19 -0
- data/spec/atdis/models/event_spec.rb +29 -0
- data/spec/atdis/models/info_spec.rb +303 -0
- data/spec/atdis/models/land_title_ref_spec.rb +39 -0
- data/spec/atdis/models/location_spec.rb +95 -0
- data/spec/atdis/models/page_spec.rb +296 -0
- data/spec/atdis/models/pagination_spec.rb +153 -0
- data/spec/atdis/models/person_spec.rb +19 -0
- data/spec/atdis/models/reference_spec.rb +55 -0
- data/spec/atdis/models/response_spec.rb +5 -0
- data/spec/atdis/models/torrens_title_spec.rb +52 -0
- data/spec/atdis/separated_url_spec.rb +4 -4
- metadata +141 -135
- data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).doc +0 -0
- data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).pdf +0 -0
- data/lib/atdis/application.rb +0 -78
- data/lib/atdis/document.rb +0 -14
- data/lib/atdis/event.rb +0 -17
- data/lib/atdis/location.rb +0 -21
- data/lib/atdis/page.rb +0 -130
- data/lib/atdis/person.rb +0 -12
- data/spec/atdis/application_spec.rb +0 -539
- data/spec/atdis/document_spec.rb +0 -19
- data/spec/atdis/event_spec.rb +0 -29
- data/spec/atdis/location_spec.rb +0 -148
- data/spec/atdis/page_spec.rb +0 -492
- data/spec/atdis/person_spec.rb +0 -19
Binary file
|
Binary file
|
data/lib/atdis/application.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
|
3
|
-
module ATDIS
|
4
|
-
class Application < Model
|
5
|
-
# TODO When we remove support for Ruby 1.8 we can convert field_mappings back to a hash
|
6
|
-
# which is much more readable
|
7
|
-
set_field_mappings [
|
8
|
-
[:application, [
|
9
|
-
[:info, [
|
10
|
-
[:dat_id, [:dat_id, String, {:level => 1}]],
|
11
|
-
[:last_modified_date, [:last_modified_date, DateTime, {:level => 1}]],
|
12
|
-
[:description, [:description, String, {:level => 1}]],
|
13
|
-
[:authority, [:authority, String, {:level => 1}]],
|
14
|
-
[:lodgement_date, [:lodgement_date, DateTime, {:level => 1}]],
|
15
|
-
[:determination_date, [:determination_date, DateTime, {:level => 1}]],
|
16
|
-
[:status, [:status, String, {:level => 1}]],
|
17
|
-
[:notification_start_date, [:notification_start_date, DateTime, {:level => 1}]],
|
18
|
-
[:notification_end_date, [:notification_end_date, DateTime, {:level => 1}]],
|
19
|
-
[:officer, [:officer, String, {:level => 1}]],
|
20
|
-
[:estimated_cost, [:estimated_cost, String, {:level => 1}]]
|
21
|
-
]],
|
22
|
-
[:reference, [
|
23
|
-
[:more_info_url, [:more_info_url, URI, {:level => 1}]],
|
24
|
-
[:comments_url, [:comments_url, URI, {:level => 1}]]
|
25
|
-
]],
|
26
|
-
[:location, [:location, Location, {:level => 1}]],
|
27
|
-
[:events, [:events, Event, {:level => 1}]],
|
28
|
-
[:documents, [:documents, Document, {:level => 1}]],
|
29
|
-
[:people, [:people, Person, {:level => 2}]],
|
30
|
-
[:extended, [:extended, Object, {:level => 3}]]
|
31
|
-
]]
|
32
|
-
]
|
33
|
-
|
34
|
-
# Mandatory parameters
|
35
|
-
validates :dat_id, :last_modified_date, :description, :authority, :lodgement_date, :determination_date, :status,
|
36
|
-
:presence_before_type_cast => {:spec_section => "4.3.1"}
|
37
|
-
validates :more_info_url, :presence_before_type_cast => {:spec_section => "4.3.2"}
|
38
|
-
validates :location, :presence_before_type_cast => {:spec_section => "4.3.3"}
|
39
|
-
validates :events, :presence_before_type_cast => {:spec_section => "4.3.4"}
|
40
|
-
validates :documents, :presence_before_type_cast => {:spec_section => "4.3.5"}
|
41
|
-
|
42
|
-
# Other validations
|
43
|
-
validates :last_modified_date, :lodgement_date, :date_time => {:spec_section => "4.3.8"}
|
44
|
-
validates :determination_date, :notification_start_date, :notification_end_date, :date_time_or_none => {:spec_section => "4.3.1"}
|
45
|
-
validates :more_info_url, :http_url => {:spec_section => "4.3.2"}
|
46
|
-
validates :location, :events, :documents, :people, :valid => true
|
47
|
-
validates :events, :documents, :array => {:spec_section => "4.3.4"}
|
48
|
-
# TODO people should be an array if it's included
|
49
|
-
|
50
|
-
validate :notification_dates_consistent!
|
51
|
-
|
52
|
-
def notification_dates_consistent!
|
53
|
-
if notification_start_date_before_type_cast == "none" && notification_end_date_before_type_cast != "none"
|
54
|
-
errors.add(:notification_start_date, ErrorMessage["can't be none unless notification_end_date is none as well", "4.3.1"])
|
55
|
-
end
|
56
|
-
if notification_start_date_before_type_cast != "none" && notification_end_date_before_type_cast == "none"
|
57
|
-
errors.add(:notification_end_date, ErrorMessage["can't be none unless notification_start_date is none as well", "4.3.1"])
|
58
|
-
end
|
59
|
-
if notification_start_date_before_type_cast && notification_end_date_before_type_cast.blank?
|
60
|
-
errors.add(:notification_end_date, ErrorMessage["can not be blank if notification_start_date is set", "4.3.1"])
|
61
|
-
end
|
62
|
-
if notification_start_date_before_type_cast.blank? && notification_end_date_before_type_cast
|
63
|
-
errors.add(:notification_start_date, ErrorMessage["can not be blank if notification_end_date is set", "4.3.1"])
|
64
|
-
end
|
65
|
-
if notification_start_date && notification_end_date && notification_start_date > notification_end_date
|
66
|
-
errors.add(:notification_end_date, ErrorMessage["can not be earlier than notification_start_date", "4.3.1"])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# TODO Validate contents of estimated_cost
|
71
|
-
# TODO Validate associated like locations, events, documents, people
|
72
|
-
# TODO Do we need to do extra checking to ensure that events, documents and people are arrays?
|
73
|
-
# TODO Separate validation for L2 and L3 compliance?
|
74
|
-
# TODO Validate date orders. i.e. determination_date >= lodgement_date and notification_end_date >= notification_start_date
|
75
|
-
# TODO also last_modified_date >= lodgement_date and all the other dates. In other words we can't put a future date in. That
|
76
|
-
# doesn't make sense in this context. Also should check dates in things like Events (to see that they're not in the future)
|
77
|
-
end
|
78
|
-
end
|
data/lib/atdis/document.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
module ATDIS
|
2
|
-
class Document < Model
|
3
|
-
set_field_mappings [
|
4
|
-
[:ref, [:ref, String, {:level => 1}]],
|
5
|
-
[:title, [:title, String, {:level => 1}]],
|
6
|
-
[:document_url, [:document_url, URI, {:level => 1}]]
|
7
|
-
]
|
8
|
-
|
9
|
-
# Mandatory parameters
|
10
|
-
validates :ref, :title, :document_url, :presence_before_type_cast => {:spec_section => "4.3.5"}
|
11
|
-
# Other validations
|
12
|
-
validates :document_url, :http_url => {:spec_section => "4.3.5"}
|
13
|
-
end
|
14
|
-
end
|
data/lib/atdis/event.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module ATDIS
|
2
|
-
class Event < Model
|
3
|
-
set_field_mappings [
|
4
|
-
[:id, [:id, String, {:level => 1}]],
|
5
|
-
[:date, [:date, DateTime, {:level => 1}]],
|
6
|
-
[:description, [:description, String, {:level => 1}]],
|
7
|
-
[:event_type, [:event_type, String, {:level => 1}]],
|
8
|
-
[:status, [:status, String, {:level => 1}]]
|
9
|
-
]
|
10
|
-
|
11
|
-
# Mandatory parameters
|
12
|
-
validates :id, :date, :description, :presence_before_type_cast => {:spec_section => "4.3.4"}
|
13
|
-
end
|
14
|
-
|
15
|
-
# TODO Check that :id is unique within an authority
|
16
|
-
|
17
|
-
end
|
data/lib/atdis/location.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require "rgeo/geo_json"
|
2
|
-
|
3
|
-
module ATDIS
|
4
|
-
class Location < Model
|
5
|
-
set_field_mappings [
|
6
|
-
[:address, [:address, String, {:level => 1}]],
|
7
|
-
[:land_title_ref, [
|
8
|
-
[:lot, [:lot, String, {:level => 1}]],
|
9
|
-
[:section, [:section, String, {:none_is_nil => true, :level => 1}]],
|
10
|
-
[:dpsp_id, [:dpsp_id, String, {:level => 1}]]
|
11
|
-
]],
|
12
|
-
[:geometry, [:geometry, RGeo::GeoJSON, {:level => 1}]]
|
13
|
-
]
|
14
|
-
# Mandatory parameters
|
15
|
-
validates :address, :lot, :section, :dpsp_id, :presence_before_type_cast => {:spec_section => "4.3.3"}
|
16
|
-
|
17
|
-
validates :geometry, :geo_json => {:spec_section => "4.3.3"}
|
18
|
-
|
19
|
-
# TODO: Provide warning if dpsp_id doesn't start with "DP" or "SP"
|
20
|
-
end
|
21
|
-
end
|
data/lib/atdis/page.rb
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
module ATDIS
|
2
|
-
class Page < Model
|
3
|
-
attr_accessor :url
|
4
|
-
|
5
|
-
set_field_mappings [
|
6
|
-
[:response, [:results, Application, {:level => 1}]],
|
7
|
-
[:count, [:count, Fixnum, {:level => 2}]],
|
8
|
-
[:pagination, [
|
9
|
-
[:previous, [:previous_page_no, Fixnum, {:level => 2}]],
|
10
|
-
[:next, [:next_page_no, Fixnum, {:level => 2}]],
|
11
|
-
[:current, [:current_page_no, Fixnum, {:level => 2}]],
|
12
|
-
[:per_page, [:no_results_per_page, Fixnum, {:level => 2}]],
|
13
|
-
[:count, [:total_no_results, Fixnum, {:level => 2}]],
|
14
|
-
[:pages, [:total_no_pages, Fixnum, {:level => 2}]]
|
15
|
-
]]
|
16
|
-
]
|
17
|
-
|
18
|
-
# Mandatory parameters
|
19
|
-
validates :results, :presence_before_type_cast => {:spec_section => "4.3"}
|
20
|
-
validates :results, :valid => true
|
21
|
-
validate :count_is_consistent, :all_pagination_is_present, :previous_page_no_is_consistent, :next_page_no_is_consistent
|
22
|
-
validate :current_page_no_is_consistent, :total_no_results_is_consistent
|
23
|
-
validate :json_loaded_correctly!
|
24
|
-
|
25
|
-
def json_loaded_correctly!
|
26
|
-
if json_load_error
|
27
|
-
errors.add(:json, ErrorMessage["Invalid JSON: #{json_load_error}", nil])
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# If some of the pagination fields are present all of the required ones should be present
|
32
|
-
def all_pagination_is_present
|
33
|
-
if count || previous_page_no || next_page_no || current_page_no || no_results_per_page ||
|
34
|
-
total_no_results || total_no_pages
|
35
|
-
errors.add(:count, ErrorMessage["should be present if pagination is being used", "6.5"]) if count.nil?
|
36
|
-
errors.add(:current_page_no, ErrorMessage["should be present if pagination is being used", "6.5"]) if current_page_no.nil?
|
37
|
-
errors.add(:no_results_per_page, ErrorMessage["should be present if pagination is being used", "6.5"]) if no_results_per_page.nil?
|
38
|
-
errors.add(:total_no_results, ErrorMessage["should be present if pagination is being used", "6.5"]) if total_no_results.nil?
|
39
|
-
errors.add(:total_no_pages, ErrorMessage["should be present if pagination is being used", "6.5"]) if total_no_pages.nil?
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def count_is_consistent
|
44
|
-
if count
|
45
|
-
errors.add(:count, ErrorMessage["is not the same as the number of applications returned", "6.5"]) if count != results.count
|
46
|
-
errors.add(:count, ErrorMessage["should not be larger than the number of results per page", "6.5"]) if count > no_results_per_page
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def previous_page_no_is_consistent
|
51
|
-
if current_page_no
|
52
|
-
if previous_page_no
|
53
|
-
if previous_page_no != current_page_no - 1
|
54
|
-
errors.add(:previous_page_no, ErrorMessage["should be one less than current page number or null if first page", "6.5"])
|
55
|
-
end
|
56
|
-
if current_page_no == 1
|
57
|
-
errors.add(:previous_page_no, ErrorMessage["should be null if on the first page", "6.5"])
|
58
|
-
end
|
59
|
-
else
|
60
|
-
if current_page_no > 1
|
61
|
-
errors.add(:previous_page_no, ErrorMessage["can't be null if not on the first page", "6.5"])
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def next_page_no_is_consistent
|
68
|
-
if next_page_no && next_page_no != current_page_no + 1
|
69
|
-
errors.add(:next_page_no, ErrorMessage["should be one greater than current page number or null if last page", "6.5"])
|
70
|
-
end
|
71
|
-
if next_page_no.nil? && current_page_no != total_no_pages
|
72
|
-
errors.add(:next_page_no, ErrorMessage["can't be null if not on the last page", "6.5"])
|
73
|
-
end
|
74
|
-
if next_page_no && current_page_no == total_no_pages
|
75
|
-
errors.add(:next_page_no, ErrorMessage["should be null if on the last page", "6.5"])
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def current_page_no_is_consistent
|
80
|
-
if current_page_no
|
81
|
-
errors.add(:current_page_no, ErrorMessage["is larger than the number of pages", "6.5"]) if current_page_no > total_no_pages
|
82
|
-
errors.add(:current_page_no, ErrorMessage["can not be less than 1", "6.5"]) if current_page_no < 1
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def total_no_results_is_consistent
|
87
|
-
if total_no_pages && total_no_results > total_no_pages * no_results_per_page
|
88
|
-
errors.add(:total_no_results, ErrorMessage["is larger than can be retrieved through paging", "6.5"])
|
89
|
-
end
|
90
|
-
if total_no_pages && total_no_results <= (total_no_pages - 1) * no_results_per_page
|
91
|
-
errors.add(:total_no_results, ErrorMessage["could fit into a smaller number of pages", "6.5"])
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.read_url(url)
|
96
|
-
r = read_json(RestClient.get(url.to_s).to_str)
|
97
|
-
r.url = url.to_s
|
98
|
-
r
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.read_json(text)
|
102
|
-
begin
|
103
|
-
data = MultiJson.load(text, :symbolize_keys => true)
|
104
|
-
interpret(data)
|
105
|
-
rescue MultiJson::LoadError => e
|
106
|
-
a = interpret({:response => []})
|
107
|
-
a.json_load_error = e.to_s
|
108
|
-
a
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def previous_url
|
113
|
-
raise "Can't use previous_url when loaded with read_json" if url.nil?
|
114
|
-
ATDIS::SeparatedURL.merge(url, :page => previous_page_no) if previous_page_no
|
115
|
-
end
|
116
|
-
|
117
|
-
def next_url
|
118
|
-
raise "Can't use next_url when loaded with read_json" if url.nil?
|
119
|
-
ATDIS::SeparatedURL.merge(url, :page => next_page_no) if next_page_no
|
120
|
-
end
|
121
|
-
|
122
|
-
def previous
|
123
|
-
Page.read_url(previous_url) if previous_url
|
124
|
-
end
|
125
|
-
|
126
|
-
def next
|
127
|
-
Page.read_url(next_url) if next_url
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
data/lib/atdis/person.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
module ATDIS
|
2
|
-
class Person < Model
|
3
|
-
set_field_mappings [
|
4
|
-
[:name, [:name, String, {:level => 2}]],
|
5
|
-
[:role, [:role, String, {:level => 2}]],
|
6
|
-
[:contact, [:contact, String, {:level => 2}]]
|
7
|
-
]
|
8
|
-
|
9
|
-
# Mandatory parameters
|
10
|
-
validates :name, :role, :presence_before_type_cast => {:spec_section => "4.3.6"}
|
11
|
-
end
|
12
|
-
end
|
@@ -1,539 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe ATDIS::Application do
|
4
|
-
|
5
|
-
describe ".level_used?" do
|
6
|
-
it "level 3" do
|
7
|
-
a = ATDIS::Application.new(:extended => {:some_info => "here"})
|
8
|
-
a.level_used?(3).should be_true
|
9
|
-
end
|
10
|
-
|
11
|
-
it "level 2" do
|
12
|
-
a = ATDIS::Application.new(:people => [])
|
13
|
-
a.level_used?(2).should be_true
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context "extra parameter in json" do
|
18
|
-
it "should not be valid" do
|
19
|
-
ATDIS::Location.should_receive(:interpret).with(:foo => "Some location data").and_return(double(:valid? => true))
|
20
|
-
a = ATDIS::Application.interpret(:application => {
|
21
|
-
:info => {
|
22
|
-
:dat_id => "DA2013-0381",
|
23
|
-
:last_modified_date => "2013-04-20T02:01:07Z",
|
24
|
-
:description => "New pool plus deck",
|
25
|
-
:authority => "Example Council Shire Council",
|
26
|
-
:lodgement_date => "2013-04-20T02:01:07Z",
|
27
|
-
:determination_date => "2013-06-20",
|
28
|
-
:status => "OPEN"
|
29
|
-
},
|
30
|
-
:reference => {
|
31
|
-
# This is the extra parameter that shouldn't be here
|
32
|
-
:foo => "bar",
|
33
|
-
:more_info_url => "http://foo.com/bar"
|
34
|
-
},
|
35
|
-
:location => {:foo => "Some location data"},
|
36
|
-
:events => [],
|
37
|
-
:documents => []
|
38
|
-
})
|
39
|
-
a.should_not be_valid
|
40
|
-
a.errors.messages.should == {:json => [ATDIS::ErrorMessage['Unexpected parameters in json data: {"application":{"reference":{"foo":"bar"}}}', "4"]]}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe ".interpret" do
|
45
|
-
it "should parse the json and create an application object" do
|
46
|
-
application = double
|
47
|
-
|
48
|
-
ATDIS::Application.should_receive(:new).with(
|
49
|
-
:dat_id => "DA2013-0381",
|
50
|
-
:last_modified_date => "2013-04-20T02:01:07Z",
|
51
|
-
:description => "New pool plus deck",
|
52
|
-
:authority => "Example Council Shire Council",
|
53
|
-
:lodgement_date => "2013-04-20T02:01:07Z",
|
54
|
-
:determination_date => "2013-06-20",
|
55
|
-
:notification_start_date => "2013-04-20T02:01:07Z",
|
56
|
-
:notification_end_date => "2013-05-20T02:01:07Z",
|
57
|
-
:officer => "Ms Smith",
|
58
|
-
:estimated_cost => "50,000",
|
59
|
-
:status => "OPEN",
|
60
|
-
:more_info_url => "http://foo.com/bar",
|
61
|
-
:comments_url => "http://foo.com/comment",
|
62
|
-
:location => { :address => "123 Fourfivesix Street" },
|
63
|
-
:events => [ { :id => "event1" }, { :id => "event2" } ],
|
64
|
-
:documents => [ { :ref => "27B/6/a" }, { :ref => "27B/6/b" } ],
|
65
|
-
:people => [ { :name => "Tuttle" }, { :name => "Buttle" } ],
|
66
|
-
:extended => {:another_parameter => "with some value", :anything => "can go here"},
|
67
|
-
:json_left_overs => {}
|
68
|
-
).and_return(application)
|
69
|
-
|
70
|
-
ATDIS::Application.interpret(:application => {
|
71
|
-
:info => {
|
72
|
-
:dat_id => "DA2013-0381",
|
73
|
-
:last_modified_date => "2013-04-20T02:01:07Z",
|
74
|
-
:description => "New pool plus deck",
|
75
|
-
:authority => "Example Council Shire Council",
|
76
|
-
:lodgement_date => "2013-04-20T02:01:07Z",
|
77
|
-
:determination_date => "2013-06-20",
|
78
|
-
:notification_start_date => "2013-04-20T02:01:07Z",
|
79
|
-
:notification_end_date => "2013-05-20T02:01:07Z",
|
80
|
-
:officer => "Ms Smith",
|
81
|
-
# TODO: In ATDIS-1.0.3 it does not specify whether this is a float or a string
|
82
|
-
# and whether to include (or not) AUD or dollar sign. For the time being we'll
|
83
|
-
# just assume it's a free-form string
|
84
|
-
:estimated_cost => "50,000",
|
85
|
-
:status => "OPEN"
|
86
|
-
},
|
87
|
-
:reference => {
|
88
|
-
:more_info_url => "http://foo.com/bar",
|
89
|
-
:comments_url => "http://foo.com/comment"
|
90
|
-
},
|
91
|
-
:location => { :address => "123 Fourfivesix Street" },
|
92
|
-
:events => [ { :id => "event1" }, { :id => "event2" } ],
|
93
|
-
:documents => [ { :ref => "27B/6/a" }, { :ref => "27B/6/b" } ],
|
94
|
-
:people => [ { :name => "Tuttle" }, { :name => "Buttle" } ],
|
95
|
-
:extended => {:another_parameter => "with some value", :anything => "can go here"}
|
96
|
-
}).should == application
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should create a nil valued application when there is no information in the json" do
|
100
|
-
application = double
|
101
|
-
ATDIS::Application.should_receive(:new).with({:json_left_overs => {}, :status=>nil, :determination_date=>nil, :estimated_cost=>nil,
|
102
|
-
:comments_url=>nil, :description=>nil, :more_info_url=>nil, :dat_id=>nil, :notification_start_date=>nil, :location=>nil,
|
103
|
-
:extended=>nil, :events=>nil, :last_modified_date=>nil, :notification_end_date=>nil, :documents=>nil, :authority=>nil,
|
104
|
-
:lodgement_date=>nil, :officer=>nil, :people=>nil}).and_return(application)
|
105
|
-
|
106
|
-
ATDIS::Application.interpret(:application => {:info => {}, :reference => {}}).should == application
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe "#extended" do
|
111
|
-
it "should do no typecasting" do
|
112
|
-
a = ATDIS::Application.new(:extended => {:another_parameter => "with some value", :anything => "can go here"})
|
113
|
-
a.extended.should == {:another_parameter => "with some value", :anything => "can go here"}
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
describe "#location=" do
|
118
|
-
let(:a) { ATDIS::Application.new }
|
119
|
-
it "should type cast to a location" do
|
120
|
-
location = double
|
121
|
-
ATDIS::Location.should_receive(:interpret).with(:address => "123 Fourfivesix Street").and_return(location)
|
122
|
-
a.location = { :address => "123 Fourfivesix Street" }
|
123
|
-
a.location.should == location
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should not cast when it's already a location" do
|
127
|
-
l = ATDIS::Location.new
|
128
|
-
a.location = l
|
129
|
-
a.location.should == l
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe "#events" do
|
134
|
-
let(:a) { ATDIS::Application.new }
|
135
|
-
it "should type cast to several events" do
|
136
|
-
event1, event2 = double, double
|
137
|
-
ATDIS::Event.should_receive(:interpret).with(:id => "event1").and_return(event1)
|
138
|
-
ATDIS::Event.should_receive(:interpret).with(:id => "event2").and_return(event2)
|
139
|
-
a.events = [ { :id => "event1" }, { :id => "event2" } ]
|
140
|
-
a.events.should == [event1, event2]
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe "#documents" do
|
145
|
-
let(:a) { ATDIS::Application.new }
|
146
|
-
it "should type cast to several documents" do
|
147
|
-
document1, document2 = double, double
|
148
|
-
ATDIS::Document.should_receive(:interpret).with(:ref => "27B/6/a").and_return(document1)
|
149
|
-
ATDIS::Document.should_receive(:interpret).with(:ref => "27B/6/b").and_return(document2)
|
150
|
-
a.documents = [ { :ref => "27B/6/a" }, { :ref => "27B/6/b" } ]
|
151
|
-
a.documents.should == [document1, document2]
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
describe "#people" do
|
156
|
-
let(:a) { ATDIS::Application.new }
|
157
|
-
it "should type cast to several people" do
|
158
|
-
tuttle, buttle = double, double
|
159
|
-
ATDIS::Person.should_receive(:interpret).with(:name => "Tuttle").and_return(tuttle)
|
160
|
-
ATDIS::Person.should_receive(:interpret).with(:name => "Buttle").and_return(buttle)
|
161
|
-
a.people = [ { :name => "Tuttle" }, { :name => "Buttle" } ]
|
162
|
-
a.people.should == [tuttle, buttle]
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
describe "#last_modified_date=" do
|
167
|
-
let(:a) { ATDIS::Application.new }
|
168
|
-
it "should do no type casting when it's already a date" do
|
169
|
-
a.last_modified_date = DateTime.new(2013,1,1)
|
170
|
-
a.last_modified_date.should == DateTime.new(2013,1,1)
|
171
|
-
end
|
172
|
-
|
173
|
-
it "should cast a string to a date when it's a valid date" do
|
174
|
-
a.last_modified_date = "2013-01-01"
|
175
|
-
a.last_modified_date.should == DateTime.new(2013,1,1)
|
176
|
-
end
|
177
|
-
|
178
|
-
context "not a valid date" do
|
179
|
-
before :each do
|
180
|
-
a.last_modified_date = "2013/01/01"
|
181
|
-
end
|
182
|
-
it "should be nil" do
|
183
|
-
a.last_modified_date.should be_nil
|
184
|
-
end
|
185
|
-
it "should keep the original string" do
|
186
|
-
a.last_modified_date_before_type_cast.should == "2013/01/01"
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
describe "#lodgement_date=" do
|
192
|
-
let(:a) { ATDIS::Application.new }
|
193
|
-
it "should do no type casting when it's already a date" do
|
194
|
-
a.lodgement_date = DateTime.new(2013,1,1)
|
195
|
-
a.lodgement_date.should == DateTime.new(2013,1,1)
|
196
|
-
end
|
197
|
-
|
198
|
-
it "should cast a string to a date when it's a valid date" do
|
199
|
-
a.lodgement_date = "2013-01-01"
|
200
|
-
a.lodgement_date.should == DateTime.new(2013,1,1)
|
201
|
-
end
|
202
|
-
|
203
|
-
context "not a valid date" do
|
204
|
-
before :each do
|
205
|
-
a.lodgement_date = "2013/01/01"
|
206
|
-
end
|
207
|
-
it "should be nil" do
|
208
|
-
a.lodgement_date.should be_nil
|
209
|
-
end
|
210
|
-
it "should keep the original string" do
|
211
|
-
a.lodgement_date_before_type_cast.should == "2013/01/01"
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe "#more_info_url=" do
|
217
|
-
let(:a) { ATDIS::Application.new }
|
218
|
-
it "should do no type casting when it's already a URI" do
|
219
|
-
a.more_info_url = URI.parse("http://foo.com/bar")
|
220
|
-
a.more_info_url.should == URI.parse("http://foo.com/bar")
|
221
|
-
end
|
222
|
-
|
223
|
-
it "should cast a string to a URI when it's a valid url" do
|
224
|
-
a.more_info_url = "http://foo.com/bar"
|
225
|
-
a.more_info_url.should == URI.parse("http://foo.com/bar")
|
226
|
-
end
|
227
|
-
|
228
|
-
context "not a valid url" do
|
229
|
-
before :each do
|
230
|
-
a.more_info_url = "This is not a url"
|
231
|
-
end
|
232
|
-
it "should be nil" do
|
233
|
-
a.more_info_url.should be_nil
|
234
|
-
end
|
235
|
-
it "should keep the original string" do
|
236
|
-
a.more_info_url_before_type_cast.should == "This is not a url"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe "#description=" do
|
242
|
-
let(:a) { ATDIS::Application.new }
|
243
|
-
it "should do not type casting when it's already a String" do
|
244
|
-
a.description = "foo"
|
245
|
-
a.description.should == "foo"
|
246
|
-
end
|
247
|
-
context "not a string" do
|
248
|
-
before :each do
|
249
|
-
a.description = 123
|
250
|
-
end
|
251
|
-
it "should cast to a string when it's not a string" do
|
252
|
-
a.description.should == "123"
|
253
|
-
end
|
254
|
-
it "should keep the original value" do
|
255
|
-
a.description_before_type_cast.should == 123
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
# TODO This should really be a test on the Model base class
|
261
|
-
describe ".attributes" do
|
262
|
-
it do
|
263
|
-
a = ATDIS::Application.new(:dat_id => "DA2013-0381", :description => "New pool plus deck")
|
264
|
-
a.attributes.should == {"dat_id" => "DA2013-0381", "description" => "New pool plus deck"}
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
# TODO This should really be a test on the Model base class
|
269
|
-
describe "#attribute_names" do
|
270
|
-
it do
|
271
|
-
# These are also ordered in a way that corresponds to the specification. Makes for easy reading by humans.
|
272
|
-
ATDIS::Application.attribute_names.should == [
|
273
|
-
"dat_id",
|
274
|
-
"last_modified_date",
|
275
|
-
"description",
|
276
|
-
"authority",
|
277
|
-
"lodgement_date",
|
278
|
-
"determination_date",
|
279
|
-
"status",
|
280
|
-
"notification_start_date",
|
281
|
-
"notification_end_date",
|
282
|
-
"officer",
|
283
|
-
"estimated_cost",
|
284
|
-
"more_info_url",
|
285
|
-
"comments_url",
|
286
|
-
"location",
|
287
|
-
"events",
|
288
|
-
"documents",
|
289
|
-
"people",
|
290
|
-
"extended"
|
291
|
-
]
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
describe ".level_attribute_names" do
|
296
|
-
it "L1" do
|
297
|
-
ATDIS::Application.level_attribute_names(1).should == [
|
298
|
-
"dat_id",
|
299
|
-
"last_modified_date",
|
300
|
-
"description",
|
301
|
-
"authority",
|
302
|
-
"lodgement_date",
|
303
|
-
"determination_date",
|
304
|
-
"status",
|
305
|
-
"notification_start_date",
|
306
|
-
"notification_end_date",
|
307
|
-
"officer",
|
308
|
-
"estimated_cost",
|
309
|
-
"more_info_url",
|
310
|
-
"comments_url",
|
311
|
-
"location",
|
312
|
-
"events",
|
313
|
-
"documents"
|
314
|
-
]
|
315
|
-
end
|
316
|
-
|
317
|
-
it "L2" do
|
318
|
-
ATDIS::Application.level_attribute_names(2).should == ["people"]
|
319
|
-
end
|
320
|
-
|
321
|
-
it "L3" do
|
322
|
-
ATDIS::Application.level_attribute_names(3).should == ["extended"]
|
323
|
-
end
|
324
|
-
end
|
325
|
-
|
326
|
-
describe "validations" do
|
327
|
-
before :each do
|
328
|
-
l = double(:valid? => true)
|
329
|
-
ATDIS::Location.should_receive(:interpret).with(:address => "123 Fourfivesix Street Neutral Bay NSW 2089").and_return(l)
|
330
|
-
end
|
331
|
-
|
332
|
-
let(:a) { ATDIS::Application.new(
|
333
|
-
:dat_id => "DA2013-0381",
|
334
|
-
:last_modified_date => DateTime.new(2013,4,20,2,1,7),
|
335
|
-
:description => "New pool plus deck",
|
336
|
-
:authority => "Example Council Shire Council",
|
337
|
-
:lodgement_date => DateTime.new(2013,4,20,2,1,7),
|
338
|
-
:determination_date => DateTime.new(2013,6,20),
|
339
|
-
:status => "OPEN",
|
340
|
-
:more_info_url => URI.parse("http://foo.com/bar"),
|
341
|
-
:location => {:address => "123 Fourfivesix Street Neutral Bay NSW 2089"},
|
342
|
-
:events => [],
|
343
|
-
:documents => []
|
344
|
-
) }
|
345
|
-
|
346
|
-
it { a.should be_valid }
|
347
|
-
|
348
|
-
describe ".location" do
|
349
|
-
it "should not be valid if the location is not valid" do
|
350
|
-
l = double(:valid? => false)
|
351
|
-
ATDIS::Location.should_receive(:interpret).with(:foo => "some location data").and_return(l)
|
352
|
-
a.location = {:foo => "some location data"}
|
353
|
-
a.should_not be_valid
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
it ".dat_id" do
|
358
|
-
a.dat_id = nil
|
359
|
-
a.should_not be_valid
|
360
|
-
a.errors.messages.should == {:dat_id => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
361
|
-
end
|
362
|
-
|
363
|
-
describe ".last_modified_date" do
|
364
|
-
it do
|
365
|
-
a.last_modified_date = nil
|
366
|
-
a.should_not be_valid
|
367
|
-
a.errors.messages.should == {:last_modified_date => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
368
|
-
end
|
369
|
-
it do
|
370
|
-
a.last_modified_date = "18 January 2013"
|
371
|
-
a.should_not be_valid
|
372
|
-
a.errors.messages.should == {:last_modified_date => [ATDIS::ErrorMessage["is not a valid date", "4.3.8"]]}
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
describe ".description" do
|
377
|
-
it do
|
378
|
-
a.description = ""
|
379
|
-
a.should_not be_valid
|
380
|
-
a.errors.messages.should == {:description => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
describe ".authority" do
|
385
|
-
it do
|
386
|
-
a.authority = nil
|
387
|
-
a.should_not be_valid
|
388
|
-
a.errors.messages.should == {:authority => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
|
-
describe ".lodgement_date" do
|
393
|
-
it do
|
394
|
-
a.lodgement_date = nil
|
395
|
-
a.should_not be_valid
|
396
|
-
a.errors.messages.should == {:lodgement_date => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
397
|
-
end
|
398
|
-
it do
|
399
|
-
a.lodgement_date = "18 January 2013"
|
400
|
-
a.should_not be_valid
|
401
|
-
a.errors.messages.should == {:lodgement_date => [ATDIS::ErrorMessage["is not a valid date", "4.3.8"]]}
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
describe ".determination_date" do
|
406
|
-
it do
|
407
|
-
a.determination_date = nil
|
408
|
-
a.should_not be_valid
|
409
|
-
a.errors.messages.should == {:determination_date => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
410
|
-
end
|
411
|
-
it do
|
412
|
-
a.determination_date = "18 January 2013"
|
413
|
-
a.should_not be_valid
|
414
|
-
a.errors.messages.should == {:determination_date => [ATDIS::ErrorMessage["is not a valid date or none", "4.3.1"]]}
|
415
|
-
end
|
416
|
-
it "none should be allowed if the application is not yet determined" do
|
417
|
-
a.determination_date = "none"
|
418
|
-
a.determination_date.should be_nil
|
419
|
-
a.should be_valid
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
describe ".status" do
|
424
|
-
it do
|
425
|
-
a.status = nil
|
426
|
-
a.should_not be_valid
|
427
|
-
a.errors.messages.should == {:status => [ATDIS::ErrorMessage["can't be blank", "4.3.1"]]}
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
describe "notification_date" do
|
432
|
-
it "both valid start and end dates" do
|
433
|
-
a.notification_start_date = DateTime.new(2013,4,20,2,1,7)
|
434
|
-
a.notification_end_date = DateTime.new(2013,5,20,0,0,0)
|
435
|
-
a.should be_valid
|
436
|
-
end
|
437
|
-
|
438
|
-
it "invalid start date" do
|
439
|
-
a.notification_start_date = "18 January 2013"
|
440
|
-
a.notification_end_date = DateTime.new(2013,2,1,0,0,0)
|
441
|
-
a.should_not be_valid
|
442
|
-
a.errors.messages.should == {:notification_start_date => [ATDIS::ErrorMessage["is not a valid date or none", "4.3.1"]]}
|
443
|
-
end
|
444
|
-
|
445
|
-
it "invalid end date" do
|
446
|
-
a.notification_start_date = DateTime.new(2013,1,10,0,0,0)
|
447
|
-
a.notification_end_date = "18 January 2013"
|
448
|
-
a.should_not be_valid
|
449
|
-
a.errors.messages.should == {:notification_end_date => [ATDIS::ErrorMessage["is not a valid date or none", "4.3.1"]]}
|
450
|
-
end
|
451
|
-
|
452
|
-
it "only start date set" do
|
453
|
-
a.notification_start_date = DateTime.new(2013,4,20,2,1,7)
|
454
|
-
a.should_not be_valid
|
455
|
-
a.errors.messages.should == {:notification_end_date => [ATDIS::ErrorMessage["can not be blank if notification_start_date is set", "4.3.1"]]}
|
456
|
-
end
|
457
|
-
|
458
|
-
it "only end date set" do
|
459
|
-
a.notification_end_date = DateTime.new(2013,4,20,2,1,7)
|
460
|
-
a.should_not be_valid
|
461
|
-
a.errors.messages.should == {:notification_start_date => [ATDIS::ErrorMessage["can not be blank if notification_end_date is set", "4.3.1"]]}
|
462
|
-
end
|
463
|
-
|
464
|
-
it "end date is before start date" do
|
465
|
-
a.notification_start_date = DateTime.new(2013,5,20,0,0,0)
|
466
|
-
a.notification_end_date = DateTime.new(2013,4,20,2,1,7)
|
467
|
-
a.should_not be_valid
|
468
|
-
a.errors.messages.should == {:notification_end_date => [ATDIS::ErrorMessage["can not be earlier than notification_start_date", "4.3.1"]]}
|
469
|
-
end
|
470
|
-
|
471
|
-
it "both dates set to none" do
|
472
|
-
a.notification_start_date = "none"
|
473
|
-
a.notification_end_date = "none"
|
474
|
-
a.notification_start_date.should be_nil
|
475
|
-
a.notification_end_date.should be_nil
|
476
|
-
a.should be_valid
|
477
|
-
end
|
478
|
-
|
479
|
-
it "only start date set to none" do
|
480
|
-
a.notification_start_date = "none"
|
481
|
-
a.notification_end_date = DateTime.new(2013,2,1,0,0,0)
|
482
|
-
a.should_not be_valid
|
483
|
-
a.errors.messages.should == {:notification_start_date => [ATDIS::ErrorMessage["can't be none unless notification_end_date is none as well", "4.3.1"]]}
|
484
|
-
end
|
485
|
-
|
486
|
-
it "only end date set to none" do
|
487
|
-
a.notification_start_date = DateTime.new(2013,2,1,0,0,0)
|
488
|
-
a.notification_end_date = "none"
|
489
|
-
a.should_not be_valid
|
490
|
-
a.errors.messages.should == {:notification_end_date => [ATDIS::ErrorMessage["can't be none unless notification_start_date is none as well", "4.3.1"]]}
|
491
|
-
end
|
492
|
-
end
|
493
|
-
|
494
|
-
describe ".more_info_url" do
|
495
|
-
it do
|
496
|
-
a.more_info_url = nil
|
497
|
-
a.should_not be_valid
|
498
|
-
a.errors.messages.should == {:more_info_url => [ATDIS::ErrorMessage["can't be blank", "4.3.2"]]}
|
499
|
-
end
|
500
|
-
it do
|
501
|
-
a.more_info_url = "This is not a valid url"
|
502
|
-
a.should_not be_valid
|
503
|
-
a.errors.messages.should == {:more_info_url => [ATDIS::ErrorMessage["is not a valid URL", "4.3.2"]]}
|
504
|
-
end
|
505
|
-
it do
|
506
|
-
a.more_info_url = "foo.com"
|
507
|
-
a.should_not be_valid
|
508
|
-
a.errors.messages.should == {:more_info_url => [ATDIS::ErrorMessage["is not a valid URL", "4.3.2"]]}
|
509
|
-
end
|
510
|
-
it do
|
511
|
-
a.more_info_url = "httpss://foo.com"
|
512
|
-
a.should_not be_valid
|
513
|
-
a.errors.messages.should == {:more_info_url => [ATDIS::ErrorMessage["is not a valid URL", "4.3.2"]]}
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
describe "events" do
|
518
|
-
it "has to be an array" do
|
519
|
-
ATDIS::Event.should_receive(:interpret).with(:foo => "bar").and_return(double(:valid? => true))
|
520
|
-
a.events = {:foo => "bar"}
|
521
|
-
#a.events.should be_nil
|
522
|
-
a.should_not be_valid
|
523
|
-
a.errors.messages.should == {:events => [ATDIS::ErrorMessage["should be an array", "4.3.4"]]}
|
524
|
-
end
|
525
|
-
|
526
|
-
it "can be an empty array" do
|
527
|
-
a.events = []
|
528
|
-
a.events.should == []
|
529
|
-
a.should be_valid
|
530
|
-
end
|
531
|
-
|
532
|
-
it "can not be empty" do
|
533
|
-
a.events = nil
|
534
|
-
a.should_not be_valid
|
535
|
-
a.errors.messages.should == {:events => [ATDIS::ErrorMessage["can't be blank", "4.3.4"]]}
|
536
|
-
end
|
537
|
-
end
|
538
|
-
end
|
539
|
-
end
|