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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +0 -1
  4. data/Gemfile +1 -1
  5. data/README.md +25 -2
  6. data/Rakefile +1 -1
  7. data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).doc +0 -0
  8. data/docs/ATDIS-1.0.2 Application Tracking Data Interchange Specification (v1.0.2).pdf +0 -0
  9. data/lib/atdis.rb +2 -7
  10. data/lib/atdis/feed.rb +80 -8
  11. data/lib/atdis/model.rb +74 -128
  12. data/lib/atdis/models/address.rb +17 -0
  13. data/lib/atdis/models/application.rb +31 -0
  14. data/lib/atdis/models/authority.rb +19 -0
  15. data/lib/atdis/models/document.rb +16 -0
  16. data/lib/atdis/models/event.rb +16 -0
  17. data/lib/atdis/models/info.rb +81 -0
  18. data/lib/atdis/models/land_title_ref.rb +26 -0
  19. data/lib/atdis/models/location.rb +23 -0
  20. data/lib/atdis/models/page.rb +56 -0
  21. data/lib/atdis/models/pagination.rb +68 -0
  22. data/lib/atdis/models/person.rb +14 -0
  23. data/lib/atdis/models/reference.rb +13 -0
  24. data/lib/atdis/models/response.rb +16 -0
  25. data/lib/atdis/models/torrens_title.rb +24 -0
  26. data/lib/atdis/validators.rb +26 -10
  27. data/lib/atdis/version.rb +1 -1
  28. data/spec/atdis/feed_spec.rb +78 -22
  29. data/spec/atdis/model_spec.rb +80 -131
  30. data/spec/atdis/models/address_spec.rb +22 -0
  31. data/spec/atdis/models/application_spec.rb +246 -0
  32. data/spec/atdis/models/authority_spec.rb +34 -0
  33. data/spec/atdis/models/document_spec.rb +19 -0
  34. data/spec/atdis/models/event_spec.rb +29 -0
  35. data/spec/atdis/models/info_spec.rb +303 -0
  36. data/spec/atdis/models/land_title_ref_spec.rb +39 -0
  37. data/spec/atdis/models/location_spec.rb +95 -0
  38. data/spec/atdis/models/page_spec.rb +296 -0
  39. data/spec/atdis/models/pagination_spec.rb +153 -0
  40. data/spec/atdis/models/person_spec.rb +19 -0
  41. data/spec/atdis/models/reference_spec.rb +55 -0
  42. data/spec/atdis/models/response_spec.rb +5 -0
  43. data/spec/atdis/models/torrens_title_spec.rb +52 -0
  44. data/spec/atdis/separated_url_spec.rb +4 -4
  45. metadata +141 -135
  46. data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).doc +0 -0
  47. data/docs/ATDIS-1.0.7 Application Tracking Data Interchange Specification (v1.0).pdf +0 -0
  48. data/lib/atdis/application.rb +0 -78
  49. data/lib/atdis/document.rb +0 -14
  50. data/lib/atdis/event.rb +0 -17
  51. data/lib/atdis/location.rb +0 -21
  52. data/lib/atdis/page.rb +0 -130
  53. data/lib/atdis/person.rb +0 -12
  54. data/spec/atdis/application_spec.rb +0 -539
  55. data/spec/atdis/document_spec.rb +0 -19
  56. data/spec/atdis/event_spec.rb +0 -29
  57. data/spec/atdis/location_spec.rb +0 -148
  58. data/spec/atdis/page_spec.rb +0 -492
  59. data/spec/atdis/person_spec.rb +0 -19
data/lib/atdis/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Atdis
2
- VERSION = "0.2"
2
+ VERSION = "0.3"
3
3
  end
@@ -1,40 +1,96 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe ATDIS::Feed do
4
- let (:base_url_string) { "http://www.council.nsw.gov.au" }
5
- let (:base_url) { URI.parse(base_url_string) }
4
+ let(:feed) { ATDIS::Feed.new("http://www.council.nsw.gov.au/atdis/1.0") }
5
+ let(:page) { double }
6
6
 
7
- context "base_url passed as string" do
8
- let(:feed) { ATDIS::Feed.new(base_url_string) }
7
+ it "should return all the applications" do
8
+ ATDIS::Models::Page.should_receive(:read_url).with("http://www.council.nsw.gov.au/atdis/1.0/applications.json").and_return(page)
9
+ feed.applications.should == page
10
+ end
11
+
12
+ it "should return all the applications" do
13
+ feed.applications_url.should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json"
14
+ end
9
15
 
