atdis 0.3.13 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +46 -0
- data/.ruby-version +1 -1
- data/Gemfile +9 -7
- data/Guardfile +4 -3
- data/Rakefile +4 -2
- data/atdis.gemspec +10 -5
- data/lib/atdis.rb +2 -0
- data/lib/atdis/feed.rb +31 -24
- data/lib/atdis/model.rb +101 -99
- data/lib/atdis/models/address.rb +10 -4
- data/lib/atdis/models/application.rb +12 -9
- data/lib/atdis/models/authority.rb +11 -6
- data/lib/atdis/models/document.rb +8 -6
- data/lib/atdis/models/event.rb +10 -8
- data/lib/atdis/models/info.rb +73 -49
- data/lib/atdis/models/land_title_ref.rb +15 -7
- data/lib/atdis/models/location.rb +9 -7
- data/lib/atdis/models/page.rb +34 -19
- data/lib/atdis/models/pagination.rb +91 -32
- data/lib/atdis/models/person.rb +7 -5
- data/lib/atdis/models/reference.rb +7 -5
- data/lib/atdis/models/response.rb +5 -3
- data/lib/atdis/models/torrens_title.rb +9 -7
- data/lib/atdis/separated_url.rb +17 -15
- data/lib/atdis/validators.rb +46 -39
- data/lib/atdis/version.rb +3 -1
- data/spec/atdis/feed_spec.rb +126 -34
- data/spec/atdis/model_spec.rb +124 -51
- data/spec/atdis/models/address_spec.rb +18 -9
- data/spec/atdis/models/application_spec.rb +222 -155
- data/spec/atdis/models/authority_spec.rb +45 -15
- data/spec/atdis/models/document_spec.rb +10 -4
- data/spec/atdis/models/event_spec.rb +23 -11
- data/spec/atdis/models/info_spec.rb +191 -116
- data/spec/atdis/models/land_title_ref_spec.rb +32 -16
- data/spec/atdis/models/location_spec.rb +75 -60
- data/spec/atdis/models/page_spec.rb +241 -135
- data/spec/atdis/models/pagination_spec.rb +177 -77
- data/spec/atdis/models/person_spec.rb +8 -4
- data/spec/atdis/models/reference_spec.rb +29 -16
- data/spec/atdis/models/response_spec.rb +2 -1
- data/spec/atdis/models/torrens_title_spec.rb +24 -18
- data/spec/atdis/separated_url_spec.rb +14 -15
- data/spec/spec_helper.rb +14 -10
- metadata +56 -27
data/lib/atdis/models/address.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Address < Model
|
4
|
-
|
6
|
+
field_mappings(
|
5
7
|
street: String,
|
6
8
|
suburb: String,
|
7
9
|
postcode: String,
|
8
10
|
state: String
|
9
|
-
|
11
|
+
)
|
10
12
|
|
11
13
|
# Mandatory parameters
|
12
|
-
validates :street, :suburb, :postcode, :state,
|
14
|
+
validates :street, :suburb, :postcode, :state,
|
15
|
+
presence_before_type_cast: { spec_section: "4.3.3" }
|
13
16
|
|
14
|
-
validates :postcode, format: {
|
17
|
+
validates :postcode, format: {
|
18
|
+
with: /\A[0-9]{4}\z/,
|
19
|
+
message: ATDIS::ErrorMessage.new("is not a valid postcode", "4.3.3")
|
20
|
+
}
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "atdis/models/info"
|
2
4
|
require "atdis/models/reference"
|
3
5
|
require "atdis/models/location"
|
@@ -8,21 +10,22 @@ require "atdis/models/person"
|
|
8
10
|
module ATDIS
|
9
11
|
module Models
|
10
12
|
class Application < Model
|
11
|
-
|
12
|
-
info:
|
13
|
+
field_mappings(
|
14
|
+
info: Info,
|
13
15
|
reference: Reference,
|
14
16
|
locations: Location,
|
15
|
-
events:
|
17
|
+
events: Event,
|
16
18
|
documents: Document,
|
17
|
-
people:
|
18
|
-
extended:
|
19
|
-
|
19
|
+
people: Person,
|
20
|
+
extended: Object
|
21
|
+
)
|
20
22
|
|
21
23
|
# Mandatory attributes
|
22
|
-
validates :info, :reference, :locations, :events, :documents,
|
24
|
+
validates :info, :reference, :locations, :events, :documents,
|
25
|
+
presence_before_type_cast: { spec_section: "4.3" }
|
23
26
|
|
24
|
-
validates :people, array: {spec_section: "4.3"}
|
25
|
-
validates :locations, :events, filled_array: {spec_section: "4.3"}
|
27
|
+
validates :people, array: { spec_section: "4.3" }
|
28
|
+
validates :locations, :events, filled_array: { spec_section: "4.3" }
|
26
29
|
|
27
30
|
# This model is only valid if the children are valid
|
28
31
|
validates :info, :reference, :locations, :events, :documents, :people, valid: true
|
@@ -1,19 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Authority < Model
|
4
|
-
|
5
|
-
ref:
|
6
|
+
field_mappings(
|
7
|
+
ref: URI,
|
6
8
|
name: String
|
7
|
-
|
9
|
+
)
|
8
10
|
|
9
11
|
# ref is a "Unique Authority Identifier" and should have the form http://www.council.nsw.gov.au/atdis/1.0
|
10
12
|
# It should also be consistent for each council.
|
11
13
|
|
12
14
|
# Mandatory attributes
|
13
|
-
validates :ref, :name, presence_before_type_cast: {spec_section: "4.3.1"}
|
15
|
+
validates :ref, :name, presence_before_type_cast: { spec_section: "4.3.1" }
|
14
16
|
|
15
|
-
validates :ref, http_url: {spec_section: "4.3.1"}
|
16
|
-
validates :ref, format: {
|
17
|
+
validates :ref, http_url: { spec_section: "4.3.1" }
|
18
|
+
validates :ref, format: {
|
19
|
+
with: %r{atdis\/1.0\z},
|
20
|
+
message: ATDIS::ErrorMessage.new("is not a valid Unique Authority Identifier", "4.3.1")
|
21
|
+
}
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Document < Model
|
4
|
-
|
5
|
-
ref:
|
6
|
-
title:
|
6
|
+
field_mappings(
|
7
|
+
ref: String,
|
8
|
+
title: String,
|
7
9
|
document_url: URI
|
8
|
-
|
10
|
+
)
|
9
11
|
|
10
12
|
# Mandatory parameters
|
11
|
-
validates :ref, :title, :document_url, presence_before_type_cast: {spec_section: "4.3.5"}
|
13
|
+
validates :ref, :title, :document_url, presence_before_type_cast: { spec_section: "4.3.5" }
|
12
14
|
# Other validations
|
13
|
-
validates :document_url, http_url: {spec_section: "4.3.5"}
|
15
|
+
validates :document_url, http_url: { spec_section: "4.3.5" }
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
data/lib/atdis/models/event.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Event < Model
|
4
|
-
|
5
|
-
id:
|
6
|
-
timestamp:
|
6
|
+
field_mappings(
|
7
|
+
id: String,
|
8
|
+
timestamp: DateTime,
|
7
9
|
description: String,
|
8
|
-
event_type:
|
9
|
-
status:
|
10
|
-
|
10
|
+
event_type: String,
|
11
|
+
status: String
|
12
|
+
)
|
11
13
|
|
12
14
|
# Mandatory parameters
|
13
|
-
validates :id, :timestamp, :description, presence_before_type_cast: {spec_section: "4.3.4"}
|
15
|
+
validates :id, :timestamp, :description, presence_before_type_cast: { spec_section: "4.3.4" }
|
14
16
|
|
15
|
-
validates :timestamp, date_time: {spec_section: "4.3.8"}
|
17
|
+
validates :timestamp, date_time: { spec_section: "4.3.8" }
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
data/lib/atdis/models/info.rb
CHANGED
@@ -1,91 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "atdis/models/authority"
|
2
4
|
|
3
5
|
module ATDIS
|
4
6
|
module Models
|
5
7
|
class Info < Model
|
6
|
-
|
7
|
-
dat_id:
|
8
|
-
development_type:
|
9
|
-
application_type:
|
10
|
-
last_modified_date:
|
11
|
-
description:
|
12
|
-
authority:
|
13
|
-
lodgement_date:
|
14
|
-
determination_date:
|
15
|
-
determination_type:
|
16
|
-
status:
|
8
|
+
field_mappings(
|
9
|
+
dat_id: String,
|
10
|
+
development_type: String,
|
11
|
+
application_type: String,
|
12
|
+
last_modified_date: DateTime,
|
13
|
+
description: String,
|
14
|
+
authority: Authority,
|
15
|
+
lodgement_date: DateTime,
|
16
|
+
determination_date: DateTime,
|
17
|
+
determination_type: String,
|
18
|
+
status: String,
|
17
19
|
notification_start_date: DateTime,
|
18
|
-
notification_end_date:
|
19
|
-
officer:
|
20
|
-
estimated_cost:
|
21
|
-
related_apps:
|
22
|
-
|
20
|
+
notification_end_date: DateTime,
|
21
|
+
officer: String,
|
22
|
+
estimated_cost: String,
|
23
|
+
related_apps: URI
|
24
|
+
)
|
23
25
|
|
24
26
|
# Mandatory parameters
|
25
27
|
# determination_date is not in this list because even though it is mandatory
|
26
28
|
# it can be null if there is no value
|
27
29
|
validates :dat_id, :development_type, :last_modified_date, :description,
|
28
|
-
|
29
|
-
|
30
|
+
:authority, :lodgement_date, :status,
|
31
|
+
presence_before_type_cast: { spec_section: "4.3.1" }
|
30
32
|
# Other validations
|
31
|
-
validates :application_type,
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
validates :application_type,
|
34
|
+
inclusion: {
|
35
|
+
in: %w[DA CDC S96 Review Appeal Other],
|
36
|
+
message: ATDIS::ErrorMessage.new(
|
37
|
+
"does not have one of the allowed types",
|
38
|
+
"4.3.1"
|
39
|
+
)
|
40
|
+
}
|
35
41
|
validates :last_modified_date, :lodgement_date, :determination_date,
|
36
|
-
|
37
|
-
|
42
|
+
:notification_start_date, :notification_end_date,
|
43
|
+
date_time: { spec_section: "4.3.1" }
|
38
44
|
# We don't need to separately validate presence because this covers it
|
39
|
-
validates :determination_type,
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
+
validates :determination_type,
|
46
|
+
inclusion: {
|
47
|
+
in: [
|
48
|
+
"Pending", "Refused by Council", "Refused under delegation", "Withdrawn",
|
49
|
+
"Approved by Council", "Approved under delegation", "Rejected"
|
50
|
+
],
|
51
|
+
message: ATDIS::ErrorMessage.new(
|
52
|
+
"does not have one of the allowed types",
|
53
|
+
"4.3.1"
|
54
|
+
)
|
55
|
+
}
|
45
56
|
validate :notification_dates_consistent!
|
46
|
-
validates :related_apps, array: {spec_section: "4.3.1"}
|
47
|
-
validates :related_apps, array_http_url: {spec_section: "4.3.1"}
|
57
|
+
validates :related_apps, array: { spec_section: "4.3.1" }
|
58
|
+
validates :related_apps, array_http_url: { spec_section: "4.3.1" }
|
48
59
|
validate :related_apps_url_format
|
49
60
|
validate :dat_id_is_url_encoded!
|
50
61
|
|
51
62
|
# This model is only valid if the children are valid
|
52
63
|
validates :authority, valid: true
|
53
64
|
|
54
|
-
# TODO Validate contents of estimated_cost
|
65
|
+
# TODO: Validate contents of estimated_cost
|
55
66
|
|
56
67
|
def dat_id_is_url_encoded!
|
57
|
-
|
58
|
-
|
59
|
-
|
68
|
+
return unless dat_id && !Info.url_encoded?(dat_id)
|
69
|
+
|
70
|
+
errors.add(:dat_id, ErrorMessage.new("should be url encoded", "4.3.1"))
|
60
71
|
end
|
61
72
|
|
62
|
-
def self.url_encoded?(
|
73
|
+
def self.url_encoded?(str)
|
63
74
|
url_encoded = true
|
64
|
-
|
75
|
+
str.each_char do |c|
|
65
76
|
# These characters are the valid ones in a url encoded string
|
66
|
-
unless c =~ /[a-zA-Z0-9\-_.~%+]/
|
67
|
-
url_encoded = false
|
68
|
-
end
|
77
|
+
url_encoded = false unless c =~ /[a-zA-Z0-9\-_.~%+]/
|
69
78
|
end
|
70
79
|
url_encoded
|
71
80
|
end
|
72
81
|
|
73
82
|
def related_apps_url_format
|
74
|
-
|
75
|
-
|
76
|
-
|
83
|
+
return unless related_apps.respond_to?(:all?) &&
|
84
|
+
!related_apps.all? { |url| url.to_s =~ %r{atdis\/1.0\/[^\/]+\.json} }
|
85
|
+
|
86
|
+
errors.add(
|
87
|
+
:related_apps,
|
88
|
+
ErrorMessage.new("contains url(s) not in the expected format", "4.3.1")
|
89
|
+
)
|
77
90
|
end
|
78
91
|
|
79
92
|
def notification_dates_consistent!
|
80
93
|
if notification_start_date_before_type_cast && notification_end_date_before_type_cast.blank?
|
81
|
-
errors.add(
|
94
|
+
errors.add(
|
95
|
+
:notification_end_date,
|
96
|
+
ErrorMessage["can not be blank if notification_start_date is set", "4.3.1"]
|
97
|
+
)
|
82
98
|
end
|
83
99
|
if notification_start_date_before_type_cast.blank? && notification_end_date_before_type_cast
|
84
|
-
errors.add(
|
85
|
-
|
86
|
-
|
87
|
-
|
100
|
+
errors.add(
|
101
|
+
:notification_start_date,
|
102
|
+
ErrorMessage["can not be blank if notification_end_date is set", "4.3.1"]
|
103
|
+
)
|
88
104
|
end
|
105
|
+
return unless notification_start_date &&
|
106
|
+
notification_end_date &&
|
107
|
+
notification_start_date > notification_end_date
|
108
|
+
|
109
|
+
errors.add(
|
110
|
+
:notification_end_date,
|
111
|
+
ErrorMessage["can not be earlier than notification_start_date", "4.3.1"]
|
112
|
+
)
|
89
113
|
end
|
90
114
|
end
|
91
115
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "atdis/models/torrens_title"
|
2
4
|
|
3
5
|
module ATDIS
|
4
6
|
module Models
|
5
7
|
class LandTitleRef < Model
|
6
|
-
|
8
|
+
field_mappings(
|
7
9
|
torrens: TorrensTitle,
|
8
|
-
other:
|
9
|
-
|
10
|
+
other: Hash
|
11
|
+
)
|
10
12
|
|
11
13
|
# This model is only valid if the children are valid
|
12
14
|
validates :torrens, valid: true
|
@@ -15,11 +17,17 @@ module ATDIS
|
|
15
17
|
|
16
18
|
def check_title_presence
|
17
19
|
if torrens.nil? && other.nil?
|
18
|
-
errors.add(
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
errors.add(
|
21
|
+
:torrens,
|
22
|
+
ATDIS::ErrorMessage.new("or other needs be present", "4.3.3")
|
23
|
+
)
|
22
24
|
end
|
25
|
+
return unless torrens && other
|
26
|
+
|
27
|
+
errors.add(
|
28
|
+
:torrens,
|
29
|
+
ATDIS::ErrorMessage.new("and other can't both be present", "4.3.3")
|
30
|
+
)
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
@@ -1,20 +1,22 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "atdis/models/address"
|
2
4
|
require "atdis/models/land_title_ref"
|
3
5
|
require "rgeo/geo_json"
|
4
6
|
|
5
7
|
module ATDIS
|
6
8
|
module Models
|
7
9
|
class Location < Model
|
8
|
-
|
9
|
-
address:
|
10
|
+
field_mappings(
|
11
|
+
address: Address,
|
10
12
|
land_title_ref: LandTitleRef,
|
11
|
-
geometry:
|
12
|
-
|
13
|
+
geometry: RGeo::GeoJSON
|
14
|
+
)
|
13
15
|
|
14
16
|
# Mandatory parameters
|
15
|
-
validates :address, :land_title_ref, presence_before_type_cast: {spec_section: "4.3.3"}
|
17
|
+
validates :address, :land_title_ref, presence_before_type_cast: { spec_section: "4.3.3" }
|
16
18
|
|
17
|
-
validates :geometry, geo_json: {spec_section: "4.3.3"}
|
19
|
+
validates :geometry, geo_json: { spec_section: "4.3.3" }
|
18
20
|
|
19
21
|
# This model is only valid if the children are valid
|
20
22
|
validates :address, :land_title_ref, valid: true
|
data/lib/atdis/models/page.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "atdis/models/response"
|
2
4
|
require "atdis/models/pagination"
|
3
5
|
|
4
6
|
module ATDIS
|
5
7
|
module Models
|
6
8
|
class Page < Model
|
7
|
-
|
8
|
-
response:
|
9
|
-
count:
|
10
|
-
pagination: Pagination
|
11
|
-
|
9
|
+
field_mappings(
|
10
|
+
response: Response,
|
11
|
+
count: Integer,
|
12
|
+
pagination: Pagination
|
13
|
+
)
|
12
14
|
|
13
15
|
# Mandatory parameters
|
14
|
-
validates :response, presence_before_type_cast: {spec_section: "4.3"}
|
15
|
-
# section 6.5 is not explicitly about this but it does contain an example
|
16
|
-
|
16
|
+
validates :response, presence_before_type_cast: { spec_section: "4.3" }
|
17
|
+
# section 6.5 is not explicitly about this but it does contain an example
|
18
|
+
# which should be helpful
|
19
|
+
validates :response, array: { spec_section: "6.4" }
|
17
20
|
validate :count_is_consistent, :all_pagination_is_present
|
18
21
|
|
19
22
|
# This model is only valid if the children are valid
|
@@ -22,30 +25,42 @@ module ATDIS
|
|
22
25
|
|
23
26
|
# If some of the pagination fields are present all of the required ones should be present
|
24
27
|
def all_pagination_is_present
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
return unless pagination && count.nil?
|
29
|
+
|
30
|
+
errors.add(:count, ErrorMessage["should be present if pagination is being used", "6.4"])
|
28
31
|
end
|
29
32
|
|
30
33
|
def count_is_consistent
|
31
|
-
if count
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
return if count.nil?
|
35
|
+
|
36
|
+
if response.respond_to?(:count)
|
37
|
+
if count != response.count
|
38
|
+
errors.add(
|
39
|
+
:count,
|
40
|
+
ErrorMessage["is not the same as the number of applications returned", "6.4"]
|
41
|
+
)
|
37
42
|
end
|
38
43
|
end
|
44
|
+
return unless pagination.respond_to?(:per_page) && pagination.per_page
|
45
|
+
|
46
|
+
return unless count > pagination.per_page
|
47
|
+
|
48
|
+
errors.add(
|
49
|
+
:count,
|
50
|
+
ErrorMessage["should not be larger than the number of results per page", "6.4"]
|
51
|
+
)
|
39
52
|
end
|
40
53
|
|
41
54
|
def previous_url
|
42
55
|
raise "Can't use previous_url when loaded with read_json" if url.nil?
|
43
|
-
|
56
|
+
|
57
|
+
ATDIS::SeparatedURL.merge(url, page: pagination.previous) if pagination&.previous
|
44
58
|
end
|
45
59
|
|
46
60
|
def next_url
|
47
61
|
raise "Can't use next_url when loaded with read_json" if url.nil?
|
48
|
-
|
62
|
+
|
63
|
+
ATDIS::SeparatedURL.merge(url, page: pagination.next) if pagination&.next
|
49
64
|
end
|
50
65
|
|
51
66
|
def previous_page
|