g5_updatable 0.10.3 → 0.20.3.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -2
  3. data/app/concerns/g5_updatable/belongs_to_client.rb +3 -3
  4. data/app/controllers/g5_updatable/feed_controller.rb +1 -1
  5. data/app/controllers/g5_updatable/locations_controller.rb +2 -2
  6. data/app/controllers/g5_updatable/syncs_controller.rb +3 -3
  7. data/app/models/g5_updatable/client.rb +4 -4
  8. data/app/models/g5_updatable/hub_amenities_location.rb +6 -0
  9. data/app/models/g5_updatable/hub_amenity.rb +21 -0
  10. data/app/models/g5_updatable/location.rb +75 -2
  11. data/app/serializers/g5_updatable/location_serializer.rb +8 -0
  12. data/db/migrate/20151103043916_add_latitude_and_longitude_to_location.rb +6 -0
  13. data/db/migrate/20151103050229_copy_lat_long_props_to_lat_long_columns.rb +19 -0
  14. data/db/migrate/20151106070749_add_latitude_longitude_indexes_to_location.rb +6 -0
  15. data/db/migrate/20161122070749_add_amenities.rb +25 -0
  16. data/db/migrate/20161209070749_add_client_urn_to_locations.rb +6 -0
  17. data/lib/g5_updatable.rb +5 -3
  18. data/lib/g5_updatable/all_client_urns_fetcher.rb +17 -0
  19. data/lib/g5_updatable/client_feed_processor.rb +26 -14
  20. data/lib/g5_updatable/client_updater.rb +37 -12
  21. data/lib/g5_updatable/factories.rb +2 -2
  22. data/lib/g5_updatable/fetcher.rb +22 -0
  23. data/lib/g5_updatable/indifferentizer.rb +11 -0
  24. data/lib/g5_updatable/locations_updater.rb +68 -20
  25. data/lib/g5_updatable/rspec/factories.rb +53 -2
  26. data/lib/g5_updatable/version.rb +1 -1
  27. data/lib/tasks/g5_updatable_tasks.rake +11 -4
  28. data/spec/concerns/g5_updatable/belongs_to_client_spec.rb +1 -3
  29. data/spec/controllers/feed_controller_spec.rb +21 -0
  30. data/spec/controllers/syncs_controller_spec.rb +3 -3
  31. data/spec/dummy/config/database.yml +2 -2
  32. data/spec/dummy/db/schema.rb +28 -1
  33. data/spec/dummy/log/development.log +172 -146
  34. data/spec/dummy/log/test.log +101011 -13426
  35. data/spec/dummy/log/tests.log +0 -0
  36. data/spec/fixtures/client-g5-c-1soj8m6e-g5-multifamily-missing-locations.json +121 -0
  37. data/spec/fixtures/client-g5-c-1soj8m6e-g5-multifamily-no-locations.json +41 -0
  38. data/spec/fixtures/client-g5-c-1soj8m6e-g5-multifamily.json +471 -0
  39. data/spec/fixtures/hub-client.json +187 -0
  40. data/spec/fixtures/hub-clients.json +19972 -0
  41. data/spec/fixtures/hub-location.json +166 -0
  42. data/spec/fixtures/location-g5-cl-1soj9pe2-541-apartments.json +98 -0
  43. data/spec/fixtures/urns.json +10 -0
  44. data/spec/lib/g5_updatable/all_client_urns_fetcher_spec.rb +56 -0
  45. data/spec/lib/g5_updatable/client_feed_processor_spec.rb +86 -33
  46. data/spec/lib/g5_updatable/client_updater_spec.rb +55 -23
  47. data/spec/lib/g5_updatable/locations_updater_spec.rb +140 -54
  48. data/spec/models/g5_updatable/client_spec.rb +2 -0
  49. data/spec/models/g5_updatable/hub_amenities_location_spec.rb +6 -0
  50. data/spec/models/g5_updatable/hub_amenity_spec.rb +29 -0
  51. data/spec/models/g5_updatable/location_spec.rb +240 -10
  52. data/spec/serializers/g5_updatable/location_serializer_spec.rb +2 -1
  53. data/spec/spec_helper.rb +2 -1
  54. data/spec/support/fixture_helper.rb +5 -0
  55. data/spec/support/shared_examples/belongs_to_client.rb +4 -5
  56. metadata +84 -17