10
- describe "#base_url" do
11
- it { feed.base_url.should == base_url }
16
+ describe "should restrict search by postcode" do
17
+ it "single postcode" do
18
+ feed.applications_url(postcode: 2000).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?postcode=2000"
12
19
  end
13
20
 
14
- describe "#applications" do
15
- it do
16
- applications_results = double
17
- ATDIS::Page.should_receive(:read_url).with(URI.parse("http://www.council.nsw.gov.au/atdis/1.0/applications.json")).and_return(applications_results)
18
- feed.applications.should == applications_results
19
- end
21
+ it "multiple postcodes in an array" do
22
+ feed.applications_url(postcode: [2000,2001]).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?postcode=2000,2001"
23
+ end
24
+
25
+ it "multiple postcodes as a string" do
26
+ feed.applications_url(postcode: "2000,2001").should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?postcode=2000,2001"
20
27
  end
21
28
  end
22
29
 
23
- context "base_url passed as url" do
24
- let(:feed) { ATDIS::Feed.new(base_url) }
30
+ describe "search by lodgement date" do
31
+ it "just a lodgement start date as a date" do
32
+ feed.applications_url(lodgement_date_start: Date.new(2001,2,1)).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?lodgement_date_start=2001-02-01"
33
+ end
34
+
35
+ it "just a lodgement start date as a string" do
36
+ feed.applications_url(lodgement_date_start: "2011-02-04").should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?lodgement_date_start=2011-02-04"
37
+ end
25
38
 
26
- describe "#base_url" do
27
- it { feed.base_url.should == base_url }
39
+ it "a lodgement start date and end date" do
40
+ feed.applications_url(lodgement_date_start: Date.new(2001,2,1), lodgement_date_end: Date.new(2001,3,1)).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?lodgement_date_end=2001-03-01&lodgement_date_start=2001-02-01"
28
41
  end
29
42
  end
30
43
 
31
- context "request for page 2" do
32
- let(:feed) { ATDIS::Feed.new(base_url_string)}
44
+ describe "search by last modified date" do
45
+ it "just a last modified start date" do
46
+ feed.applications_url(last_modified_date_start: Date.new(2001,2,1)).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?last_modified_date_start=2001-02-01"
47
+ end
33
48
 
34
- it "#applications" do
35
- applications_results = double
36
- ATDIS::Page.should_receive(:read_url).with(URI.parse("http://www.council.nsw.gov.au/atdis/1.0/applications.json?page=2")).and_return(applications_results)
37
- feed.applications(2).should == applications_results
49
+ it "a last modified start date and end date" do
50
+ feed.applications_url(last_modified_date_start: Date.new(2001,2,1), last_modified_date_end: Date.new(2001,3,1)).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?last_modified_date_end=2001-03-01&last_modified_date_start=2001-02-01"
38
51
  end
39
52
  end
