flapjack-diner 1.4.0 → 2.0.0.a4

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/README.md +620 -413
  5. data/flapjack-diner.gemspec +1 -1
  6. data/lib/flapjack-diner/argument_validator.rb +77 -7
  7. data/lib/flapjack-diner/configuration.rb +409 -0
  8. data/lib/flapjack-diner/index_range.rb +42 -0
  9. data/lib/flapjack-diner/log_formatter.rb +22 -0
  10. data/lib/flapjack-diner/query.rb +114 -0
  11. data/lib/flapjack-diner/relationships.rb +180 -0
  12. data/lib/flapjack-diner/request.rb +280 -0
  13. data/lib/flapjack-diner/resources.rb +64 -0
  14. data/lib/flapjack-diner/response.rb +91 -0
  15. data/lib/flapjack-diner/tools.rb +47 -251
  16. data/lib/flapjack-diner/utility.rb +16 -0
  17. data/lib/flapjack-diner/version.rb +1 -1
  18. data/lib/flapjack-diner.rb +54 -20
  19. data/spec/argument_validator_spec.rb +87 -28
  20. data/spec/flapjack-diner_spec.rb +42 -64
  21. data/spec/relationships_spec.rb +211 -0
  22. data/spec/resources/checks_spec.rb +219 -79
  23. data/spec/resources/contacts_spec.rb +179 -151
  24. data/spec/resources/events_spec.rb +208 -0
  25. data/spec/resources/maintenance_periods_spec.rb +177 -565
  26. data/spec/resources/media_spec.rb +157 -171
  27. data/spec/resources/metrics_spec.rb +45 -0
  28. data/spec/resources/rules_spec.rb +278 -0
  29. data/spec/resources/states_spec.rb +93 -0
  30. data/spec/resources/statistics_spec.rb +53 -0
  31. data/spec/resources/tags_spec.rb +243 -0
  32. data/spec/spec_helper.rb +16 -0
  33. data/spec/support/fixture_data.rb +541 -0
  34. metadata +33 -31
  35. data/.rubocop.yml +0 -21
  36. data/.rubocop_todo.yml +0 -135
  37. data/lib/flapjack-diner/resources/checks.rb +0 -64
  38. data/lib/flapjack-diner/resources/contacts.rb +0 -70
  39. data/lib/flapjack-diner/resources/entities.rb +0 -68
  40. data/lib/flapjack-diner/resources/maintenance_periods.rb +0 -82
  41. data/lib/flapjack-diner/resources/media.rb +0 -61
  42. data/lib/flapjack-diner/resources/notification_rules.rb +0 -66
  43. data/lib/flapjack-diner/resources/notifications.rb +0 -28
  44. data/lib/flapjack-diner/resources/pagerduty_credentials.rb +0 -59
  45. data/lib/flapjack-diner/resources/reports.rb +0 -33
  46. data/spec/pacts/flapjack-diner-flapjack.json +0 -4515
  47. data/spec/resources/entities_spec.rb +0 -181
  48. data/spec/resources/notification_rules_spec.rb +0 -341
  49. data/spec/resources/notifications_spec.rb +0 -208
  50. data/spec/resources/pagerduty_credentials_spec.rb +0 -237
  51. data/spec/resources/reports_spec.rb +0 -255
@@ -6,88 +6,143 @@ describe Flapjack::ArgumentValidator do
6
6
  context 'required' do
7
7
 
8
8
  let(:query) do
9
- {:entity => 'myservice', :check => 'HOST'}
9
+ {:name => 'HOST', :enabled => false}
10
10
  end
11
11
 
12
12
  subject { Flapjack::ArgumentValidator.new(query) }
13
13
 
14
- it 'does not raise an exception when query entity is valid' do
15
- expect { subject.validate(:query => :entity, :as => :required) }.not_to raise_exception
14
+ it 'does not raise an error when query entity is valid' do
15
+ expect {
16
+ subject.validate(:query => :name, :as => :required)
17
+ }.not_to raise_error
16
18
  end
17
19
 
18
20
  it 'raises ArgumentError when query entity is invalid' do
