atdis 0.2 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|