ama_layout 5.12.0 → 6.3.0.pre
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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/ama_layout.gemspec +20 -21
- data/app/assets/javascripts/ama_layout/desktop/foundation-custom.js +8 -10
- data/app/assets/javascripts/ama_layout/desktop/index.js +0 -1
- data/app/helpers/ama_layout_path_helper.rb +5 -5
- data/app/views/ama_layout/_siteheader.html.erb +3 -8
- data/lib/ama_layout.rb +20 -28
- data/lib/ama_layout/decorators/moneris_decorator.rb +2 -3
- data/lib/ama_layout/decorators/navigation_decorator.rb +6 -52
- data/lib/ama_layout/decorators/navigation_item_decorator.rb +2 -3
- data/lib/ama_layout/moneris.rb +1 -4
- data/lib/ama_layout/navigation.rb +1 -7
- data/lib/ama_layout/navigation.yml +6 -58
- data/lib/ama_layout/navigation_item.rb +1 -4
- data/lib/ama_layout/version.rb +1 -1
- data/spec/ama_layout/decorators/navigation_decorator_spec.rb +8 -124
- data/spec/ama_layout/decorators/navigation_item_decorator_spec.rb +4 -2
- data/spec/ama_layout/navigation_spec.rb +43 -13
- data/spec/helpers/ama_layout_path_helper_spec.rb +6 -6
- data/spec/internal/app/controllers/application_controller.rb +0 -21
- data/spec/internal/config/routes.rb +0 -1
- data/spec/spec_helper.rb +16 -9
- data/styles.scss +0 -0
- metadata +41 -79
- data/PULL_REQUEST_TEMPLATE.md +0 -10
- data/app/assets/javascripts/ama_layout/notifications.coffee +0 -17
- data/app/controllers/ama_layout/api/v1/notifications_controller.rb +0 -18
- data/app/views/ama_layout/_notification.html.erb +0 -10
- data/app/views/ama_layout/_notification_sidebar.html.erb +0 -22
- data/app/views/ama_layout/_notifications.html.erb +0 -6
- data/app/views/ama_layout/_sign_out_link.html.erb +0 -3
- data/config/routes.rb +0 -9
- data/lib/ama_layout/decorators/notification_decorator.rb +0 -46
- data/lib/ama_layout/draper_replacement.rb +0 -27
- data/lib/ama_layout/navigation_helper.rb +0 -31
- data/lib/ama_layout/notification.rb +0 -87
- data/lib/ama_layout/notification_scrubber.rb +0 -13
- data/lib/ama_layout/notification_set.rb +0 -140
- data/lib/ama_layout/notifications.rb +0 -73
- data/lib/ama_layout/notifications/abstract_store.rb +0 -17
- data/lib/ama_layout/notifications/redis_store.rb +0 -38
- data/spec/ama_layout/controllers/ama_layout/api/v1/notifications_controller_spec.rb +0 -13
- data/spec/ama_layout/decorators/notification_decorator_spec.rb +0 -57
- data/spec/ama_layout/navigation_helper_spec.rb +0 -63
- data/spec/ama_layout/notification_scrubber_spec.rb +0 -10
- data/spec/ama_layout/notification_set_spec.rb +0 -281
- data/spec/ama_layout/notification_spec.rb +0 -193
- data/spec/ama_layout/notifications/abstract_store_spec.rb +0 -23
- data/spec/ama_layout/notifications/redis_store_spec.rb +0 -94
- data/spec/ama_layout/notifications_spec.rb +0 -109
- data/spec/factories/users.rb +0 -35
- data/spec/support/shared_examples/member_navigation.rb +0 -105
@@ -1,73 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
# Usage:
|
3
|
-
#
|
4
|
-
# class MyClass
|
5
|
-
# include AmaLayout::Notifications
|
6
|
-
#
|
7
|
-
# notification_store AmaLayout::Notifications::RedisStore.new(options)
|
8
|
-
# notification_foreign_key :a_method_name_or_proc # defaults to :id
|
9
|
-
#
|
10
|
-
# ...
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
module Notifications
|
14
|
-
InvalidNotificationStore = Class.new(StandardError)
|
15
|
-
|
16
|
-
def self.included(base)
|
17
|
-
base.extend(ClassMethods)
|
18
|
-
base.include(InstanceMethods)
|
19
|
-
end
|
20
|
-
|
21
|
-
module InstanceMethods
|
22
|
-
def notifications
|
23
|
-
@notifications ||= NotificationSet.new(_store, _foreign_key)
|
24
|
-
end
|
25
|
-
|
26
|
-
def notifications=(other)
|
27
|
-
@notifications = other
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def _store
|
33
|
-
self.class._notification_store || invalid_store!
|
34
|
-
end
|
35
|
-
|
36
|
-
def _foreign_key
|
37
|
-
self.class._notification_foreign_key.call(self)
|
38
|
-
end
|
39
|
-
|
40
|
-
def invalid_store!
|
41
|
-
raise InvalidNotificationStore, 'a notification store must be specified'
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
module ClassMethods
|
46
|
-
def notification_store(store)
|
47
|
-
self._notification_store = store
|
48
|
-
end
|
49
|
-
|
50
|
-
def notification_foreign_key(key)
|
51
|
-
self._notification_foreign_key = key
|
52
|
-
end
|
53
|
-
|
54
|
-
def _notification_foreign_key
|
55
|
-
@_notification_foreign_key || Proc.new(&:id)
|
56
|
-
end
|
57
|
-
|
58
|
-
def _notification_store
|
59
|
-
@_notification_store
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def _notification_store=(store)
|
65
|
-
@_notification_store = store
|
66
|
-
end
|
67
|
-
|
68
|
-
def _notification_foreign_key=(key)
|
69
|
-
@_notification_foreign_key = key.to_proc
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
module Notifications
|
3
|
-
class AbstractStore
|
4
|
-
def get(key, opts = {})
|
5
|
-
raise NotImplementedError, 'you must define a #get method in a subclass'
|
6
|
-
end
|
7
|
-
|
8
|
-
def set(key, value, opts = {})
|
9
|
-
raise NotImplementedError, 'you must define a #set method in a subclass'
|
10
|
-
end
|
11
|
-
|
12
|
-
def delete(key, opts = {})
|
13
|
-
raise NotImplementedError, 'you must define a #delete method in a subclass'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module AmaLayout
|
2
|
-
module Notifications
|
3
|
-
class RedisStore < AbstractStore
|
4
|
-
delegate :clear, to: :base
|
5
|
-
|
6
|
-
attr_accessor :base
|
7
|
-
|
8
|
-
def initialize(opts = {})
|
9
|
-
self.base = ActiveSupport::Cache.lookup_store(
|
10
|
-
:redis_store,
|
11
|
-
opts.merge(raw: true)
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
def get(key, opts = {})
|
16
|
-
if opts.fetch(:default, false)
|
17
|
-
base.fetch(key) { opts[:default] }
|
18
|
-
else
|
19
|
-
base.read(key)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def set(key, value, opts = {})
|
24
|
-
base.write(key, value, opts) == 'OK'
|
25
|
-
end
|
26
|
-
|
27
|
-
def delete(key, opts = {})
|
28
|
-
base.delete(key, opts) == 1
|
29
|
-
end
|
30
|
-
|
31
|
-
def transaction
|
32
|
-
base.data.multi do
|
33
|
-
yield self
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
describe AmaLayout::Api::V1::NotificationsController, type: :controller do
|
2
|
-
describe 'DELETE api/v1/notifications' do
|
3
|
-
routes { AmaLayout::Engine.routes }
|
4
|
-
|
5
|
-
before(:each) do
|
6
|
-
delete :dismiss_all
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'returns a 204 No Content status' do
|
10
|
-
expect(response).to have_http_status(:no_content)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
describe AmaLayout::NotificationDecorator do
|
2
|
-
let(:notification) do
|
3
|
-
AmaLayout::Notification.new(
|
4
|
-
header: 'test',
|
5
|
-
content: 'content',
|
6
|
-
type: :warning,
|
7
|
-
created_at: Date.yesterday.beginning_of_day,
|
8
|
-
active: true
|
9
|
-
)
|
10
|
-
end
|
11
|
-
subject { described_class.new(notification) }
|
12
|
-
|
13
|
-
describe '#created_at' do
|
14
|
-
around(:each) do |example|
|
15
|
-
Timecop.freeze(Time.zone.local(2017, 8)) do
|
16
|
-
example.run
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'returns the time elapsed in english words' do
|
21
|
-
expect(subject.created_at).to eq('1 day ago')
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#icon' do
|
26
|
-
it 'returns a div' do
|
27
|
-
expect(subject.icon).to include('<div')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'contains the proper icon class' do
|
31
|
-
expect(subject.icon).to include('fa-exclamation')
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'contains the proper colour class' do
|
35
|
-
expect(subject.icon).to include('right-sidebar__content-icon--orange')
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#active_class' do
|
40
|
-
context 'when active' do
|
41
|
-
it 'returns the proper class' do
|
42
|
-
expect(subject.active_class).to_not include('inactive')
|
43
|
-
expect(subject.active_class).to include('active')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'when inactive' do
|
48
|
-
before(:each) do
|
49
|
-
notification.dismiss!
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'returns the proper class' do
|
53
|
-
expect(subject.active_class).to include('inactive')
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
describe AmaLayout::NavigationHelper do
|
2
|
-
subject { FactoryGirl.create(:user) }
|
3
|
-
|
4
|
-
describe '#navigation' do
|
5
|
-
before(:each) do
|
6
|
-
subject.class.include(AmaLayout::NavigationHelper).new
|
7
|
-
end
|
8
|
-
|
9
|
-
context 'non-member' do
|
10
|
-
subject { FactoryGirl.create(:user, :non_member) }
|
11
|
-
|
12
|
-
it 'shows non-member sidebar menu' do
|
13
|
-
expect(subject.navigation).to eq 'non-member'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'member' do
|
18
|
-
it 'shows member sidebar menu' do
|
19
|
-
expect(subject.navigation).to eq 'member'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'member with accr' do
|
24
|
-
subject { FactoryGirl.create(:user, :with_accr) }
|
25
|
-
|
26
|
-
it 'shows member sidebar menu' do
|
27
|
-
expect(subject.navigation).to eq 'member'
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'member with mpp' do
|
32
|
-
subject { FactoryGirl.create(:user, :with_mpp) }
|
33
|
-
|
34
|
-
it 'shows member sidebar menu' do
|
35
|
-
expect(subject.navigation).to eq 'member'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'member in-renewal' do
|
40
|
-
subject { FactoryGirl.create(:user, :in_renewal) }
|
41
|
-
|
42
|
-
it 'shows in-renewal sidebar menu' do
|
43
|
-
expect(subject.navigation).to eq 'member-in-renewal'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'member in-renewal late' do
|
48
|
-
subject { FactoryGirl.create(:user, :in_renewal_late) }
|
49
|
-
|
50
|
-
it 'shows in-renewal-late sidebar menu' do
|
51
|
-
expect(subject.navigation).to eq 'member-in-renewal-late'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'member with outstanding balance' do
|
56
|
-
subject { FactoryGirl.create(:user, :outstanding_balance) }
|
57
|
-
|
58
|
-
it 'shows member-with-outstanding-balance sidebar menu' do
|
59
|
-
expect(subject.navigation).to eq 'member-with-outstanding-balance'
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
describe AmaLayout::NotificationScrubber do
|
2
|
-
describe '#initialize' do
|
3
|
-
let(:sanitized) { Loofah.fragment(string).scrub!(subject).to_s }
|
4
|
-
let(:string) { '<script>alert("haxxed");</script><a href="#" invalid="test">test</a>waffles' }
|
5
|
-
|
6
|
-
it 'scrubs HTML tags from a string' do
|
7
|
-
expect(sanitized).to eq('alert("haxxed");<a href="#">test</a>waffles')
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
@@ -1,281 +0,0 @@
|
|
1
|
-
describe AmaLayout::NotificationSet do
|
2
|
-
let(:store) do
|
3
|
-
AmaLayout::Notifications::RedisStore.new(
|
4
|
-
db: 4,
|
5
|
-
namespace: 'test_notifications',
|
6
|
-
host: 'localhost'
|
7
|
-
)
|
8
|
-
end
|
9
|
-
let(:key) { 1 }
|
10
|
-
let(:duration) { AmaLayout::Notification::DEFAULT_LIFESPAN }
|
11
|
-
let(:store_key) { key.to_s }
|
12
|
-
let(:digest) { base_notification.digest }
|
13
|
-
let(:base_notification) do
|
14
|
-
AmaLayout::Notification.new(
|
15
|
-
type: :notice,
|
16
|
-
header: 'test',
|
17
|
-
content: 'test',
|
18
|
-
lifespan: duration,
|
19
|
-
version: '1.0.0',
|
20
|
-
created_at: Time.zone.local(2017, 06, 19),
|
21
|
-
active: true
|
22
|
-
)
|
23
|
-
end
|
24
|
-
let(:json) do
|
25
|
-
<<-JSON
|
26
|
-
{
|
27
|
-
"#{digest}": {
|
28
|
-
"type": "notice",
|
29
|
-
"header": "test",
|
30
|
-
"content": "test",
|
31
|
-
"created_at": "2017-06-19T06:00:00.000Z",
|
32
|
-
"active": true,
|
33
|
-
"lifespan": #{duration},
|
34
|
-
"version": "1.0.0"
|
35
|
-
}
|
36
|
-
}
|
37
|
-
JSON
|
38
|
-
end
|
39
|
-
let(:stale_json) do
|
40
|
-
<<-JSON
|
41
|
-
{
|
42
|
-
"d3c2bc71904100674325791b371db7446097f956ea76a304e787abd5f2588665": {
|
43
|
-
"type": "notice",
|
44
|
-
"header": "stale",
|
45
|
-
"content": "stale",
|
46
|
-
"created_at": "2012-06-19T06:00:00.000Z",
|
47
|
-
"active": true,
|
48
|
-
"lifespan": #{duration},
|
49
|
-
"version": "1.0.0"
|
50
|
-
}
|
51
|
-
}
|
52
|
-
JSON
|
53
|
-
end
|
54
|
-
|
55
|
-
subject { described_class.new(store, key) }
|
56
|
-
|
57
|
-
around(:each) do |example|
|
58
|
-
Timecop.freeze(Time.zone.local(2017, 6, 19)) do
|
59
|
-
store.clear
|
60
|
-
example.run
|
61
|
-
store.clear
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe '#initialize' do
|
66
|
-
context 'with valid JSON in data store' do
|
67
|
-
before(:each) do
|
68
|
-
store.set(store_key, notification)
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'without stale notifications in the data store' do
|
72
|
-
let(:notification) { json }
|
73
|
-
|
74
|
-
it 'fetches the notifications' do
|
75
|
-
expect(subject.size).to eq(1)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'with stale notifications in the data store' do
|
80
|
-
let(:notification) { stale_json }
|
81
|
-
|
82
|
-
it 'returns an empty set' do
|
83
|
-
expect(subject).to be_empty
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'cleans out stale notifications from the data store' do
|
87
|
-
subject
|
88
|
-
expect(store.get(store_key)).to eq('{}')
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context 'with invalid JSON in data store' do
|
94
|
-
before(:each) do
|
95
|
-
store.set(store_key, '{"invalid_json":')
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'logs to Rails logger' do
|
99
|
-
expect(Rails.logger).to receive(:error).with(instance_of(String))
|
100
|
-
subject
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'deletes the key in data store' do
|
104
|
-
subject
|
105
|
-
expect(store.get(store_key)).to be nil
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'returns an empty set' do
|
109
|
-
expect(subject).to be_empty
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'sets the base attribute to a hash' do
|
113
|
-
expect(subject.base).to be_a(Hash)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
context 'with no entry in data store' do
|
118
|
-
it 'returns an empty set' do
|
119
|
-
expect(subject).to be_empty
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
describe '#create' do
|
125
|
-
it 'returns the NotificationSet instance' do
|
126
|
-
expect(subject.create(header: 'test', content: 'test')).to be_a(described_class)
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'creates a new active notification' do
|
130
|
-
subject.create(header: 'test', content: 'test')
|
131
|
-
expect(subject.size).to eq(1)
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'saves a notification in data store' do
|
135
|
-
subject.create(header: 'test', content: 'test')
|
136
|
-
expect(store.get(store_key)).to be_a(String)
|
137
|
-
end
|
138
|
-
|
139
|
-
context 'when the same notification exists but is dismissed' do
|
140
|
-
before(:each) do
|
141
|
-
store.set(store_key, json)
|
142
|
-
subject.first.dismiss!
|
143
|
-
subject.save
|
144
|
-
subject.create(header: 'test', content: 'test')
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'does not overwrite the notification' do
|
148
|
-
expect(subject.active).to be_empty
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'still has the dismissed notification in the data store' do
|
152
|
-
data = JSON.parse(store.get(store_key))
|
153
|
-
notification = data.values.first
|
154
|
-
expect(data.values.first['active']).to be false
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
describe '#delete' do
|
160
|
-
before(:each) do
|
161
|
-
subject.create(base_notification.to_h)
|
162
|
-
end
|
163
|
-
|
164
|
-
context 'with an array as an argument' do
|
165
|
-
it 'deletes the notification from the data store' do
|
166
|
-
data = subject.delete([digest])
|
167
|
-
expect(data).to be_a(described_class)
|
168
|
-
expect(data).to be_empty
|
169
|
-
expect(store.get(store_key)).to eq('{}')
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'returns falsey if nothing is deleted' do
|
173
|
-
expect(subject.delete(['missing'])).to be_falsey
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'with string arguments' do
|
178
|
-
it 'deletes the notification from the data store' do
|
179
|
-
data = subject.delete(digest)
|
180
|
-
expect(data).to be_a(described_class)
|
181
|
-
expect(data).to be_empty
|
182
|
-
expect(store.get(store_key)).to eq('{}')
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'returns falsey if nothing is deleted' do
|
186
|
-
expect(subject.delete('missing')).to be_falsey
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
describe '#destroy' do
|
192
|
-
context 'when data is removed' do
|
193
|
-
before(:each) do
|
194
|
-
subject.create(header: 'test', content: 'test', lifespan: 1.day)
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'returns a NotificationSet instance' do
|
198
|
-
expect(subject.destroy!).to be_a(described_class)
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'removes the notifications from the data store' do
|
202
|
-
subject.destroy!
|
203
|
-
expect(store.get(store_key)).to be nil
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'returns an empty set' do
|
207
|
-
expect(subject.destroy!).to be_empty
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
context 'when data is not removed' do
|
212
|
-
it 'returns false' do
|
213
|
-
expect(subject.destroy!).to be false
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
describe '#find' do
|
219
|
-
context 'when id is not preset' do
|
220
|
-
it 'returns nil' do
|
221
|
-
expect(subject.find('invalid')).to be nil
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
context 'when id is present' do
|
226
|
-
let(:id) { subject.last.id }
|
227
|
-
|
228
|
-
before(:each) do
|
229
|
-
subject.create(header: 'test', content: 'test')
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'returns the notification' do
|
233
|
-
expect(subject.find(id)).to eq(subject.last)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
describe '#save' do
|
239
|
-
before(:each) do
|
240
|
-
subject.create(header: 'test', content: 'test')
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'saves the notifications' do
|
244
|
-
expect(subject.last.active?).to be true
|
245
|
-
subject.last.dismiss!
|
246
|
-
subject.save
|
247
|
-
expect(subject.active).to be_empty
|
248
|
-
end
|
249
|
-
|
250
|
-
it 'returns the NotificationSet instance' do
|
251
|
-
expect(subject.save).to be_a(described_class)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
describe '#inspect' do
|
256
|
-
it 'returns a stringified instance' do
|
257
|
-
expect(subject.inspect).to eq('<AmaLayout::NotificationSet>: []')
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
context 'scoping' do
|
262
|
-
before(:each) do
|
263
|
-
subject.create(header: 'test', content: 'test')
|
264
|
-
subject.create(header: 'inactive', content: 'inactive')
|
265
|
-
subject.last.dismiss!
|
266
|
-
subject.save
|
267
|
-
end
|
268
|
-
|
269
|
-
describe '#all' do
|
270
|
-
it 'returns both active and inactive notifications' do
|
271
|
-
expect(subject.all.size).to eq(2)
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
describe '#active' do
|
276
|
-
it 'returns only active notifications' do
|
277
|
-
expect(subject.active.size).to eq(1)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|