19
- query[:entity] = nil
20
- expect { subject.validate(:query => :entity, :as => :required) }.to raise_exception
21
+ query[:name] = nil
22
+ expect {
23
+ subject.validate(:query => :name, :as => :required)
24
+ }.to raise_error(ArgumentError)
21
25
  end
22
26
 
23
27
  it 'handles arrays as query values valid' do
24
- expect { subject.validate(:query => [:entity, :check], :as => :required) }.not_to raise_exception
28
+ expect {
29
+ subject.validate(:query => [:name, :enabled], :as => :required)
30
+ }.not_to raise_error
25
31
  end
26
32
 
27
33
  it 'handles arrays as query values invalid' do
28
- query[:check] = nil
29
- expect { subject.validate(:query => [:entity, :check], :as => :required) }.to raise_exception
34
+ query[:name] = nil
35
+ expect {
36
+ subject.validate(:query => [:name, :enabled], :as => :required)
37
+ }.to raise_error(ArgumentError)
30
38
  end
31
39
  end
32
40
 
33
41
  context 'time' do
34
42
 
35
43
  let(:query) do
36
- {:start_time => Time.now, :duration => 10}
44
+ {:start_time => Time.now}
37
45
  end
38
46
 
39
47
  subject { Flapjack::ArgumentValidator.new(query) }
40
48
 
41
- it 'does not raise an exception when query start_time is valid' do
42
- expect { subject.validate(:query => :start_time, :as => :time) }.not_to raise_exception
49
+ it 'does not raise an error when query start_time is valid' do
50
+ expect {
51
+ subject.validate(:query => :start_time, :as => :time)
52
+ }.not_to raise_error
43
53
  end
44
54
 
45
- it 'raises an exception when query start_time is invalid' do
55
+ it 'raises an error when query start_time is invalid' do
46
56
  query[:start_time] = 1234
47
- expect { subject.validate(:query => :start_time, :as => :time) }.to raise_exception
57
+ expect {
58
+ subject.validate(:query => :start_time, :as => :time)
59
+ }.to raise_error(ArgumentError)
48
60
  end
49
61
 
50
62
  it 'handles arrays as query values valid' do
51
63
  query[:end_time] = Time.now
52
- expect { subject.validate(:query => [:start_time, :end_time], :as => :time) }.not_to raise_exception
64
+ expect {
65
+ subject.validate(:query => [:start_time, :end_time], :as => :time)
66
+ }.not_to raise_error
53
67
  end
54
68
 
55
69
  it 'handles arrays as query values invalid' do
56
70
  query[:end_time] = 3904
57
- expect { subject.validate(:query => [:start_time, :end_time], :as => :time) }.to raise_exception
71
+ expect {
72
+ subject.validate(:query => [:start_time, :end_time], :as => :time)
73
+ }.to raise_error(ArgumentError)
58
74
  end
59
75
 
60
76
  it 'handles dates as query values' do
61
77
  query[:end_time] = Date.today
62
- expect { subject.validate(:query => :end_time, :as => :time) }.not_to raise_exception
78
+ expect {
79
+ subject.validate(:query => :end_time, :as => :time)
80
+ }.not_to raise_error
63
81
  end
64
82
 
65
83
  it 'handles ISO 8601 strings as query values' do
66
84
  query[:end_time] = Time.now.iso8601
67
- expect { subject.validate(:query => :end_time, :as => :time) }.not_to raise_exception
85
+ expect {
86
+ subject.validate(:query => :end_time, :as => :time)
87
+ }.not_to raise_error
68
88
  end
69
89
 
70
- it 'raises an exception when invalid time strings are provided' do
90
+ it 'raises an error when invalid time strings are provided' do
71
91
  query[:end_time] = '2011-08-01T00:00'
72
- expect { subject.validate(:query => :end_time, :as => :time) }.to raise_exception
92
+ expect {
93
+ subject.validate(:query => :end_time, :as => :time)
94
+ }.to raise_error(ArgumentError)
73
95
  end
74
96
  end
75
97
 
76
98
  context 'integer via method missing' do
77
99
 
78
100
  let(:query) do
79
- {:start_time => Time.now, :duration => 10}
101
+ {:duration => 10}
80
102
  end
81
103
 
82
104
  subject { Flapjack::ArgumentValidator.new(query) }
