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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +46 -0
  3. data/.ruby-version +1 -1
  4. data/Gemfile +9 -7
  5. data/Guardfile +4 -3
  6. data/Rakefile +4 -2
  7. data/atdis.gemspec +10 -5
  8. data/lib/atdis.rb +2 -0
  9. data/lib/atdis/feed.rb +31 -24
  10. data/lib/atdis/model.rb +101 -99
  11. data/lib/atdis/models/address.rb +10 -4
  12. data/lib/atdis/models/application.rb +12 -9
  13. data/lib/atdis/models/authority.rb +11 -6
  14. data/lib/atdis/models/document.rb +8 -6
  15. data/lib/atdis/models/event.rb +10 -8
  16. data/lib/atdis/models/info.rb +73 -49
  17. data/lib/atdis/models/land_title_ref.rb +15 -7
  18. data/lib/atdis/models/location.rb +9 -7
  19. data/lib/atdis/models/page.rb +34 -19
  20. data/lib/atdis/models/pagination.rb +91 -32
  21. data/lib/atdis/models/person.rb +7 -5
  22. data/lib/atdis/models/reference.rb +7 -5
  23. data/lib/atdis/models/response.rb +5 -3
  24. data/lib/atdis/models/torrens_title.rb +9 -7
  25. data/lib/atdis/separated_url.rb +17 -15
  26. data/lib/atdis/validators.rb +46 -39
  27. data/lib/atdis/version.rb +3 -1
  28. data/spec/atdis/feed_spec.rb +126 -34
  29. data/spec/atdis/model_spec.rb +124 -51
  30. data/spec/atdis/models/address_spec.rb +18 -9
  31. data/spec/atdis/models/application_spec.rb +222 -155
  32. data/spec/atdis/models/authority_spec.rb +45 -15
  33. data/spec/atdis/models/document_spec.rb +10 -4
  34. data/spec/atdis/models/event_spec.rb +23 -11
  35. data/spec/atdis/models/info_spec.rb +191 -116
  36. data/spec/atdis/models/land_title_ref_spec.rb +32 -16
  37. data/spec/atdis/models/location_spec.rb +75 -60
  38. data/spec/atdis/models/page_spec.rb +241 -135
  39. data/spec/atdis/models/pagination_spec.rb +177 -77
  40. data/spec/atdis/models/person_spec.rb +8 -4
  41. data/spec/atdis/models/reference_spec.rb +29 -16
  42. data/spec/atdis/models/response_spec.rb +2 -1
  43. data/spec/atdis/models/torrens_title_spec.rb +24 -18
  44. data/spec/atdis/separated_url_spec.rb +14 -15
  45. data/spec/spec_helper.rb +14 -10
  46. metadata +56 -27
@@ -1,17 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ATDIS
2
4
  module Models
3
5
  class Address < Model