53
+
54
+ it "jump straight to the second page" do
55
+ feed.applications_url(page: 2).should == "http://www.council.nsw.gov.au/atdis/1.0/applications.json?page=2"
56
+ end
57
+
58
+ it "passing an invalid option" do
59
+ expect {feed.applications_url(foo: 1)}.to raise_error "Unexpected options used: foo"
60
+ end
61
+
62
+ describe ".base_url_from_url" do
63
+ it { ATDIS::Feed.base_url_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json?postcode=2000").should == "http://www.council.nsw.gov.au/atdis/1.0" }
64
+ it { ATDIS::Feed.base_url_from_url("http://www.foo.nsw.gov.au/prefix/atdis/1.0/applications.json?postcode=2000#bar").should == "http://www.foo.nsw.gov.au/prefix/atdis/1.0" }
65
+ it "should assume that any query parameters that are not recognised are part of the base_url" do
66
+ ATDIS::Feed.base_url_from_url("http://www.foo.nsw.gov.au/prefix/atdis/1.0/applications.json?postcode=2000&foo=bar").should == "http://www.foo.nsw.gov.au/prefix/atdis/1.0?foo=bar"
67
+ end
68
+ end
69
+
70
+ describe ".options_from_url" do
71
+ it { ATDIS::Feed.options_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json").should == {} }
72
+ it { ATDIS::Feed.options_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json?page=2").should == {page: 2} }
73
+ it { ATDIS::Feed.options_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json?postcode=2000,2001").should == {postcode: "2000,2001"} }
74
+ it { ATDIS::Feed.options_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json?lodgement_date_end=2001-03-01&lodgement_date_start=2001-02-01").should ==
75
+ {lodgement_date_start: Date.new(2001,2,1), lodgement_date_end: Date.new(2001,3,1)} }
76
+ it { ATDIS::Feed.options_from_url("http://www.council.nsw.gov.au/atdis/1.0/applications.json?last_modified_date_end=2001-03-01&last_modified_date_start=2001-02-01").should ==
77
+ {last_modified_date_start: Date.new(2001,2,1), last_modified_date_end: Date.new(2001,3,1)} }
78
+ it "should assume that any query parameters that are not recognised are part of the base_url" do
79
+ ATDIS::Feed.options_from_url("http://www.foo.nsw.gov.au/prefix/atdis/1.0/applications.json?postcode=2000&foo=bar").should == {postcode: "2000"}
80
+ end
81
+ end
82
+
83
+ describe "#application_url" do
84
+ it { feed.application_url("27B6").should == "http://www.council.nsw.gov.au/atdis/1.0/27B6.json" }
85
+ it { feed.application_url("27B stroke 6").should == "http://www.council.nsw.gov.au/atdis/1.0/27B+stroke+6.json" }
86
+ it { feed.application_url("27B/6").should == "http://www.council.nsw.gov.au/atdis/1.0/27B%2F6.json" }
87
+ end
88
+
89
+ describe "#application" do
90
+ it {
91
+ application = double
92
+ ATDIS::Models::Application.should_receive(:read_url).with("http://www.council.nsw.gov.au/atdis/1.0/27B%2F6.json").and_return(application)
93
+ feed.application("27B/6").should == application
94
+ }
95
+ end
40
96
  end
@@ -1,7 +1,67 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
+ class ModelB < ATDIS::Model
4
+ set_field_mappings ({
5
+ bar: [String]
6
+ })
7
+ end
8
+
9
+ class ModelA < ATDIS::Model
10
+ set_field_mappings ({
11
+ bar: [String],
12
+ hello: [ModelB]
13
+ })
14
+ end
15
+
3
16
  describe ATDIS::Model do
4
- describe ".cast" do
17
+ describe ".attributes" do
18
+ it do
19
+ a = ModelA.new(bar: "foo")
20
+ a.attributes.should == {"bar" => "foo"}
21
+ end
22
+ end
23
+
24
+ describe "#json_errors" do
25
+ it "should return the json attribute with the errors" do
26
+ a = ModelA.interpret(bar: "Hello")
27
+ a.errors.add(:bar, ATDIS::ErrorMessage["can not be so friendly", "4.5"])
28
+ a.errors.add(:bar, ATDIS::ErrorMessage["and something else", "4.6"])
29
+ a.json_errors.should == [[{bar: "Hello"}, [
30
+ ATDIS::ErrorMessage["bar can not be so friendly", "4.5"],
31
+ ATDIS::ErrorMessage["bar and something else", "4.6"]]]]
32
+ end
33
+
34
+ it "should include the errors from child objects" do
35
+ a = ModelA.interpret(hello: {bar: "Kat"})
36
+ a.hello.errors.add(:bar, ATDIS::ErrorMessage["can't be a name", "2.3"])
37
+ a.hello.json_errors.should == [[{bar: "Kat"}, [ATDIS::ErrorMessage["bar can't be a name", "2.3"]]]]
38
+ a.json_errors.should == [[{hello: {bar: "Kat"}}, [ATDIS::ErrorMessage["bar can't be a name", "2.3"]]]]
39
+ end
40
+
41
+ it "should include the errors from only the first child object in an array" do
42
+ a = ModelA.interpret(hello: [{bar: "Kat"}, {bar: "Mat"}])
43
+ a.hello[0].bar.should == "Kat"
44
+ a.hello[1].bar.should == "Mat"
45
+ a.json_errors.should == []
46
+ a.hello[0].errors.add(:bar, ATDIS::ErrorMessage["can't be a name", "1.2"])
47
+ a.hello[1].errors.add(:bar, ATDIS::ErrorMessage["can't be a name", "1.2"])
48
+ a.json_errors.should == [[{hello: [{bar: "Kat"}]}, [ATDIS::ErrorMessage["bar can't be a name", "1.2"]]]]
49
+ end
50
+
51
+ it "should show json parsing errors" do
52
+ a = ModelA.interpret(invalid: {parameter: "foo"})
53
+ a.should_not be_valid
54
+ a.json_errors.should == [[nil, [ATDIS::ErrorMessage['Unexpected parameters in json data: {"invalid":{"parameter":"foo"}}', "4"]]]]
55
+ end
56
+
57
+ it "should json errors even if value is nil" do
58
+ b = ModelB.new
59
+ b.errors.add(:bar, ATDIS::ErrorMessage.new("can't be nil", "1.2"))
60
+ b.json_errors.should == [[{bar: nil}, [ATDIS::ErrorMessage.new("bar can't be nil", "1.2")]]]
61
+ end
62
+ end
63
+
64
+ describe ".cast" do
5
65
  it {ATDIS::Model.cast("2013-04-20T02:01:07Z", DateTime).should == DateTime.new(2013,4,20,2,1,7)}
6
66
  it {ATDIS::Model.cast("2013-04-20", DateTime).should == DateTime.new(2013,4,20)}
7
67
  it {ATDIS::Model.cast("2013-04-20T02:01:07+05:00", DateTime).should == DateTime.new(2013,4,20,2,1,7,"+5")}
@@ -24,147 +84,36 @@ describe ATDIS::Model do
24
84
  end
25
85
  end
26
86
 
27
- describe ".map_field" do
28
- let(:mappings) { { :foo => :bar, :a => :b, :info => { :foo => :bar2, :a => :b2, :c => :c2 } } }
29
-
30
- context "one version of data" do
31
- let(:data) { { :foo => 2, :a => 3, :d => 4, :info => { :foo => 2, :a => 3, :d => 4 } } }
32
-
33
- it { ATDIS::Model.map_field(:bar, data, mappings).should == 2 }
34
- it { ATDIS::Model.map_field(:b, data, mappings).should == 3 }
35
- it { ATDIS::Model.map_field(:bar2, data, mappings).should == 2 }
36
- it { ATDIS::Model.map_field(:b2, data, mappings).should == 3 }
37
- it { ATDIS::Model.map_field(:c2, data, mappings).should be_nil }
38
- end
39
-
40
- context "another version of data" do
41
- let(:data) { { :foo => 2, :a => 3, :d => 4 } }
42
-
43
- it { ATDIS::Model.map_field(:bar, data, mappings).should == 2 }
44
- it { ATDIS::Model.map_field(:b, data, mappings).should == 3 }
45
- it { ATDIS::Model.map_field(:bar2, data, mappings).should be_nil }
46
- it { ATDIS::Model.map_field(:b2, data, mappings).should be_nil }
47
- it { ATDIS::Model.map_field(:c2, data, mappings).should be_nil }
48
- end
49
- end
50
-
51
- describe ".unused_data" do
52
- it do
53
- ATDIS::Model.unused_data(
54
- {
55
- :foo => 2,
56
- :a => 3,
57
- :d => 4
58
- },
59
- {
60
- :foo => :bar,
61
- :a => :b
62
- }).should ==
63
- {
64
- :d => 4
65
- }
66
- end
67
-
87
+ describe ".attribute_keys" do
68
88
  it do
69
- ATDIS::Model.unused_data(
70
- {
71
- :foo => 2,
72
- :a => 3,
73
- :d => 4,
74
- :info => {
75
- :foo => 2,
76
- :a => 3,
77
- :d => 4
78
- }
79
- },
80
- {
81
- :foo => :bar,
82
- :a => :b,
83
- :info => {
84
- :foo => :bar2,
85
- :a => :b2
86
- }
87
- }).should ==
88
- {
89
- :d => 4,
90
- :info => {
91
- :d => 4
92
- }
93
- }
89
+ ATDIS::Model.attribute_types = {foo: String, a: Fixnum, info: String}
90
+ ATDIS::Model.attribute_keys.should == [:foo, :a, :info]
94
91
  end
95
92
  end
96
93
 
97
- describe ".attribute_names_from_mappings" do
94
+ describe ".partition_by_used" do
98
95
  it do
99
- # Doing this nastiness to support Ruby 1.8
100
- h = ActiveSupport::OrderedHash.new
101
- h[:foo] = :bar
102
- h[:a] = :b
103
- h2 = ActiveSupport::OrderedHash.new
104
- h2[:foo] = :bar2
105
- h2[:a] = :b2
106
- h[:info] = h2
107
- ATDIS::Model.attribute_names_from_mappings(h).should == [:bar, :b, :bar2, :b2]
96
+ ATDIS::Model.stub(:attribute_keys).and_return([:foo])
97
+ ATDIS::Model.partition_by_used({foo: 2}).should == [
98
+ {foo: 2}, {}
99
+ ]
108
100
  end
109
- end
110
101
 
111
- describe ".map_fields" do
112
102
  it do
113
- ATDIS::Model.map_fields(
114
- {
115
- :foo => 2,
116
- :a => 3,
117
- :d => 4
118
- },
119
- {
120
- :foo => :bar,
121
- :a => :b
122
- }).should ==
123
- {
124
- :bar => 2,
125
- :b => 3,
126
- }
103
+ ATDIS::Model.stub(:attribute_keys).and_return([:foo, :a])
104
+ ATDIS::Model.partition_by_used({foo: 2, a: 3, d: 4}).should == [
105
+ {foo: 2, a: 3},
106
+ {d: 4}
107
+ ]
127
108
  end
128
109
 
129
- it do
130
- ATDIS::Model.map_fields(
131
- {
132
- :foo => 2,
133
- :a => 3,
134
- :d => 4,
135
- :info => {
136
- :foo => 2,
137
- :a => 3,
138
- :d => 4
139
- }
140
- },
141
- {
142
- :foo => :bar,
143
- :a => :b,
144
- :info => {
145
- :foo => :bar2,
146
- :a => :b2
147
- }
148
- }).should ==
149
- {
150
- :bar => 2,
151
- :b => 3,
152
- :bar2 => 2,
153
- :b2 => 3
154
- }
155
- end
156
- end
157
-
158
- describe "#json_attribute" do
159
- let(:model) { ATDIS::Model.new }
160
- let(:mapping) { {:previous => :previous_page_no, :next => :next_page_no, :foo => {:bar => :apple, :foo => :orange}} }
161
-
162
- it "simple case" do
163
- model.json_attribute(:previous_page_no, 12, mapping).should == {:previous => 12}
164
- end
110
+ it "something that isn't a hash will never get used" do
111
+ ATDIS::Model.stub(:attribute_keys).and_return([:foo, :a])
112
+ ATDIS::Model.partition_by_used("hello").should == [
113
+ {},
114
+ "hello"
115
+ ]
165
116
 
166
- it "with recursion" do
167
- model.json_attribute(:apple, 12, mapping).should == {:foo => {:bar => 12}}
168
117
  end
169
118
  end
170
119
  end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe ATDIS::Models::Address do
4
+ context "valid address" do
5
+ let(:a) { ATDIS::Models::Address.new(
6
+ street: "123 Fourfivesix Street",
7
+ suburb: "Neutral Bay",
8
+ postcode: "2780",
9
+ state: "NSW"
10
+ )}
11
+
12
+ it { a.should be_valid }
13
+
14
+ context "postcode that is too short" do
15
+ before(:each) { a.postcode = "278" }
16
+ it {
17
+ a.should_not be_valid
18
+ a.errors.messages.should == {postcode: [ATDIS::ErrorMessage.new("is not a valid postcode", "4.3.3")]}
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,246 @@
1
+ require "spec_helper"
2
+
3
+ describe ATDIS::Models::Application do
4
+ context "extra parameter in json" do
5
+ it "should not be valid" do
6
+ ATDIS::Models::Location.should_receive(:interpret).with("location").and_return(double(valid?: true))
7
+ ATDIS::Models::Document.should_receive(:interpret).with("document").and_return(double(valid?: true))
8
+ ATDIS::Models::Event.should_receive(:interpret).with("event").and_return(double(valid?: true))
9
+
10
+ a = ATDIS::Models::Application.interpret(
11
+ info: {
12
+ dat_id: "DA2013-0381",
13
+ development_type: "residential",
14
+ application_type: "DA",
15
+ last_modified_date: "2013-04-20T02:01:07Z",
16
+ description: "New pool plus deck",
17
+ authority: {
18
+ ref: "http://www.council.nsw.gov.au/atdis/1.0",
19
+ name: "Example Council Shire Council"
20
+ },
21
+ lodgement_date: "2013-04-20T02:01:07Z",
22
+ determination_date: "2013-06-20",
23
+ determination_type: "Pending",
24
+ status: "OPEN"
25
+ },
26
+ reference: {
27
+ more_info_url: "http://foo.com/bar"
28
+ },
29
+ # This is the extra parameter that shouldn't be here
30
+ foo: "bar",
31
+ locations: ["location"],
32
+ events: ["event"],
33
+ documents: ["document"]
34
+ )
35
+ a.should_not be_valid
36
+ a.errors.messages.should == {json: [ATDIS::ErrorMessage['Unexpected parameters in json data: {"foo":"bar"}', "4"]]}
37
+ end
38
+ end
39
+
40
+ describe ".interpret" do
41
+ it "should parse the json and create an application object" do
42
+ application = double
43
+
44
+ ATDIS::Models::Application.should_receive(:new).with(
45
+ info: {
46
+ dat_id: "DA2013-0381",
47
+ development_type: "residential",
48
+ last_modified_date: "2013-04-20T02:01:07Z",
49
+ description: "New pool plus deck",
50
+ authority: "Example Council Shire Council",
51
+ lodgement_date: "2013-04-20T02:01:07Z",
52
+ determination_date: "2013-06-20",
53
+ notification_start_date: "2013-04-20T02:01:07Z",
54
+ notification_end_date: "2013-05-20T02:01:07Z",
55
+ officer: "Ms Smith",
56
+ estimated_cost: "50,000",
57
+ status: "OPEN",
58
+ },
59
+ reference: {
60
+ more_info_url: "http://foo.com/bar",
61
+ comments_url: "http://foo.com/comment",
62
+ },
63
+ locations: [{ address: "123 Fourfivesix Street" }],
64
+ events: [ { id: "event1" }, { id: "event2" } ],
65
+ documents: [ { ref: "27B/6/a" }, { ref: "27B/6/b" } ],
66
+ people: [ { name: "Tuttle" }, { name: "Buttle" } ],
67
+ extended: {another_parameter: "with some value", anything: "can go here"},
68
+ json_left_overs: {}
69
+ ).and_return(application)
70
+
71
+ ATDIS::Models::Application.interpret(
72
+ info: {
73
+ dat_id: "DA2013-0381",
74
+ development_type: "residential",
75
+ last_modified_date: "2013-04-20T02:01:07Z",
76
+ description: "New pool plus deck",
77
+ authority: "Example Council Shire Council",
78
+ lodgement_date: "2013-04-20T02:01:07Z",
79
+ determination_date: "2013-06-20",
80
+ notification_start_date: "2013-04-20T02:01:07Z",
81
+ notification_end_date: "2013-05-20T02:01:07Z",
82
+ officer: "Ms Smith",
83
+ # TODO: In ATDIS-1.0.3 it does not specify whether this is a float or a string
84
+ # and whether to include (or not) AUD or dollar sign. For the time being we'll
85
+ # just assume it's a free-form string
86
+ estimated_cost: "50,000",
87
+ status: "OPEN"
88
+ },
89
+ reference: {
90
+ more_info_url: "http://foo.com/bar",
91
+ comments_url: "http://foo.com/comment"
92
+ },
93
+ locations: [{ address: "123 Fourfivesix Street" }],
94
+ events: [ { id: "event1" }, { id: "event2" } ],
95
+ documents: [ { ref: "27B/6/a" }, { ref: "27B/6/b" } ],
96
+ people: [ { name: "Tuttle" }, { name: "Buttle" } ],
97
+ extended: {another_parameter: "with some value", anything: "can go here"}
98
+ ).should == application
99
+ end
100
+
101
+ it "should create a nil valued application when there is no information in the json" do
102
+ application = double
103
+ ATDIS::Models::Application.should_receive(:new).with({json_left_overs:{}, info: {},
104
+ reference: {}}).and_return(application)
105
+
106
+ ATDIS::Models::Application.interpret(info: {}, reference: {}).should == application
107
+ end
108
+ end
109
+
110
+ describe "#extended" do
111
+ it "should do no typecasting" do
112
+ a = ATDIS::Models::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::Models::Application.new }
119
+ it "should type cast to a location" do
120
+ location = double
121
+ ATDIS::Models::Location.should_receive(:interpret).with(address: "123 Fourfivesix Street").and_return(location)
122
+ a.locations = [{ address: "123 Fourfivesix Street" }]
123
+ a.locations.should == [location]
124
+ end
125
+
126
+ it "should not cast when it's already a location" do
127
+ l = ATDIS::Models::Location.new
128
+ a.locations = [l]
129
+ a.locations.should == [l]
130
+ end
131
+ end
132
+
133
+ describe "#events" do
134
+ let(:a) { ATDIS::Models::Application.new }
135
+ it "should type cast to several events" do
136
+ event1, event2 = double, double
137
+ ATDIS::Models::Event.should_receive(:interpret).with(id: "event1").and_return(event1)
138
+ ATDIS::Models::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::Models::Application.new }
146
+ it "should type cast to several documents" do
147
+ document1, document2 = double, double
148
+ ATDIS::Models::Document.should_receive(:interpret).with(ref: "27B/6/a").and_return(document1)
149
+ ATDIS::Models::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::Models::Application.new }
157
+ it "should type cast to several people" do
158
+ tuttle, buttle = double, double
159
+ ATDIS::Models::Person.should_receive(:interpret).with(name: "Tuttle").and_return(tuttle)
160
+ ATDIS::Models::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
+ # TODO This should really be a test on the Model base class
167
+ describe "#attribute_names" do
168
+ it do
169
+ # These are also ordered in a way that corresponds to the specification. Makes for easy reading by humans.
170
+ ATDIS::Models::Application.attribute_names.should == [
171
+ "info",
172
+ "reference",
173
+ "locations",
174
+ "events",
175
+ "documents",
176
+ "people",
177
+ "extended"
178
+ ]
179
+ end
180
+ end
181
+
182
+ describe "validations" do
183
+ before :each do
184
+ ATDIS::Models::Location.should_receive(:interpret).with("address").and_return(double(valid?: true))
185
+ ATDIS::Models::Document.should_receive(:interpret).with("document").and_return(double(valid?: true))
186
+ ATDIS::Models::Event.should_receive(:interpret).with("event").and_return(double(valid?: true))
187
+ end
188
+
189
+ let(:a) { ATDIS::Models::Application.new(
190
+ info: ATDIS::Models::Info.new(
191
+ dat_id: "DA2013-0381",
192
+ development_type: "residential",
193
+ application_type: "DA",
194
+ last_modified_date: DateTime.new(2013,4,20,2,1,7),
195
+ description: "New pool plus deck",
196
+ authority: {
197
+ ref: "http://www.council.nsw.gov.au/atdis/1.0",
198
+ name: "Example Council Shire Council"
199
+ },
200
+ lodgement_date: DateTime.new(2013,4,20,2,1,7),
201
+ determination_date: DateTime.new(2013,6,20),
202
+ determination_type: "Pending",
203
+ status: "OPEN",
204
+ ),
205
+ reference: ATDIS::Models::Reference.new(
206
+ more_info_url: URI.parse("http://foo.com/bar"),
207
+ ),
208
+ locations: ["address"],
209
+ events: ["event"],
210
+ documents: ["document"]
211
+ ) }
212
+
213
+ it { a.should be_valid }
214
+
215
+ describe ".location" do
216
+ it "should not be valid if the location is not valid" do
217
+ l = double(valid?: false)
218
+ ATDIS::Models::Location.should_receive(:interpret).with(foo: "some location data").and_return(l)
219
+ a.locations = [{foo: "some location data"}]
220
+ a.should_not be_valid
221
+ end
222
+ end
223
+
224
+ describe "events" do
225
+ it "has to be an array" do
226
+ ATDIS::Models::Event.should_receive(:interpret).with(foo: "bar").and_return(double(valid?: true))
227
+ a.events = {foo: "bar"}
228
+ #a.events.should be_nil
229
+ a.should_not be_valid
230
+ a.errors.messages.should == {events: [ATDIS::ErrorMessage["should be an array", "4.3"]]}
231
+ end
232
+
233
+ it "can not be an empty array" do
234
+ a.events = []
235
+ a.should_not be_valid
236
+ a.errors.messages.should == {events: [ATDIS::ErrorMessage.new("should not be an empty array", "4.3")]}
237
+ end
238
+
239
+ it "can not be empty" do
240
+ a.events = nil
241
+ a.should_not be_valid
242
+ a.errors.messages.should == {events: [ATDIS::ErrorMessage["can't be blank", "4.3"]]}
243
+ end
244
+ end
245
+ end
246
+ end