83
105
 
84
- it 'does not raise an exception when query duration is valid' do
85
- expect { subject.validate(:query => :duration, :as => :integer) }.not_to raise_exception
106
+ it 'does not raise an error when query duration is valid' do
107
+ expect {
108
+ subject.validate(:query => :duration, :as => :integer)
109
+ }.not_to raise_error
86
110
  end
87
111
 
88
- it 'raises an exception when query duration is invalid' do
112
+ it 'raises an error when query duration is invalid' do
89
113
  query[:duration] = '23'
90
- expect { subject.validate(:query => :duration, :as => :integer) }.to raise_exception
114
+ expect {
115
+ subject.validate(:query => :duration, :as => :integer)
116
+ }.to raise_error(ArgumentError)
117
+ end
118
+ end
119
+
120
+ context 'string via method missing' do
121
+
122
+ let(:query) do
123
+ {:name => 'Herbert'}
124
+ end
125
+
126
+ subject { Flapjack::ArgumentValidator.new(query) }
127
+
128
+ it 'does not raise an error when query name is valid' do
129
+ expect {
130
+ subject.validate(:query => :name, :as => :non_empty_string)
131
+ }.not_to raise_error
132
+ end
133
+
134
+ it 'raises an error when query name is empty' do
135
+ query[:name] = ''
136
+ expect {
137
+ subject.validate(:query => :name, :as => :non_empty_string)
138
+ }.to raise_error(ArgumentError)
139
+ end
140
+
141
+ it 'raises an error when query name is invalid' do
142
+ query[:name] = 23
143
+ expect {
144
+ subject.validate(:query => :name, :as => :non_empty_string)
145
+ }.to raise_error(ArgumentError)
91
146
  end
92
147
  end
93
148
 
@@ -99,13 +154,17 @@ describe Flapjack::ArgumentValidator do
99
154
 
100
155
  subject { Flapjack::ArgumentValidator.new(query) }
101
156
 
102
- it 'does not raise an exception when query start_time is valid' do
103
- expect { subject.validate(:query => :start_time, :as => [:time, :required]) }.not_to raise_exception
157
+ it 'does not raise an error when query start_time is valid' do
158
+ expect {
159
+ subject.validate(:query => :start_time, :as => [:time, :required])
160
+ }.not_to raise_error
104
161
  end
105
162
 
106
- it 'raises an exception when query start_time is invalid' do
163
+ it 'raises an error when query start_time is invalid' do
107
164
  query[:start_time] = nil
108
- expect { subject.validate(:query => :start_time, :as => [:time, :required]) }.to raise_exception
165
+ expect {
166
+ subject.validate(:query => :start_time, :as => [:time, :required])
167
+ }.to raise_error(ArgumentError)
109
168
  end
110
169
  end
111
170
  end
@@ -7,10 +7,6 @@ describe Flapjack::Diner do
7
7
 
8
8
  let(:time) { Time.now }
9
9
 
10
- def response_with_data(name, data = [])
11
- "{\"#{name}\":#{data.to_json}}"
12
- end
13
-
14
10
  before(:each) do
15
11
  Flapjack::Diner.base_uri(server)
16
12
  Flapjack::Diner.logger = nil
@@ -20,9 +16,9 @@ describe Flapjack::Diner do
20
16
  WebMock.reset!
21
17
  end
22
18
 
23
- context 'argument parsing' do
19
+ # context 'argument parsing' do
24
20
 
25
- end
21
+ # end
26
22
 
27
23
  context 'keys as strings' do
28
24
 
@@ -35,32 +31,16 @@ describe Flapjack::Diner do
35
31
  end
36
32
 
37
33
  it 'can return keys as strings' do
38
- data = [{
39
- :id => '21',
40
- :first_name => 'Ada',
41
- :last_name => 'Lovelace',
42
- :email => 'ada@example.com',
43
- :timezone => 'Europe/London',
44
- :tags => [ 'legend', 'first computer programmer' ],
45
- :links => {
46
- :entities => ['7', '12', '83'],
47
- :media => ['21_email', '21_sms'],
48
- :notification_rules => ['30fd36ae-3922-4957-ae3e-c8f6dd27e543']
49
- }
50
- }]
51
-
52
34
  req = stub_request(:get, "http://#{server}/contacts").to_return(
53
- :status => 200, :body => response_with_data('contacts', data))
35
+ :status => 200, :body => {:data => [contact_data]}.to_json)
54
36
 
