atdis 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
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