atdis 0.3.13 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,67 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Pagination < Model
|
4
|
-
|
5
|
-
previous:
|
6
|
-
next:
|
7
|
-
current:
|
8
|
-
per_page:
|
9
|
-
count:
|
10
|
-
pages:
|
11
|
-
|
6
|
+
field_mappings(
|
7
|
+
previous: Integer,
|
8
|
+
next: Integer,
|
9
|
+
current: Integer,
|
10
|
+
per_page: Integer,
|
11
|
+
count: Integer,
|
12
|
+
pages: Integer
|
13
|
+
)
|
12
14
|
|
13
15
|
validate :all_pagination_is_present, :previous_is_consistent,
|
14
|
-
|
15
|
-
|
16
|
+
:next_is_consistent, :current_is_consistent,
|
17
|
+
:count_is_consistent
|
16
18
|
|
17
19
|
# If some of the pagination fields are present all of the required ones should be present
|
18
20
|
def all_pagination_is_present
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
if current.nil?
|
22
|
+
errors.add(
|
23
|
+
:current,
|
24
|
+
ErrorMessage["should be present if pagination is being used", "6.4"]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
if per_page.nil?
|
28
|
+
errors.add(
|
29
|
+
:per_page,
|
30
|
+
ErrorMessage["should be present if pagination is being used", "6.4"]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
if count.nil?
|
34
|
+
errors.add(
|
35
|
+
:count,
|
36
|
+
ErrorMessage["should be present if pagination is being used", "6.4"]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
return unless pages.nil?
|
40
|
+
|
41
|
+
errors.add(
|
42
|
+
:pages,
|
43
|
+
ErrorMessage["should be present if pagination is being used", "6.4"]
|
44
|
+
)
|
23
45
|
end
|
24
46
|
|
25
47
|
def previous_is_consistent
|
26
48
|
if previous && current && previous != current - 1
|
27
|
-
errors.add(
|
49
|
+
errors.add(
|
50
|
+
:previous,
|
51
|
+
ErrorMessage["should be one less than current page number or null if first page", "6.4"]
|
52
|
+
)
|
28
53
|
end
|
29
54
|
if previous && current && current == 1
|
30
|
-
errors.add(
|
31
|
-
|
32
|
-
|
33
|
-
|
55
|
+
errors.add(
|
56
|
+
:previous,
|
57
|
+
ErrorMessage["should be null if on the first page", "6.4"]
|
58
|
+
)
|
34
59
|
end
|
60
|
+
return unless previous.nil? && current && current > 1
|
61
|
+
|
62
|
+
errors.add(
|
63
|
+
:previous,
|
64
|
+
ErrorMessage["can't be null if not on the first page", "6.4"]
|
65
|
+
)
|
35
66
|
end
|
36
67
|
|
37
68
|
def next_is_consistent
|
38
69
|
if self.next && current && self.next != current + 1
|
39
|
-
errors.add(
|
70
|
+
errors.add(
|
71
|
+
:next,
|
72
|
+
ErrorMessage[
|
73
|
+
"should be one greater than current page number or null if last page",
|
74
|
+
"6.4"
|
75
|
+
]
|
76
|
+
)
|
40
77
|
end
|
41
78
|
if self.next.nil? && current != pages
|
42
|
-
errors.add(
|
43
|
-
|
44
|
-
|
45
|
-
|
79
|
+
errors.add(
|
80
|
+
:next,
|
81
|
+
ErrorMessage["can't be null if not on the last page", "6.4"]
|
82
|
+
)
|
46
83
|
end
|
84
|
+
return unless self.next && current == pages
|
85
|
+
|
86
|
+
errors.add(
|
87
|
+
:next,
|
88
|
+
ErrorMessage["should be null if on the last page", "6.4"]
|
89
|
+
)
|
47
90
|
end
|
48
91
|
|
49
92
|
def current_is_consistent
|
50
93
|
if current && pages && current > pages
|
51
|
-
errors.add(
|
52
|
-
|
53
|
-
|
54
|
-
|
94
|
+
errors.add(
|
95
|
+
:current,
|
96
|
+
ErrorMessage["is larger than the number of pages", "6.4"]
|
97
|
+
)
|
55
98
|
end
|
99
|
+
return unless current && current < 1
|
100
|
+
|
101
|
+
errors.add(
|
102
|
+
:current,
|
103
|
+
ErrorMessage["can not be less than 1", "6.4"]
|
104
|
+
)
|
56
105
|
end
|
57
106
|
|
58
107
|
def count_is_consistent
|
59
108
|
if pages && per_page && count && count > pages * per_page
|
60
|
-
errors.add(
|
61
|
-
|
62
|
-
|
63
|
-
|
109
|
+
errors.add(
|
110
|
+
:count,
|
111
|
+
ErrorMessage["is larger than can be retrieved through paging", "6.4"]
|
112
|
+
)
|
64
113
|
end
|
114
|
+
return unless pages &&
|
115
|
+
per_page &&
|
116
|
+
count &&
|
117
|
+
count.positive? &&
|
118
|
+
count <= (pages - 1) * per_page
|
119
|
+
|
120
|
+
errors.add(
|
121
|
+
:count,
|
122
|
+
ErrorMessage["could fit into a smaller number of pages", "6.4"]
|
123
|
+
)
|
65
124
|
end
|
66
125
|
end
|
67
126
|
end
|
data/lib/atdis/models/person.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Person < Model
|
4
|
-
|
5
|
-
name:
|
6
|
-
role:
|
6
|
+
field_mappings(
|
7
|
+
name: String,
|
8
|
+
role: String,
|
7
9
|
contact: String
|
8
|
-
|
10
|
+
)
|
9
11
|
|
10
12
|
# Mandatory parameters
|
11
|
-
validates :name, :role, presence_before_type_cast: {spec_section: "4.3.6"}
|
13
|
+
validates :name, :role, presence_before_type_cast: { spec_section: "4.3.6" }
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class Reference < Model
|
4
|
-
|
6
|
+
field_mappings(
|
5
7
|
more_info_url: URI,
|
6
|
-
comments_url:
|
7
|
-
|
8
|
+
comments_url: URI
|
9
|
+
)
|
8
10
|
|
9
|
-
validates :more_info_url, presence_before_type_cast: {spec_section: "4.3.2"}
|
10
|
-
validates :more_info_url, :comments_url, http_url: {spec_section: "4.3.2"}
|
11
|
+
validates :more_info_url, presence_before_type_cast: { spec_section: "4.3.2" }
|
12
|
+
validates :more_info_url, :comments_url, http_url: { spec_section: "4.3.2" }
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "atdis/models/application"
|
2
4
|
|
3
5
|
module ATDIS
|
4
6
|
module Models
|
5
7
|
class Response < Model
|
6
|
-
|
8
|
+
field_mappings(
|
7
9
|
application: Application
|
8
|
-
|
10
|
+
)
|
9
11
|
|
10
|
-
validates :application, presence_before_type_cast: {spec_section: "4.3"}
|
12
|
+
validates :application, presence_before_type_cast: { spec_section: "4.3" }
|
11
13
|
|
12
14
|
# This model is only valid if the children are valid
|
13
15
|
validates :application, valid: true
|
@@ -1,23 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
module Models
|
3
5
|
class TorrensTitle < Model
|
4
|
-
|
5
|
-
lot:
|
6
|
+
field_mappings(
|
7
|
+
lot: String,
|
6
8
|
section: String,
|
7
9
|
dpsp_id: String
|
8
|
-
|
10
|
+
)
|
9
11
|
|
10
12
|
# Mandatory attributes
|
11
13
|
# section is not in this list because it can be null (even though it is mandatory)
|
12
|
-
validates :lot, :dpsp_id, presence_before_type_cast: {spec_section: "4.3.3"}
|
14
|
+
validates :lot, :dpsp_id, presence_before_type_cast: { spec_section: "4.3.3" }
|
13
15
|
# TODO: Provide warning if dpsp_id doesn't start with "DP" or "SP"
|
14
16
|
|
15
17
|
validate :section_can_not_be_empty_string
|
16
18
|
|
17
19
|
def section_can_not_be_empty_string
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
return unless section == ""
|
21
|
+
|
22
|
+
errors.add(:section, ATDIS::ErrorMessage.new("can't be blank", "4.3.3"))
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
data/lib/atdis/separated_url.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ATDIS
|
2
4
|
class SeparatedURL
|
3
|
-
|
4
5
|
def self.merge(full_url, params)
|
5
6
|
url, url_params = split(full_url)
|
6
7
|
combine(url, url_params.merge(params))
|
7
8
|
end
|
8
9
|
|
9
|
-
private
|
10
|
-
|
11
10
|
def self.combine(url, url_params)
|
12
11
|
# Doing this jiggery pokery to ensure the params are sorted alphabetically (even on Ruby 1.8)
|
13
|
-
query = url_params.map{|k,v| [k.to_s, v]
|
12
|
+
query = url_params.map { |k, v| [k.to_s, v] }
|
13
|
+
.sort
|
14
|
+
.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v.to_s)}" }
|
15
|
+
.join("&")
|
14
16
|
if url_params.empty?
|
15
17
|
url
|
16
18
|
else
|
@@ -20,18 +22,18 @@ module ATDIS
|
|
20
22
|
|
21
23
|
def self.split(full_url)
|
22
24
|
uri = URI.parse(full_url)
|
23
|
-
if (uri.scheme == "http" && uri.port == 80) ||
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
25
|
+
url = if (uri.scheme == "http" && uri.port == 80) ||
|
26
|
+
(uri.scheme == "https" && uri.port == 443)
|
27
|
+
"#{uri.scheme}://#{uri.host}#{uri.path}"
|
28
|
+
else
|
29
|
+
"#{uri.scheme}://#{uri.host}:#{uri.port}#{uri.path}"
|
30
|
+
end
|
31
|
+
url_params = if uri.query
|
32
|
+
Hash[*CGI.parse(uri.query).map { |k, v| [k.to_sym, v.first] }.flatten]
|
33
|
+
else
|
34
|
+
{}
|
35
|
+
end
|
33
36
|
[url, url_params]
|
34
37
|
end
|
35
|
-
|
36
38
|
end
|
37
39
|
end
|
data/lib/atdis/validators.rb
CHANGED
@@ -1,93 +1,100 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model"
|
2
4
|
|
3
5
|
module ATDIS
|
4
6
|
module Validators
|
5
7
|
class GeoJsonValidator < ActiveModel::EachValidator
|
6
8
|
def validate_each(record, attribute, value)
|
7
9
|
raw_value = record.send("#{attribute}_before_type_cast")
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
return unless raw_value.present? && value.nil?
|
11
|
+
|
12
|
+
message = "is not valid GeoJSON"
|
13
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
14
|
+
record.errors.add(attribute, message)
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
18
|
class DateTimeValidator < ActiveModel::EachValidator
|
17
19
|
def validate_each(record, attribute, value)
|
18
20
|
raw_value = record.send("#{attribute}_before_type_cast")
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
return unless raw_value.present? && !value.is_a?(DateTime)
|
22
|
+
|
23
|
+
record.errors.add(attribute, ErrorMessage["is not a valid date", options[:spec_section]])
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
27
|
class HttpUrlValidator < ActiveModel::EachValidator
|
26
28
|
def validate_each(record, attribute, value)
|
27
29
|
raw_value = record.send("#{attribute}_before_type_cast")
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
return unless raw_value.present? && !value.is_a?(URI::HTTP) && !value.is_a?(URI::HTTPS)
|
31
|
+
|
32
|
+
message = "is not a valid URL"
|
33
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
34
|
+
record.errors.add(attribute, message)
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
38
|
class ArrayHttpUrlValidator < ActiveModel::EachValidator
|
37
39
|
def validate_each(record, attribute, value)
|
38
|
-
if value.present? &&
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
if value.present? &&
|
41
|
+
value.is_a?(Array) &&
|
42
|
+
value.any? { |v| !v.is_a?(URI::HTTP) && !v.is_a?(URI::HTTPS) }
|
43
|
+
message = "contains an invalid URL"
|
44
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
45
|
+
record.errors.add(attribute, message)
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
50
|
class ArrayValidator < ActiveModel::EachValidator
|
48
51
|
def validate_each(record, attribute, value)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
return unless value && !value.is_a?(Array)
|
53
|
+
|
54
|
+
message = "should be an array"
|
55
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
56
|
+
record.errors.add(attribute, message)
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
57
60
|
# Can't be an empty array
|
58
61
|
class FilledArrayValidator < ActiveModel::EachValidator
|
59
62
|
def validate_each(record, attribute, value)
|
60
|
-
if value && !value.
|
63
|
+
if value && !value.is_a?(Array)
|
61
64
|
message = "should be an array"
|
62
65
|
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
63
66
|
record.errors.add(attribute, message)
|
64
67
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
68
|
+
return unless value&.is_a?(Array) && value&.empty?
|
69
|
+
|
70
|
+
message = "should not be an empty array"
|
71
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
72
|
+
record.errors.add(attribute, message)
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
73
76
|
# Take into account the value before type casting
|
74
77
|
class PresenceBeforeTypeCastValidator < ActiveModel::EachValidator
|
75
|
-
def validate_each(record, attribute,
|
78
|
+
def validate_each(record, attribute, _value)
|
76
79
|
raw_value = record.send("#{attribute}_before_type_cast")
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
return unless !raw_value.is_a?(Array) && !raw_value.present?
|
81
|
+
|
82
|
+
message = "can't be blank"
|
83
|
+
message = ErrorMessage[message, options[:spec_section]] if options[:spec_section]
|
84
|
+
record.errors.add(attribute, message)
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
85
88
|
# This attribute itself needs to be valid
|
86
89
|
class ValidValidator < ActiveModel::EachValidator
|
87
90
|
def validate_each(record, attribute, value)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
+
return unless (value.respond_to?(:valid?) && !value.valid?) ||
|
92
|
+
(value && !value.respond_to?(:valid?) && !value.all?(&:valid?))
|
93
|
+
|
94
|
+
record.errors.add(
|
95
|
+
attribute,
|
96
|
+
ErrorMessage["is not valid (see further errors for details)", nil]
|
97
|
+
)
|
91
98
|
end
|
92
99
|
end
|
93
100
|
end
|