55
37
  result = Flapjack::Diner.contacts
56
38
  expect(req).to have_been_requested
57
39
  expect(result).not_to be_nil
58
40
  expect(result).to be_an_instance_of(Array)
59
41
  expect(result.length).to be(1)
60
- expect(result[0]).to be_an_instance_of(Hash)
61
- expect(result[0]).to have_key('id')
62
- expect(result[0]).to have_key('links')
63
- expect(result[0]['links']).to have_key('entities')
42
+ expect(result.first).to be_an_instance_of(Hash)
43
+ expect(result.first).to have_key('id')
64
44
  end
65
45
 
66
46
  end
@@ -73,65 +53,70 @@ describe Flapjack::Diner do
73
53
  Flapjack::Diner.logger = logger
74
54
  end
75
55
 
76
- it 'logs a GET request without a path' do
77
- response = response_with_data('entities')
78
- req = stub_request(:get, "http://#{server}/entities").
56
+ it "logs a GET request without a path" do
57
+ response = {:data => [contact_data]}.to_json
58
+ req = stub_request(:get, "http://#{server}/contacts").
79
59
  to_return(:body => response)
80
60
 
81
- expect(logger).to receive(:info).with("GET http://#{server}/entities")
82
- expect(logger).to receive(:info).with(' Response Code: 200')
83
- expect(logger).to receive(:info).with(" Response Body: #{response}")
61
+ expect(logger).to receive(:info).with(%r{\[Flapjack::Diner\] \[[^\]]+\] 200 "GET /contacts" - $})
84
62
 
85
- result = Flapjack::Diner.entities
63
+ result = Flapjack::Diner.contacts
86
64
  expect(req).to have_been_requested
87
65
  expect(result).not_to be_nil
88
66
  end
89
67
 
90
68
  it "logs a POST request" do
91
- req = stub_request(:post, "http://#{server}/test_notifications/entities/27").
92
- to_return(:status => 204)
93
- expect(logger).to receive(:info).with("POST http://#{server}/test_notifications/entities/27\n" +
94
- " Body: {:test_notifications=>[{:summary=>\"dealing with it\"}]}")
95
- expect(logger).to receive(:info).with(' Response Code: 204')
69
+ req_data = test_notification_json(test_notification_data).merge(
70
+ :relationships => {
71
+ :check => {
72
+ :data => {:type => 'check', :id => check_data[:id]}
73
+ }
74
+ }
75
+ )
76
+ resp_data = test_notification_json(test_notification_data)
77
+
78
+ response = {:data => resp_data}.to_json
79
+ req = stub_request(:post, "http://#{server}/test_notifications").
80
+ to_return(:status => 201, :body => response)
96
81
 
97
- result = Flapjack::Diner.create_test_notifications_entities(27, [{:summary => 'dealing with it'}])
82
+ expect(logger).to receive(:info).with(%r{\[Flapjack::Diner\] \[[^\]]+\] 201 "POST /test_notifications" - $})
83
+
84
+ result = Flapjack::Diner.create_test_notifications(test_notification_data.merge(:check => check_data[:id]))
98
85
  expect(req).to have_been_requested
99
- expect(result).to be_truthy
86
+ expect(result).to eq(resultify(resp_data))
100
87
  end
101
88
 
102
89
  it "logs a DELETE request" do
103
- req = stub_request(:delete, "http://#{server}/scheduled_maintenances/checks/example.com%3ASSH").
104
- with(:query => {:start_time => time.iso8601}).
90
+ req = stub_request(:delete, "http://#{server}/scheduled_maintenances/#{scheduled_maintenance_data[:id]}").
105
91
  to_return(:status => 204)
106
92
 