@@ -0,0 +1,166 @@
1
+ {
2
+ "location": {
3
+ "id": 3,
4
+ "uid": "http://192.168.33.30:3000/clients/g5-c-6hng302-no-store/locations/g5-cl-6hng303-brussels",
5
+ "client_id": 2,
6
+ "client_uid": "http://192.168.33.30:3000/clients/g5-c-6hng302-no-store",
7
+ "name": "brussels",
8
+ "corporate": false,
9
+ "created_at": "2014-10-08T20:27:36.011Z",
10
+ "updated_at": "2014-10-08T20:27:36.011Z",
11
+ "urn": "g5-cl-6hng303-brussels",
12
+ "street_address_1": "20270 W North Ave",
13
+ "street_address_2": "",
14
+ "city": "Brookfield",
15
+ "state": "WI",
16
+ "postal_code": "53045-4278",
17
+ "fax": "(262) 744-9458",
18
+ "email": "perry@hertler.org",
19
+ "hours": "",
20
+ "twitter_username": "",
21
+ "facebook_username": "",
22
+ "yelp_username": "",
23
+ "pinterest_username": "",
24
+ "foursquare_username": "",
25
+ "tumblr_username": "",
26
+ "instagram_username": "",
27
+ "vimeo_username": "",
28
+ "youtube_username": "",
29
+ "domain": "http://nostore.com/brussels",
30
+ "phone_number": "(262) 744-9458",
31
+ "neighborhood": "",
32
+ "boat_storage": false,
33
+ "business_storage": false,
34
+ "gate_access": false,
35
+ "security_monitoring": false,
36
+ "business_center": false,
37
+ "climate_controlled": false,
38
+ "heated_cooled": false,
39
+ "friendly_staff": false,
40
+ "covered_drivethru": false,
41
+ "covered_loading": false,
42
+ "rv_boat_storage": false,
43
+ "outside_parking": false,
44
+ "deliveries": false,
45
+ "dollies_carts": false,
46
+ "digital_surveillance": false,
47
+ "drive_up_access": false,
48
+ "electronic_gate": false,
49
+ "uhaul_trucks": false,
50
+ "budget_trucks": false,
51
+ "moving_trucks": false,
52
+ "free_truck": false,
53
+ "fenced_lighted": false,
54
+ "ground_level_units": false,
55
+ "high_ceilings": false,
56
+ "individual_alarmed_units": false,
57
+ "mail_boxes": false,
58
+ "major_credit_cards": false,
59
+ "military_discounts": false,
60
+ "student_discount": false,
61
+ "senior_discount": false,
62
+ "month_to_month": false,
63
+ "no_admin_fee": false,
64
+ "no_deposits": false,
65
+ "no_late_fees": false,
66
+ "online_bill_pay": false,
67
+ "packing_moving_supplies": false,
68
+ "boxes_locks": false,
69
+ "tenant_insurance": false,
70
+ "truck_rentals": false,
71
+ "wide_driveways": false,
72
+ "wine_storage": false,
73
+ "other_features": "",
74
+ "rv_storage": false,
75
+ "seven_day_access": false,
76
+ "other_storage": "",
77
+ "specific_demographic": "",
78
+ "primary_offering": "",
79
+ "secondary_other": "",
80
+ "secondary_condo": false,
81
+ "secondary_townhomes": false,
82
+ "secondary_apartments": false,
83
+ "floor_plans": "",
84
+ "nearby_schools": "",
85
+ "highrise_structure": false,
86
+ "garden_structure": false,
87
+ "townhome_structure": false,
88
+ "modern_structure": false,
89
+ "nearby_employers": "",
90
+ "dogs_allowed": false,
91
+ "cats_allowed": false,
92
+ "accessibility": "0",
93
+ "air_conditioned": false,
94
+ "cable_included": false,
95
+ "ceiling_fans": false,
96
+ "custom_cabinetry": false,
97
+ "dishwasher": false,
98
+ "energy_efficient": false,
99
+ "fireplace": false,
100
+ "granite_counters": false,
101
+ "hardwood_floors": false,
102
+ "private_balcony": false,
103
+ "private_patio": false,
104
+ "refrigerator": false,
105
+ "stainless_appliances": false,
106
+ "smoke_free": false,
107
+ "style_design": "",
108
+ "style_cost": "",
109
+ "walkin_closet": false,
110
+ "washer_dryer": false,
111
+ "has_view": false,
112
+ "other_amenities": "",
113
+ "carport_parking": false,
114
+ "club_house": false,
115
+ "dog_park": false,
116
+ "corporate_suites": false,
117
+ "family_friendly": false,
118
+ "fitness_center": false,
119
+ "furnished_apartments": false,
120
+ "garages": false,
121
+ "gated_entrance": false,
122
+ "laundry_facilities": false,
123
+ "online_rental_payments": false,
124
+ "onsite_management": false,
125
+ "close_park": false,
126
+ "pet_friendly": false,
127
+ "playground": false,
128
+ "recycling_center": false,
129
+ "swimming_pool": false,
130
+ "hot_tub": false,
131
+ "storage_available": false,
132
+ "tennis_court": false,
133
+ "wifi_available": false,
134
+ "other_community_amenities": "",
135
+ "primary_offering_other": null,
136
+ "ga_tracking_id": "",
137
+ "ga_profile_id": "",
138
+ "landmark_1_type": "",
139
+ "landmark_1_name": "",
140
+ "landmark_2_type": "",
141
+ "landmark_2_name": "",
142
+ "property_feature_1": "",
143
+ "property_feature_2": "",
144
+ "property_feature_3": "",
145
+ "apartment_amenity_1": "",
146
+ "apartment_amenity_2": "",
147
+ "community_amenity_1": "",
148
+ "community_amenity_2": "",
149
+ "amenities": [
150
+ {
151
+ "id": 1,
152
+ "name": "Covered Parking",
153
+ "icon": "fa fa-parking-interior",
154
+ "created_at": "2016-11-22T09:20:16.549-08:00",
155
+ "updated_at": "2016-11-22T09:20:16.549-08:00"
156
+ },
157
+ {
158
+ "id": 3,
159
+ "name": "WIFI",
160
+ "icon": "fa fa-wifi",
161
+ "created_at": "2016-11-22T09:20:16.578-08:00",
162
+ "updated_at": "2016-11-22T09:20:16.578-08:00"
163
+ }
164
+ ]
165
+ }
166
+ }
@@ -0,0 +1,98 @@
1
+ {
2
+ "location": {
3
+ "uid": "http://hub.g5dxm.com/clients/g5-c-1soj8m6e-g5-multifamily/locations/g5-cl-1soj9pe2-541-apartments",
4
+ "client_uid": "http://hub.g5dxm.com/clients/g5-c-1soj8m6e-g5-multifamily",
5
+ "client_urn": "g5-c-1soj8m6e-g5-multifamily",
6
+ "amenities": [
7
+ {
8
+ "id": 1,
9
+ "name": "WIFI",
10
+ "icon": "fa-wifi",
11
+ "created_at": "2016-12-07T15:06:47.500-08:00",
12
+ "updated_at": "2016-12-07T15:06:47.500-08:00"
13
+ },
14
+ {
15
+ "id": 7,
16
+ "name": "Power",
17
+ "icon": "fa-electric-outlet",
18
+ "created_at": "2016-12-07T15:09:33.391-08:00",
19
+ "updated_at": "2016-12-07T15:09:33.391-08:00"
20
+ }
21
+ ],
22
+ "created_at": "2014-08-13T17:30:32.413-07:00",
23
+ "updated_at": "2016-10-05T21:14:50.523-07:00",
24
+ "client_id": 22,
25
+ "name": "541 Apartments",
26
+ "internal_branded_name": null,
27
+ "custom_slug": "541-apartments",
28
+ "corporate": false,
29
+ "urn": "g5-cl-1soj9pe2-541-apartments",
30
+ "status": "Pending",
31
+ "home_page_url": "http://www.g5salesdemo3.com",
32
+ "street_address_1": "541 NW Bond St",
33
+ "street_address_2": "",
34
+ "country": "US",
35
+ "country_code": "1",
36
+ "city": "Bend",
37
+ "state": "OH",
38
+ "state_name": "Ohio",
39
+ "postal_code": "12345",
40
+ "website_page_prefix": "http://www.g5salesdemo3.com/apartments/oh/bend",
41
+ "service_1": null,
42
+ "service_2": null,
43
+ "service_3": null,
44
+ "service_4": null,
45
+ "service_5": null,
46
+ "fax": "",
47
+ "email": "",
48
+ "office_hours": "M-F 9-5",
49
+ "access_hours": null,
50
+ "twitter_username": "",
51
+ "facebook_username": "",
52
+ "yelp_username": "",
53
+ "pinterest_username": "",
54
+ "foursquare_username": "",
55
+ "linkedin_username": null,
56
+ "linkedin_account_type": null,
57
+ "tumblr_username": "",
58
+ "instagram_username": "",
59
+ "vimeo_username": "",
60
+ "youtube_username": "",
61
+ "domain": "http://www.g5salesdemo3.com",
62
+ "secure_domain": false,
63
+ "phone_number": "541-541-5413",
64
+ "local_phone_number": null,
65
+ "neighborhood": "",
66
+ "floor_plans": "Studio \u0026 2",
67
+ "nearby_schools": "COCC",
68
+ "nearby_employers": "Deschutes Brewery",
69
+ "ga_tracking_id": "",
70
+ "ga_profile_id": "",
71
+ "landmark_1_type": "Lake",
72
+ "landmark_1_name": "Crater Lake",
73
+ "landmark_2_type": "Military Base",
74
+ "landmark_2_name": "G5 Special Ops",
75
+ "property_feature_1": "Luxury",
76
+ "property_feature_2": "Furnished",
77
+ "property_feature_3": "Affordable",
78
+ "apartment_amenity_1": "Central Air \u0026 Heating",
79
+ "apartment_amenity_2": "Free WiFi",
80
+ "community_amenity_1": "Swimming Pool",
81
+ "community_amenity_2": "Roller Coaster",
82
+ "timezone": "America/New_York",
83
+ "latitude": 39.205226,
84
+ "longitude": -84.500929,
85
+ "go_squared_site_token": "",
86
+ "thumbnail_url_300px": "/images/original/missing.png",
87
+ "google_plus_id": null,
88
+ "neighborhood_2": null,
89
+ "verified_address": "unverified",
90
+ "gtm_codes": "GTM-KTND",
91
+ "spinup_web_theme": null,
92
+ "spinup_strategy": null,
93
+ "core_store_id": null,
94
+ "custom_vertical": null,
95
+ "off_platform": false,
96
+ "thumbnail_url": "/images/thumb/missing.png"
97
+ }
98
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "clients": [
3
+ {
4
+ "urn": "g5-c-iwcqdt3u-arenhall-management-company-client"
5
+ },
6
+ {
7
+ "urn": "g5-c-iw2fm3cx-artis-senior-living-management-multidomain"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe G5Updatable::AllClientUrnsFetcher do
4
+ let(:token) { 'a-token' }
5
+
6
+ describe '#fetch_uids' do
7
+ before do
8
+ allow(G5Updatable::Fetcher).to receive(:do_with_username_pw_access_token).and_yield(token)
9
+ stub_request(:get, 'https://g5-hub.herokuapp.com/urns.json?access_token=a-token').
10
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
11
+ to_return(status: status, body: fixture('urns.json'), headers: {})
12
+ end
13
+
14
+ subject { described_class.fetch_uids }
15
+
16
+ context 'success' do
17
+ let(:status) { 200 }
18
+
19
+ it do
20
+ is_expected.to eq(['https://g5-hub.herokuapp.com/clients/g5-c-iwcqdt3u-arenhall-management-company-client.json',
21
+ 'https://g5-hub.herokuapp.com/clients/g5-c-iw2fm3cx-artis-senior-living-management-multidomain.json'])
22
+ end
23
+ end
24
+
25
+ context '404' do
26
+ let(:status) { 404 }
27
+
28
+ it 'raises error' do
29
+ expect { subject }.to raise_error("Couldn't find record at URL 'https://g5-hub.herokuapp.com/urns.json'")
30
+ end
31
+ end
32
+
33
+ context '500' do
34
+ let(:status) { 500 }
35
+
36
+ it 'raises error' do
37
+ expect { subject }.to raise_error("I got an unexpected response code '500'")
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ describe '#hub_url' do
44
+ it 'returns the default hub url' do
45
+ expect(described_class.hub_url).to eq(G5Updatable::HUB_URL)
46
+ end
47
+
48
+ context 'with HUB_URL override' do
49
+ before { stub_const('G5Updatable::HUB_URL', 'http://whatever.com') }
50
+
51
+ it 'returns a custom URL if set' do
52
+ expect(described_class.hub_url).to eq('http://whatever.com')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,8 +1,11 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe G5Updatable::ClientFeedProcessor do
4
+ let(:token) { 'a-token' }
5
+
4
6
  describe ".new" do
5
- let(:processor) { described_class.new(passed_uid) }
7
+ let(:params) { {client_uid: passed_uid} }
8
+ let(:processor) { described_class.new params }
6
9
  subject(:client_uid) { processor.client_uid }
7
10
  let(:configured_client_uid) { nil }
8
11
 
@@ -40,46 +43,96 @@ describe G5Updatable::ClientFeedProcessor do
40
43
  end
41
44
  end
42
45
 
43
- describe "#work" do
44
- let(:client_updater) { double(update: nil) }
45
- let(:locations_updater) { double(update: nil) }
46
-
47
- let(:client) { G5FoundationClient::Client.new(uid: client_uid,
48
- urn: "urn",
49
- name: "Client Name",
50
- locations: [{uid: location_uid}]) }
51
- let(:client_uid) { "http://example.com/cilent_uid" }
52
- let(:location_uid) { "http://example.com/cilent_uid/locations/location_uid" }
53
-
46
+ describe '#load_all_clients' do
54
47
  before do
55
- stub_client_for_uid(client_uid, client)
56
- allow(G5Updatable::ClientUpdater).to receive(:new) { client_updater }
57
- allow(G5Updatable::LocationsUpdater).to receive(:new) { locations_updater }
58
- G5Updatable::ClientFeedProcessor.new(client_uid).work
59
- end
60
-
61
- it "updates with the found client" do
62
- expect(G5Updatable::ClientUpdater).to have_received(:new).with(client)
63
- expect(client_updater).to have_received(:update)
48
+ allow(G5Updatable::Fetcher).to receive(:do_with_username_pw_access_token).and_yield(token)
49
+ stub_request(:get, 'https://g5-hub.herokuapp.com/urns.json?access_token=a-token').
50
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
51
+ to_return(status: 200, body: fixture('urns.json'), headers: {})
64
52
  end
65
53
 
66
- it "updates with the client's associated locations" do
67
- expect(G5Updatable::LocationsUpdater).to have_received(:new).with(client)
68
- expect(locations_updater).to have_received(:update)
54
+ it 'loads each client' do
55
+ expect(G5Updatable::ClientFeedProcessor).to receive(:new).with(client_uid: 'https://g5-hub.herokuapp.com/clients/g5-c-iwcqdt3u-arenhall-management-company-client.json')
56
+ expect(G5Updatable::ClientFeedProcessor).to receive(:new).with(client_uid: 'https://g5-hub.herokuapp.com/clients/g5-c-iw2fm3cx-artis-senior-living-management-multidomain.json')
57
+ G5Updatable::ClientFeedProcessor.load_all_clients
69
58
  end
70
59
  end
71
60
 
72
- describe :load_all_clients do
73
- let(:clients_url) { 'http://g5-hub-clients-url' }
74
- let(:client_uids) { %w(uid-1 uid-2) }
75
- before do
76
- expect(G5FoundationClient::Client).to receive(:all_client_uids).with(clients_url).and_return(client_uids)
77
- expect(G5Updatable::ClientFeedProcessor).to receive(:new).with('uid-1').and_return(double(:work1, work: 'work-1'))
78
- expect(G5Updatable::ClientFeedProcessor).to receive(:new).with('uid-2').and_return(double(:work1, work: 'work-2'))
61
+ describe '#work', integration: true do
62
+ let(:client_uid) { 'http://hub.g5dxm.com/clients/g5-c-1soj8m6e-g5-multifamily' }
63
+ let(:location_uid) { 'http://hub.g5dxm.com/clients/g5-c-1soj8m6e-g5-multifamily/locations/g5-cl-1soj9pe2-541-apartments' }
64
+
65
+ context 'just client_uid' do
66
+ subject { described_class.new(client_uid: client_uid) }
67
+ before do
68
+ allow(G5Updatable::Fetcher).to receive(:do_with_username_pw_access_token).and_yield(token)
69
+ stub_request(:get, "#{client_uid}?access_token=#{token}").
70
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
71
+ to_return(status: 200, body: fixture('client-g5-c-1soj8m6e-g5-multifamily.json'), headers: {})
72
+ end
73
+
74
+ let(:created_client) { G5Updatable::Client.last }
75
+
76
+ it 'creates a client' do
77
+ expect { subject.work }.to change { G5Updatable::Client.count }.by(1)
78
+ expect(created_client.urn).to eq('g5-c-1soj8m6e-g5-multifamily')
79
+ end
80
+
81
+ it 'creates locations' do
82
+ expect { subject.work }.to change { G5Updatable::Location.count }.by(5)
83
+ expect(created_client.locations.collect(&:urn)).to match_array(%w(g5-cl-1soj9pe2-541-apartments g5-cl-1soja3fn-99-apartments g5-cl-560belmk8-denali g5-cl-i2xqm52t-mockup-design-3 g5-cl-i2gg3rv8-g5-apartments))
84
+ end
85
+
86
+ it 'creates amenities' do
87
+ expect { subject.work }.to change { G5Updatable::HubAmenity.count }.by(2)
88
+ expect(G5Updatable::HubAmenity.all.collect(&:name)).to match_array(['WIFI', 'Power'])
89
+ expect(G5Updatable::Location.find_by_urn('g5-cl-560belmk8-denali').hub_amenities.collect(&:name)).to match_array(['WIFI', 'Power'])
90
+ end
91
+
92
+ context 'subsequent update with missing locations' do
93
+ before do
94
+ subject.work
95
+ expect(created_client.locations.count).to eq(5)
96
+ stub_request(:get, "#{client_uid}?access_token=#{token}").
97
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
98
+ to_return(status: 200, body: fixture('client-g5-c-1soj8m6e-g5-multifamily-missing-locations.json'), headers: {})
99
+ end
100
+
101
+ it 'removes orphaned locations' do
102
+ expect { subject.work }.to change { created_client.locations.count }.from(5).to(1)
103
+ end
104
+ end
105
+
106
+ context 'subsequent update with NO locations' do
107
+ before do
108
+ subject.work
109
+ expect(created_client.locations.count).to eq(5)
110
+ stub_request(:get, "#{client_uid}?access_token=#{token}").
111
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
112
+ to_return(status: 200, body: fixture('client-g5-c-1soj8m6e-g5-multifamily-no-locations.json'), headers: {})
113
+ end
114
+
115
+ it 'removes orphaned locations' do
116
+ expect { subject.work }.to change { created_client.locations.count }.from(5).to(0)
117
+ end
118
+ end
79
119
  end
80
120
 
81
- it 'loads every client' do
82
- expect(G5Updatable::ClientFeedProcessor.load_all_clients(clients_url)).to eq(%w(work-1 work-2))
121
+ context 'with client and location uids' do
122
+ subject { described_class.new(client_uid: client_uid, location_uid: location_uid) }
123
+ before do
124
+ allow(G5Updatable::Fetcher).to receive(:do_with_username_pw_access_token).and_yield(token)
125
+ stub_request(:get, "#{location_uid}?access_token=#{token}").
126
+ with(:headers => {'Accept' => 'application/json', 'Content-Type' => 'application/json'}).
127
+ to_return(status: 200, body: fixture('location-g5-cl-1soj9pe2-541-apartments.json'), headers: {})
128
+ end
129
+
130
+ let(:created_location) { G5Updatable::Location.last }
131
+
132
+ it 'creates a location' do
133
+ expect { subject.work }.to change { G5Updatable::Location.count }.by(1)
134
+ expect(created_location.urn).to eq('g5-cl-1soj9pe2-541-apartments')
135
+ end
83
136
  end
84
137
  end
85
138
  end