4
- set_field_mappings ({
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, presence_before_type_cast: {spec_section: "4.3.3"}
14
+ validates :street, :suburb, :postcode, :state,
15
+ presence_before_type_cast: { spec_section: "4.3.3" }
13
16
 
14
- validates :postcode, format: { with: /\A[0-9]{4}\z/, message: ATDIS::ErrorMessage.new("is not a valid postcode", "4.3.3")}
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
- set_field_mappings ({
12
- info: Info,
13
+ field_mappings(
14
+ info: Info,
13
15
  reference: Reference,
14
16
  locations: Location,
15
- events: Event,
17
+ events: Event,
16
18
  documents: Document,
17
- people: Person,
18
- extended: Object,
19
- })
19
+ people: Person,
20
+ extended: Object
21
+ )
20
22
 
21
23
  # Mandatory attributes
22
- validates :info, :reference, :locations, :events, :documents, presence_before_type_cast: {spec_section: "4.3"}
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
- set_field_mappings ({
5
- ref: URI,
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: { with: /atdis\/1.0\z/, message: ATDIS::ErrorMessage.new("is not a valid Unique Authority Identifier", "4.3.1")}
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
- set_field_mappings ({
5
- ref: String,
6
- title: String,
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
@@ -1,18 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ATDIS
2
4
  module Models
3
5
  class Event < Model
4
- set_field_mappings ({
5
- id: String,
6
- timestamp: DateTime,
6
+ field_mappings(
7
+ id: String,
8
+ timestamp: DateTime,
7
9
  description: String,
8
- event_type: String,
9
- status: String
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
@@ -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
- set_field_mappings ({
7
- dat_id: String,
8
- development_type: String,
9
- application_type: String,
10
- last_modified_date: DateTime,
11
- description: String,
12
- authority: Authority,
13
- lodgement_date: DateTime,
14
- determination_date: DateTime,
15
- determination_type: String,
16
- status: String,
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: DateTime,
19
- officer: String,
20
- estimated_cost: String,
21
- related_apps: URI
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
- :authority, :lodgement_date, :status,
29
- presence_before_type_cast: {spec_section: "4.3.1"}
30
+ :authority, :lodgement_date, :status,
31
+ presence_before_type_cast: { spec_section: "4.3.1" }
30
32
  # Other validations
31
- validates :application_type, inclusion: { in: [
32
- "DA", "CDC", "S96", "Review", "Appeal", "Other"
33
- ],
34
- message: ATDIS::ErrorMessage.new("does not have one of the allowed types", "4.3.1")}
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
- :notification_start_date, :notification_end_date,
37
- date_time: {spec_section: "4.3.1"}
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, inclusion: { in: [
40
- "Pending", "Refused by Council", "Refused under delegation", "Withdrawn",
41
- "Approved by Council", "Approved under delegation", "Rejected"
42
- ],
43
- message: ATDIS::ErrorMessage.new("does not have one of the allowed types", "4.3.1")
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
- if dat_id && !Info.url_encoded?(dat_id)
58
- errors.add(:dat_id, ErrorMessage.new("should be url encoded", "4.3.1"))
59
- end
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?(s)
73
+ def self.url_encoded?(str)
63
74
  url_encoded = true
64
- s.each_char do |c|
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
- if related_apps.respond_to?(:all?) && !related_apps.all? {|url| url.to_s =~ /atdis\/1.0\/[^\/]+\.json/}
75
- errors.add(:related_apps, ErrorMessage.new("contains url(s) not in the expected format", "4.3.1"))
76
- end
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(:notification_end_date, ErrorMessage["can not be blank if notification_start_date is set", "4.3.1"])
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(:notification_start_date, ErrorMessage["can not be blank if notification_end_date is set", "4.3.1"])
85
- end
86
- if notification_start_date && notification_end_date && notification_start_date > notification_end_date
87
- errors.add(:notification_end_date, ErrorMessage["can not be earlier than notification_start_date", "4.3.1"])
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
- set_field_mappings ({
8
+ field_mappings(
7
9
  torrens: TorrensTitle,
8
- other: Hash
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(:torrens, ATDIS::ErrorMessage.new("or other needs be present", "4.3.3"))
19
- end
20
- if torrens && other
21
- errors.add(:torrens, ATDIS::ErrorMessage.new("and other can't both be present", "4.3.3"))
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
- require 'atdis/models/address'
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
- set_field_mappings ({
9
- address: Address,
10
+ field_mappings(
11
+ address: Address,
10
12
  land_title_ref: LandTitleRef,
11
- geometry: RGeo::GeoJSON
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
@@ -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
- set_field_mappings ({
8
- response: Response,
9
- count: Fixnum,
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 which should be helpful
16
- validates :response, array: {spec_section: "6.4"}
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
- if pagination && count.nil?
26
- errors.add(:count, ErrorMessage["should be present if pagination is being used", "6.4"])
27
- end
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
- if response.respond_to?(:count)
33
- errors.add(:count, ErrorMessage["is not the same as the number of applications returned", "6.4"]) if count != response.count
34
- end
35
- if pagination.respond_to?(:per_page) && pagination.per_page
36
- errors.add(:count, ErrorMessage["should not be larger than the number of results per page", "6.4"]) if count > pagination.per_page
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
- ATDIS::SeparatedURL.merge(url, page: pagination.previous) if pagination && pagination.previous
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
- ATDIS::SeparatedURL.merge(url, page: pagination.next) if pagination && pagination.next
62
+
63
+ ATDIS::SeparatedURL.merge(url, page: pagination.next) if pagination&.next
49
64
  end
50
65
 
51
66
  def previous_page