107
- expect(logger).to receive(:info).with("DELETE http://#{server}/scheduled_maintenances/checks/example.com:SSH?start_time=#{URI.encode_www_form_component(time.iso8601)}")
108
- expect(logger).to receive(:info).with(" Response Code: 204")
93
+ expect(logger).to receive(:info).
94
+ with(%r{\[Flapjack::Diner\] \[[^\]]+\] 204 "DELETE /scheduled_maintenances/#{scheduled_maintenance_data[:id]}" - $})
109
95
 
110
- result = Flapjack::Diner.delete_scheduled_maintenances_checks('example.com:SSH', :start_time => time)
96
+ result = Flapjack::Diner.delete_scheduled_maintenances(scheduled_maintenance_data[:id])
111
97
  expect(req).to have_been_requested
112
- expect(result).to be_truthy
98
+ expect(result).to be_a(TrueClass)
113
99
  end
114
100
 
115
101
  end
116
102
 
117
103
  context "problems" do
118
-
119
104
  it "raises an exception on network failure" do
120
- req = stub_request(:get, "http://#{server}/entities").to_timeout
105
+ req = stub_request(:get, "http://#{server}/contacts").to_timeout
121
106
 
122
107
  expect {
123
- Flapjack::Diner.entities
124
- }.to raise_error
108
+ Flapjack::Diner.contacts
109
+ }.to raise_error(Timeout::Error)
125
110
  expect(req).to have_been_requested
126
111
  end
127
112
 
128
113
  it "raises an exception on invalid JSON data" do
129
- req = stub_request(:get, "http://#{server}/entities").to_return(
114
+ req = stub_request(:get, "http://#{server}/contacts").to_return(
130
115
  :body => "{")
131
116
 
132
117
  expect {
133
- Flapjack::Diner.entities
134
- }.to raise_error
118
+ Flapjack::Diner.contacts
119
+ }.to raise_error(JSON::ParserError)
135
120
  expect(req).to have_been_requested
136
121
  end
137
122
 
@@ -139,26 +124,19 @@ describe Flapjack::Diner do
139
124
  req = stub_request(:get, /http:\/\/#{server}\/*/)
140
125
 
141
126
  expect {
142
- Flapjack::Diner.delete_scheduled_maintenances_checks('example.com:SSH', :start_time => nil)
143
- }.to raise_error
127
+ Flapjack::Diner.create_scheduled_maintenances
128
+ }.to raise_error(ArgumentError)
144
129
  expect(req).not_to have_been_requested
145
130
  end
146
131
 
147
132
  it "raises an exception if a time argument is provided with the wrong data type" do
148
- start_str = '2011-08-01T00:00:00+10:00'
149
- finish_str = 'yesterday'
150
-
151
- start = Time.iso8601(start_str)
152
-
153
133
  req = stub_request(:get, /http:\/\/#{server}\/*/)
154
134
 
155
135
  expect {
156
- Flapjack::Diner.downtime_report_checks('example.com:SSH',
157
- :start_time => start_time, :end_time => end_time)
158
- }.to raise_error
136
+ Flapjack::Diner.create_scheduled_maintenances(:start_time => Time.now,
137
+ :end_time => 'tomorrow')
138
+ }.to raise_error(ArgumentError)
159
139
  expect(req).not_to have_been_requested
160
140
  end
161
-
162
141
  end
163
-
164
142
  end
@@ -0,0 +1,211 @@
1
+ require 'spec_helper'
2
+ require 'flapjack-diner'
3
+
4
+ describe Flapjack::Diner::Relationships, :pact => true do
5
+
6
+ before(:each) do
7
+ Flapjack::Diner.base_uri('localhost:19081')
8
+ Flapjack::Diner.logger = nil
9
+ end
10
+
11
+ it 'adds a tag to a check' do
12
+ flapjack.given("a check and a tag exist").
13
+ upon_receiving("a POST request adding a tag to a check").
14
+ with(:method => :post, :path => "/checks/#{check_data[:id]}/relationships/tags",
15
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
16
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}]}).
17
+ will_respond_with(:status => 204,
18
+ :body => '')
19
+
20
+ result = Flapjack::Diner.create_check_link_tags(check_data[:id], tag_data[:id])
21
+ expect(result).to be true
22
+ end
23
+
24
+ it 'adds two tags to a check' do
25
+ flapjack.given("a check and two tags exist").
26
+ upon_receiving("a POST request adding two tags to a check").
27
+ with(:method => :post, :path => "/checks/#{check_data[:id]}/relationships/tags",
28
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
29
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'},
30
+ {:id => tag_2_data[:id], :type => 'tag'}]}).
31
+ will_respond_with(:status => 204,
32
+ :body => '')
33
+
34
+ result = Flapjack::Diner.create_check_link_tags(check_data[:id],
35
+ tag_data[:id], tag_2_data[:id])
36
+ expect(result).to be true
37
+ end
38
+
39
+ it 'gets tags for a check' do
40
+ flapjack.given("a check with a tag exists").
41
+ upon_receiving("a GET request for all tags on a check").
42
+ with(:method => :get, :path => "/checks/#{check_data[:id]}/tags").
43
+ will_respond_with(
44
+ :status => 200,
45
+ :headers => {'Content-Type' => 'application/vnd.api+json; supported-ext=bulk; charset=utf-8'},
46
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}]})
47
+
48
+ result = Flapjack::Diner.check_link_tags(check_data[:id])
49
+ expect(result).to eq([{:id => tag_data[:id], :type => 'tag'}])
50
+ end
51
+
52
+ it 'gets tags for a check with full tag records' do
53
+ included_data = [
54
+ tag_json(tag_data)
55
+ ]
56
+
57
+ flapjack.given("a check with a tag exists").
58
+ upon_receiving("a GET request for all tags on a check, with full tag records").
59
+ with(:method => :get,
60
+ :path => "/checks/#{check_data[:id]}/tags",
61
+ :query => "include=tags").
62
+ will_respond_with(
63
+ :status => 200,
64
+ :headers => {'Content-Type' => 'application/vnd.api+json; supported-ext=bulk; charset=utf-8'},
65
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}],
66
+ :included => included_data})
67
+
68
+ result = Flapjack::Diner.check_link_tags(check_data[:id], :include => 'tags')
69
+ expect(result).to eq([{:id => tag_data[:id], :type => 'tag'}])
70
+ expect(Flapjack::Diner.context[:included]).to eq('tag' => {tag_data[:id] => resultify(included_data[0])})
71
+ end
72
+
73
+ it 'gets tags for a check with full tag and rule record' do
74
+ included_data = [
75
+ tag_json(tag_data),
76
+ rule_json(rule_data)
77
+ ]
78
+
79
+ flapjack.given("a check with a tag and a rule exists").
80
+ upon_receiving("a GET request for all tags on a check, with full tag and rule records").
81
+ with(:method => :get,
82
+ :path => "/checks/#{check_data[:id]}/tags",
83
+ :query => 'include=tags.rules').
84
+ will_respond_with(
85
+ :status => 200,
86
+ :headers => {'Content-Type' => 'application/vnd.api+json; supported-ext=bulk; charset=utf-8'},
87
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}],
88
+ :included => included_data})
89
+
90
+ result = Flapjack::Diner.check_link_tags(check_data[:id], :include => 'rules')
91
+ expect(result).to eq([{:id => tag_data[:id], :type => 'tag'}])
92
+ expect(Flapjack::Diner.context[:included]).to eq(
93
+ 'tag' => {tag_data[:id] => resultify(included_data[0])},
94
+ 'rule' => {rule_data[:id] => resultify(included_data[1])}
95
+ )
96
+ end
97
+
98
+ it 'updates tags for a check' do
99
+ flapjack.given("a check and a tag exist").
100
+ upon_receiving("a PATCH request updating tags for a check").
101
+ with(:method => :patch, :path => "/checks/#{check_data[:id]}/relationships/tags",
102
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
103
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}]}).
104
+ will_respond_with(:status => 204,
105
+ :body => '')
106
+
107
+ result = Flapjack::Diner.update_check_link_tags(check_data[:id],
108
+ tag_data[:id])
109
+ expect(result).to be true
110
+ end
111
+
112
+ it 'clears all tags from a check' do
113
+ flapjack.given("a check and a tag exist").
114
+ upon_receiving("a PATCH request clearing tags for a check").
115
+ with(:method => :patch, :path => "/checks/#{check_data[:id]}/relationships/tags",
116
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
117
+ :body => {:data => []}).
118
+ will_respond_with(:status => 204,
119
+ :body => '')
120
+
121
+ result = Flapjack::Diner.update_check_link_tags(check_data[:id], [])
122
+ expect(result).to be true
123
+ end
124
+
125
+ it 'deletes a tag from a check' do
126
+ flapjack.given("a check with a tag exists").
127
+ upon_receiving("a DELETE request deleting a tag from a check").
128
+ with(:method => :delete, :path => "/checks/#{check_data[:id]}/relationships/tags",
129
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
130
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'}]}).
131
+ will_respond_with(:status => 204,
132
+ :body => '')
133
+
134
+ result = Flapjack::Diner.delete_check_link_tags(check_data[:id],
135
+ tag_data[:id])
136
+ expect(result).to be true
137
+ end
138
+
139
+ it 'deletes two tags from a check' do
140
+ flapjack.given("a check with two tags exists").
141
+ upon_receiving("a DELETE request deleting two tags from a check").
142
+ with(:method => :delete, :path => "/checks/#{check_data[:id]}/relationships/tags",
143
+ :headers => {'Content-Type' => 'application/vnd.api+json'},
144
+ :body => {:data => [{:id => tag_data[:id], :type => 'tag'},
145
+ {:id => tag_2_data[:id], :type => 'tag'}]}).
146
+ will_respond_with(:status => 204,
147
+ :body => '')
148
+
149
+ result = Flapjack::Diner.delete_check_link_tags(check_data[:id],
150
+ tag_data[:id], tag_2_data[:id])
151
+ expect(result).to be true
152
+ end
153
+
154
+ it 'gets the contact for a medium' do
155
+ flapjack.given("a contact with a medium exists").
156
+ upon_receiving("a GET request for a medium's contact").
157
+ with(:method => :get, :path => "/media/#{email_data[:id]}/contact").
158
+ will_respond_with(
159
+ :status => 200,
160
+ :headers => {'Content-Type' => 'application/vnd.api+json; supported-ext=bulk; charset=utf-8'},
161
+ :body => {:data => {:id => contact_data[:id], :type => 'contact'}})
162
+
163
+ result = Flapjack::Diner.medium_link_contact(email_data[:id])
164
+ expect(result).to eq(:id => contact_data[:id], :type => 'contact')
165
+ end
166
+
167
+ it "doesn't duplicate linked data references in included data" do
168
+ resp_check = check_json(check_data)
169
+ resp_check[:relationships] = {
170
+ :current_state => {
171
+ :data => {:type => 'state', :id => state_data[:id]}
172
+ },
173
+ :latest_notifications => {
174
+ :data => [{:type => 'state', :id => state_data[:id]}]
175
+ }
176
+ }
177
+
178
+ sd = state_data.delete_if {|k, _| [:created_at, :updated_at].include?(k)}
179
+
180
+ included_data = [
181
+ resp_check,
182
+ state_json(sd)
183
+ ]
184
+
185
+ flapjack.given("a check with a tag, current state and a latest notification exists").
186
+ upon_receiving("a GET request for a check (via tag)'s state and notifications").
187
+ with(:method => :get,
188
+ :path => "/tags/#{tag_data[:id]}/checks",
189
+ :query => 'include=checks.current_state%2Cchecks.latest_notifications').
190
+ will_respond_with(
191
+ :status => 200,
192
+ :headers => {'Content-Type' => 'application/vnd.api+json; supported-ext=bulk; charset=utf-8'},
193
+ :body => {
194
+ :data => [
195
+ {:id => check_data[:id], :type => 'check'},
196
+ ],
197
+ :included => included_data
198
+ })
199
+
200
+ result = Flapjack::Diner.tag_link_checks(tag_data[:id],
201
+ :include => ['checks.current_state', 'checks.latest_notifications'])
202
+ expect(result).to eq([
203
+ {:id => check_data[:id], :type => 'check'}
204
+ ])
205
+ expect(Flapjack::Diner.context[:included]).to eq(
206
+ 'check' => {check_data[:id] => resultify(resp_check)},
207
+ 'state' => {sd[:id] => resultify(state_json(sd))}
208
+ )
209
+ end
210
+
211
+ end