ama_layout 5.6.0 → 5.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ff91bd72118815e0b2ebaf099522f1174148190d
4
- data.tar.gz: 000c2e9c578a9abd1d277eb84c511882048a3e59
3
+ metadata.gz: 681ee492fa8e24d8f976759f37763fb2aa82a6bc
4
+ data.tar.gz: 0174f1cfcb34cf34c3747af2159930a49edba280
5
5
  SHA512:
6
- metadata.gz: b4a285e25b076bd864d750f1021961eb2d73a7aeeb3da8ec0cf87be1359c2c383e1de06fef8b0cc4d5ee5661b4039cb74ee6b01668f1c010bcb493e45ccba13b
7
- data.tar.gz: 3368542892732acab63e622b16312608fb78844536b05eebf92b71621e403275a2dbcd558481e46b56d16a3e7fbecc719662ab440d977f4a29bb7b3903f94532
6
+ metadata.gz: 2329ee194ad518c686aaca74a7dac3b730d467d5e0e4952c4ec0d4b1a088d68fbf43be1f5bab0d4fc915829e3ae1f0fc891cc1645792288e9c737bbb1ad8fd7c
7
+ data.tar.gz: b04fbb19aac1aed374ca4f4f14c8499dac9f055e245f8f5b869f02d018d9a23d48e2d72a0e2b05fced356f884a2981dc0a5aa59a5c6dc93299050a4f7f9fe9a7
@@ -5,3 +5,4 @@
5
5
  //= require ./cookie.ready
6
6
  //= require ../mailcheck/index
7
7
  //= require ../real_date_picker
8
+ //= require ../notifications
@@ -0,0 +1,17 @@
1
+ class AMALayout.Notifications
2
+ constructor: () ->
3
+ $(document).on 'click', '[data-notifications-toggle]', (event) =>
4
+ event.preventDefault();
5
+ badge = event.currentTarget
6
+ if $(badge).find('[data-notification-count]').remove().size()
7
+ @request()
8
+
9
+ request: () ->
10
+ $.ajax(
11
+ type: 'DELETE',
12
+ url: '/ama_layout/api/v1/notifications',
13
+ timeout: 10000
14
+ )
15
+
16
+ $(document).ready ->
17
+ window.AMALayout.notifications = new AMALayout.Notifications()
@@ -0,0 +1,18 @@
1
+ module AmaLayout
2
+ module Api
3
+ module V1
4
+ class NotificationsController < ApplicationController
5
+ before_action :require_login
6
+
7
+ # DELETE /api/v1/notifications
8
+ # Dismiss all user notifications
9
+ def dismiss_all
10
+ notifications = current_user.notifications
11
+ notifications.each(&:dismiss!)
12
+ notifications.save
13
+ head :no_content
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ <div class="row <%= notification.active_class %>">
2
+ <div class="small-2 column">
3
+ <%= notification.icon %>
4
+ </div>
5
+ <div class="small-10 column">
6
+ <p class="bold"><%= notification.header %></p>
7
+ <p><%= sanitize notification.content, scrubber: AmaLayout::NotificationScrubber.new %></p>
8
+ <p class="micetype"><%= notification.created_at %></p>
9
+ </div>
10
+ </div>
@@ -0,0 +1,22 @@
1
+ <div class="off-canvas position-right right-sidebar" id="offCanvasRight" data-off-canvas>
2
+ <div class="row column right-sidebar__header">
3
+ <h2 class="mt1">Notification Centre</h2>
4
+ <button class="close-button" aria-label="Close menu" type="button" data-close>
5
+ <span aria-hidden="true">&times;</span>
6
+ </button>
7
+ </div>
8
+ <div class="row column">
9
+ <%= navigation.notifications_heading %>
10
+ </div>
11
+ <%= render partial: 'ama_layout/notification', collection: notifications %>
12
+ <div class="row column">
13
+ <p class="mt1">Did You Know?</p>
14
+ <div class="section-content">
15
+ <p class="bold">Sign up for Vehicle Registration Auto-Renew</p>
16
+ <p>
17
+ We'll process your payment and mail you a new registration certificate and licence plate sticker. It's that simple!
18
+ </p>
19
+ <%= link_to 'Sign up now', "#{Rails.configuration.registries_site}/order/registrations/new", class: 'button--right button--expand-small-down' %>
20
+ </div>
21
+ </div>
22
+ </div>
@@ -0,0 +1,6 @@
1
+ <li>
2
+ <a href="#" class="notification link--no-underline" data-toggle="offCanvasRight" data-notifications-toggle>
3
+ <i class="fa fa-2x fa-bell"></i>
4
+ <%= navigation.notification_badge %>
5
+ </a>
6
+ </li>
@@ -2,6 +2,10 @@
2
2
  <div class="title-bar" data-responsive-toggle="main-menu" data-hide-for="large">
3
3
  <button class="menu-icon" type="button" data-toggle="offCanvasLeft"></button>
4
4
  <%= link_to(image_tag("ama-logo.png"), "https://www.ama.ab.ca", class: "title-bar__logo") %>
5
+ <a href="#" data-toggle="offCanvasRight" data-notifications-toggle>
6
+ <i class="fa fa-2x fa-bell notification__icon"></i>
7
+ <%= navigation.notification_badge %>
8
+ </a>
5
9
  </div>
6
10
  <div class="top-bar" id="main-menu">
7
11
  <div class="top-bar-left">
@@ -9,6 +13,7 @@
9
13
  </div>
10
14
  <div class="top-bar-right">
11
15
  <ul class="menu" data-responsive-menu="drilldown medium-dropdown">
16
+ <%= navigation.notifications %>
12
17
  <li>
13
18
  <a href="<%= Rails.configuration.gatekeeper_site %>/help" target="_blank">Help</a>
14
19
  </li>
@@ -43,7 +48,7 @@
43
48
  </ul>
44
49
  </div>
45
50
  </div>
46
-
51
+ <%= navigation.notification_sidebar %>
47
52
  <div class="javascript_errors error_notification" hidden></div>
48
53
  <noscript>
49
54
  <div class="mt1 large-12 columns text-center error_notification">
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ AmaLayout::Engine.routes.draw do
2
+ scope module: 'ama_layout' do
3
+ namespace :api do
4
+ namespace :v1 do
5
+ delete :notifications, to: 'notifications#dismiss_all'
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/ama_layout.rb CHANGED
@@ -17,16 +17,16 @@ require 'ama_layout/controllers/action_controller'
17
17
  require 'ama_layout/notifications/abstract_store'
18
18
  require 'ama_layout/notifications/redis_store'
19
19
  require 'ama_layout/notification'
20
+ require 'ama_layout/decorators/notification_decorator'
21
+ require 'ama_layout/notification_scrubber'
20
22
  require 'ama_layout/notification_set'
21
23
  require 'ama_layout/notifications'
22
24
 
23
25
  module AmaLayout
24
- module Rails
25
- class Engine < ::Rails::Engine
26
- initializer('ama_layout') do
27
- I18n.load_path << File.join(self.root, 'app', 'config', 'locales', 'en.yml')
28
- ::ActionController::Base.send :include, AmaLayout::ActionController
29
- end
26
+ class Engine < Rails::Engine
27
+ initializer('ama_layout') do
28
+ I18n.load_path << File.join(self.root, 'app', 'config', 'locales', 'en.yml')
29
+ ::ActionController::Base.send :include, AmaLayout::ActionController
30
30
  end
31
31
  end
32
32
  end
@@ -32,5 +32,52 @@ module AmaLayout
32
32
  def account_toggle
33
33
  h.render partial: "account_toggle"
34
34
  end
35
+
36
+ def notifications
37
+ if user
38
+ h.render 'ama_layout/notifications', notifications: user.notifications, navigation: self
39
+ end
40
+ end
41
+
42
+ def notification_badge
43
+ if new_notifications?
44
+ h.content_tag(
45
+ :div,
46
+ active_notification_count,
47
+ class: 'notification__badge',
48
+ data: {
49
+ notification_count: true
50
+ }
51
+ )
52
+ end
53
+ end
54
+
55
+ def notification_sidebar
56
+ if user
57
+ h.render 'ama_layout/notification_sidebar', navigation: self, notifications: decorated_notifications
58
+ end
59
+ end
60
+
61
+ def notifications_heading
62
+ if user.notifications.any?
63
+ h.content_tag :p, 'Most Recent Notifications', class: 'mt1'
64
+ else
65
+ h.content_tag :p, 'No Recent Notifications', class: 'mt1 italic'
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def decorated_notifications
72
+ AmaLayout::NotificationDecorator.decorate_collection(user.notifications)
73
+ end
74
+
75
+ def active_notification_count
76
+ user && user.notifications.active.size || 0
77
+ end
78
+
79
+ def new_notifications?
80
+ active_notification_count > 0
81
+ end
35
82
  end
36
83
  end
@@ -0,0 +1,45 @@
1
+ module AmaLayout
2
+ class NotificationDecorator < Draper::Decorator
3
+ delegate_all
4
+
5
+ ICONS = {
6
+ notice: {
7
+ icon_class: 'fa-info',
8
+ colour_class: 'right-sidebar__content-icon--blue' # currently not in use
9
+ },
10
+ warning: {
11
+ icon_class: 'fa-exclamation',
12
+ colour_class: 'right-sidebar__content-icon--orange'
13
+ },
14
+ alert: {
15
+ icon_class: 'fa-exclamation-triangle',
16
+ colour_class: 'right-sidebar__content-icon--red'
17
+ }
18
+ }.freeze
19
+
20
+ def created_at
21
+ "#{time_elapsed} ago".humanize
22
+ end
23
+
24
+ def icon
25
+ h.content_tag :div, class: icon_data.fetch(:colour_class) do
26
+ klass = icon_data.fetch(:icon_class)
27
+ h.content_tag :i, nil, class: "fa #{klass} right-sidebar__notice-icon"
28
+ end
29
+ end
30
+
31
+ def active_class
32
+ active? ? 'right-sidebar__content--active' : 'right-sidebar__content--inactive'
33
+ end
34
+
35
+ private
36
+
37
+ def icon_data
38
+ @icon_data ||= ICONS.fetch(type)
39
+ end
40
+
41
+ def time_elapsed
42
+ h.time_ago_in_words(object.created_at, include_seconds: true)
43
+ end
44
+ end
45
+ end
@@ -1,18 +1,22 @@
1
1
  module AmaLayout
2
2
  class Notification
3
+ include Draper::Decoratable
4
+
3
5
  TYPES = %i[notice warning alert].freeze
4
6
  DEFAULT_LIFESPAN = 1.year.freeze
5
7
  FORMAT_VERSION = '1.0.0'.freeze
6
8
 
7
9
  # NOTE: The following attributes are designed to be immutable - you need
8
10
  # make a new instance to change them. The only mutable attribute is :active.
9
- attr_reader :id, :type, :header, :content, :created_at, :lifespan, :version
11
+ attr_reader :id, :type, :brand, :header, :content, :created_at, :lifespan,
12
+ :version
10
13
  attr_accessor :active
11
14
 
12
15
  def initialize(args = {})
13
16
  args = args.with_indifferent_access
14
17
  @id = args[:id]
15
18
  @type = args.fetch(:type, :notice).to_sym
19
+ @brand = args[:brand]
16
20
  @header = args.fetch(:header)
17
21
  @content = args.fetch(:content)
18
22
  @created_at = parse_time(args.fetch(:created_at))
@@ -41,7 +45,7 @@ module AmaLayout
41
45
 
42
46
  def digest
43
47
  Digest::SHA256.hexdigest(
44
- "#{type}#{header}#{content}#{lifespan.to_i}#{version}"
48
+ "#{type}#{header}#{content}#{brand}#{version}"
45
49
  )
46
50
  end
47
51
 
@@ -54,6 +58,7 @@ module AmaLayout
54
58
  # consistency with the underlying data store.
55
59
  {
56
60
  'type' => type.to_s,
61
+ 'brand' => brand,
57
62
  'header' => header,
58
63
  'content' => content,
59
64
  'created_at' => created_at.iso8601,
@@ -0,0 +1,13 @@
1
+ module AmaLayout
2
+ class NotificationScrubber < Rails::Html::PermitScrubber
3
+ def initialize
4
+ super
5
+ self.tags = %w(i a div span strong br em h1 h2 h3 h4 h5 h6 blockquote)
6
+ self.attributes = %w(href class id)
7
+ end
8
+
9
+ def skip_node?(node)
10
+ node.text?
11
+ end
12
+ end
13
+ end
@@ -5,8 +5,9 @@ module AmaLayout
5
5
  # The raw serialization format is JSON as follows (keys are SHA256 hashes):
6
6
  #
7
7
  # {
8
- # "8ca9f850c18acc17643038b2341bee3ede8a24c0f3e92f56f2109ce49fdcb616": {
8
+ # "57107043eab0f60a37f7735307dc6fc6709d04eec2dbeea8c284958057af9b77": {
9
9
  # "type": "notice",
10
+ # "brand": "membership",
10
11
  # "header": "test",
11
12
  # "content": "test",
12
13
  # "created_at": "2017-06-19T11:26:57.730-06:00",
@@ -20,7 +21,7 @@ module AmaLayout
20
21
  include Enumerable
21
22
  attr_accessor :base, :data_store, :key
22
23
 
23
- delegate :each, :first, :last, :size, :[], :empty?, :any?, to: :active
24
+ delegate :each, :first, :last, :size, :[], :empty?, :any?, to: :all
24
25
 
25
26
  def initialize(data_store, key)
26
27
  self.data_store = data_store
@@ -50,6 +51,15 @@ module AmaLayout
50
51
  data_store.delete(key) && reload!
51
52
  end
52
53
 
54
+ def delete(*digests)
55
+ digests = Array.wrap(digests.flatten)
56
+ delta = all.reject { |n| digests.include?(n.digest) }
57
+ if delta != all
58
+ @all = delta
59
+ save
60
+ end
61
+ end
62
+
53
63
  def find(digest)
54
64
  all.find { |n| n.id == digest }
55
65
  end
@@ -1,3 +1,3 @@
1
1
  module AmaLayout
2
- VERSION = '5.6.0'
2
+ VERSION = '5.7.0'
3
3
  end
@@ -0,0 +1,13 @@
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
@@ -7,8 +7,8 @@ describe AmaLayout::NavigationDecorator do
7
7
  let(:membership_site) { "http://membership.waffles.ca" }
8
8
  let(:driveredonline_site) { "http://driveredonline.waffles.ca" }
9
9
  let(:registries_site) { "http://registries.waffles.ca" }
10
- let(:automotive_site) { "http://automotive.waffles.ca"}
11
- let(:travel_site) { "http://travel.waffles.ca"}
10
+ let(:automotive_site) { "http://automotive.waffles.ca" }
11
+ let(:travel_site) { "http://travel.waffles.ca" }
12
12
 
13
13
  before(:each) do
14
14
  allow(Rails.configuration).to receive(:gatekeeper_site).and_return(gatekeeper_site)
@@ -129,4 +129,123 @@ describe AmaLayout::NavigationDecorator do
129
129
  expect(navigation_presenter.account_toggle).to eq "render"
130
130
  end
131
131
  end
132
+
133
+ context 'notification center' do
134
+ let(:store) do
135
+ AmaLayout::Notifications::RedisStore.new(
136
+ db: 4,
137
+ namespace: 'test_notifications',
138
+ host: 'localhost'
139
+ )
140
+ end
141
+ let(:notification_set) { AmaLayout::NotificationSet.new(store, 1) }
142
+ let(:user) { OpenStruct.new(navigation: 'member', notifications: notification_set) }
143
+ let(:navigation) { FactoryGirl.build :navigation, user: user }
144
+ subject { described_class.new(navigation) }
145
+
146
+ around(:each) do |example|
147
+ Timecop.freeze(Time.zone.local(2017, 6, 19)) do
148
+ store.clear
149
+ example.run
150
+ store.clear
151
+ end
152
+ end
153
+
154
+ describe '#notifications' do
155
+ it 'renders the content to the page' do
156
+ expect(subject.h).to receive(:render).once.and_return true
157
+ expect(subject.notifications).to be true
158
+ end
159
+ end
160
+
161
+ describe '#notification_badge' do
162
+ context 'with 1 active notification' do
163
+ before(:each) do
164
+ user.notifications.create(
165
+ type: :warning,
166
+ header: 'test',
167
+ content: 'test'
168
+ )
169
+ end
170
+
171
+ it 'returns a div with the count of active notifications' do
172
+ expect(subject.notification_badge).to include('div')
173
+ expect(subject.notification_badge).to include('1')
174
+ end
175
+ end
176
+
177
+ context 'with only inactive notifications' do
178
+ before(:each) do
179
+ user.notifications.create(
180
+ type: :warning,
181
+ header: 'test',
182
+ content: 'test'
183
+ )
184
+ user.notifications.first.dismiss!
185
+ user.notifications.save
186
+ end
187
+
188
+ it 'does not return the badge markup' do
189
+ expect(subject.notification_badge).to be nil
190
+ end
191
+ end
192
+
193
+ context 'with only active and inactive notifications' do
194
+ before(:each) do
195
+ user.notifications.create(
196
+ type: :warning,
197
+ header: 'test',
198
+ content: 'test'
199
+ )
200
+ 2.times do |i|
201
+ user.notifications.create(
202
+ type: :notice,
203
+ header: i,
204
+ content: i
205
+ )
206
+ end
207
+ user.notifications.first.dismiss!
208
+ user.notifications.save
209
+ end
210
+
211
+ it 'returns a div with the count of active notifications' do
212
+ expect(subject.notification_badge).to include('div')
213
+ expect(subject.notification_badge).to include('2')
214
+ end
215
+ end
216
+ end
217
+
218
+ describe '#notification_sidebar' do
219
+ it 'renders content to the page' do
220
+ expect(subject.h).to receive(:render).once.and_return true
221
+ expect(subject.notification_sidebar).to be true
222
+ end
223
+ end
224
+
225
+ describe '#notifications_heading' do
226
+ context 'when notifications are present' do
227
+ before(:each) do
228
+ user.notifications.create(
229
+ type: :warning,
230
+ header: 'test',
231
+ content: 'test'
232
+ )
233
+ end
234
+
235
+ it 'returns the correct heading' do
236
+ expect(subject.notifications_heading).to include('Most Recent Notifications')
237
+ end
238
+ end
239
+
240
+ context 'when notifications are not present' do
241
+ it 'returns the correct heading' do
242
+ expect(subject.notifications_heading).to include('No Recent Notifications')
243
+ end
244
+
245
+ it 'italicizes the message' do
246
+ expect(subject.notifications_heading).to include('italic')
247
+ end
248
+ end
249
+ end
250
+ end
132
251
  end
@@ -0,0 +1,57 @@
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
@@ -0,0 +1,10 @@
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
@@ -7,12 +7,24 @@ describe AmaLayout::NotificationSet do
7
7
  )
8
8
  end
9
9
  let(:key) { 1 }
10
- let(:duration) { AmaLayout::Notification::DEFAULT_LIFESPAN.to_i }
10
+ let(:duration) { AmaLayout::Notification::DEFAULT_LIFESPAN }
11
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
12
24
  let(:json) do
13
25
  <<-JSON
14
26
  {
15
- "8ca9f850c18acc17643038b2341bee3ede8a24c0f3e92f56f2109ce49fdcb616": {
27
+ "#{digest}": {
16
28
  "type": "notice",
17
29
  "header": "test",
18
30
  "content": "test",
@@ -50,7 +62,7 @@ describe AmaLayout::NotificationSet do
50
62
  end
51
63
  end
52
64
 
53
- describe '#intialize' do
65
+ describe '#initialize' do
54
66
  context 'with valid JSON in data store' do
55
67
  before(:each) do
56
68
  store.set(store_key, notification)
@@ -133,7 +145,7 @@ describe AmaLayout::NotificationSet do
133
145
  end
134
146
 
135
147
  it 'does not overwrite the notification' do
136
- expect(subject).to be_empty # we have only non-active notifications
148
+ expect(subject.active).to be_empty
137
149
  end
138
150
 
139
151
  it 'still has the dismissed notification in the data store' do
@@ -144,6 +156,38 @@ describe AmaLayout::NotificationSet do
144
156
  end
145
157
  end
146
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
+
147
191
  describe '#destroy' do
148
192
  context 'when data is removed' do
149
193
  before(:each) do
@@ -200,7 +244,7 @@ describe AmaLayout::NotificationSet do
200
244
  expect(subject.last.active?).to be true
201
245
  subject.last.dismiss!
202
246
  subject.save
203
- expect(subject).to be_empty
247
+ expect(subject.active).to be_empty
204
248
  end
205
249
 
206
250
  it 'returns the NotificationSet instance' do
@@ -9,7 +9,7 @@ describe AmaLayout::Notifications do
9
9
  let(:json) do
10
10
  <<-JSON
11
11
  {
12
- "8ca9f850c18acc17643038b2341bee3ede8a24c0f3e92f56f2109ce49fdcb616": {
12
+ "02ac263cea5660e9f9020cb46e93772ed7755f2a60c40ad8961d2a15c1f99e6f": {
13
13
  "type": "notice",
14
14
  "header": "test",
15
15
  "content": "test",
@@ -1,2 +1,23 @@
1
1
  class ApplicationController < ActionController::Base
2
+ class NotificationsStub
3
+ include Enumerable
4
+
5
+ def each
6
+ [OpenStruct.new(dismiss!: true)].each do |element|
7
+ yield element
8
+ end
9
+ end
10
+
11
+ def save
12
+ true
13
+ end
14
+ end
15
+
16
+ def require_login
17
+ @current_user = OpenStruct.new(notifications: NotificationsStub.new)
18
+ end
19
+
20
+ def current_user
21
+ @current_user
22
+ end
2
23
  end
@@ -1,4 +1,5 @@
1
1
  Rails.application.routes.draw do
2
+ mount AmaLayout::Engine, at: 'ama_layout'
2
3
  root 'pages#index'
3
4
  get '/pages', to: 'pages#index', as: 'pages'
4
5
  end
data/spec/spec_helper.rb CHANGED
@@ -18,12 +18,6 @@ ActionView::TestCase::TestController.instance_eval do
18
18
  helper Rails.application.routes.url_helpers
19
19
  end
20
20
 
21
- ActionView::TestCase::TestController.class_eval do
22
- def _routes
23
- Rails.application.routes
24
- end
25
- end
26
-
27
21
  Draper::ViewContext.test_strategy :fast
28
22
 
29
23
  RSpec.configure do |config|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ama_layout
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.0
4
+ version: 5.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael van den Beuken
@@ -18,7 +18,7 @@ authors:
18
18
  autorequire:
19
19
  bindir: bin
20
20
  cert_chain: []
21
- date: 2017-06-26 00:00:00.000000000 Z
21
+ date: 2017-07-06 00:00:00.000000000 Z
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
24
24
  name: foundation-rails
@@ -271,8 +271,10 @@ files:
271
271
  - app/assets/javascripts/ama_layout/mobile/mobile_menu.coffee
272
272
  - app/assets/javascripts/ama_layout/mobile/ready.coffee
273
273
  - app/assets/javascripts/ama_layout/mobile/tablesaw.stackonly.js
274
+ - app/assets/javascripts/ama_layout/notifications.coffee
274
275
  - app/assets/javascripts/ama_layout/real_date_picker.coffee
275
276
  - app/config/locales/en.yml
277
+ - app/controllers/ama_layout/api/v1/notifications_controller.rb
276
278
  - app/helpers/ama_layout_breadcrumb_helper.rb
277
279
  - app/helpers/ama_layout_content_helper.rb
278
280
  - app/helpers/ama_layout_path_helper.rb
@@ -286,6 +288,9 @@ files:
286
288
  - app/views/ama_layout/_main_top_nav_item.html.erb
287
289
  - app/views/ama_layout/_notice.html.erb
288
290
  - app/views/ama_layout/_notices.html.erb
291
+ - app/views/ama_layout/_notification.html.erb
292
+ - app/views/ama_layout/_notification_sidebar.html.erb
293
+ - app/views/ama_layout/_notifications.html.erb
289
294
  - app/views/ama_layout/_sidebar.html.erb
290
295
  - app/views/ama_layout/_siteheader.html.erb
291
296
  - app/views/ama_layout/_sub_nav.html.erb
@@ -295,12 +300,14 @@ files:
295
300
  - app/views/ama_layout/_top_sub_nav.html.erb
296
301
  - app/views/ama_layout/_top_sub_nav_item.html.erb
297
302
  - app/views/application/_account_toggle.html.erb
303
+ - config/routes.rb
298
304
  - lib/ama_layout.rb
299
305
  - lib/ama_layout/breadcrumb_builder.rb
300
306
  - lib/ama_layout/controllers/action_controller.rb
301
307
  - lib/ama_layout/decorators/moneris_decorator.rb
302
308
  - lib/ama_layout/decorators/navigation_decorator.rb
303
309
  - lib/ama_layout/decorators/navigation_item_decorator.rb
310
+ - lib/ama_layout/decorators/notification_decorator.rb
304
311
  - lib/ama_layout/moneris.rb
305
312
  - lib/ama_layout/moneris/textbox.txt
306
313
  - lib/ama_layout/navigation.rb
@@ -308,16 +315,19 @@ files:
308
315
  - lib/ama_layout/navigation_helper.rb
309
316
  - lib/ama_layout/navigation_item.rb
310
317
  - lib/ama_layout/notification.rb
318
+ - lib/ama_layout/notification_scrubber.rb
311
319
  - lib/ama_layout/notification_set.rb
312
320
  - lib/ama_layout/notifications.rb
313
321
  - lib/ama_layout/notifications/abstract_store.rb
314
322
  - lib/ama_layout/notifications/redis_store.rb
315
323
  - lib/ama_layout/version.rb
316
324
  - spec/ama_layout/breadcrumb_builder_spec.rb
325
+ - spec/ama_layout/controllers/ama_layout/api/v1/notifications_controller_spec.rb
317
326
  - spec/ama_layout/controllers/pages_controller_spec.rb
318
327
  - spec/ama_layout/decorators/moneris_decorator_spec.rb
319
328
  - spec/ama_layout/decorators/navigation_decorator_spec.rb
320
329
  - spec/ama_layout/decorators/navigation_item_decorator_spec.rb
330
+ - spec/ama_layout/decorators/notification_decorator_spec.rb
321
331
  - spec/ama_layout/fixtures/navigation.yml
322
332
  - spec/ama_layout/fixtures/real_date_picker.html
323
333
  - spec/ama_layout/javascripts/real_date_picker_spec.coffee
@@ -325,6 +335,7 @@ files:
325
335
  - spec/ama_layout/navigation_helper_spec.rb
326
336
  - spec/ama_layout/navigation_item_spec.rb
327
337
  - spec/ama_layout/navigation_spec.rb
338
+ - spec/ama_layout/notification_scrubber_spec.rb
328
339
  - spec/ama_layout/notification_set_spec.rb
329
340
  - spec/ama_layout/notification_spec.rb
330
341
  - spec/ama_layout/notifications/abstract_store_spec.rb
@@ -371,10 +382,12 @@ specification_version: 4
371
382
  summary: ".ama.ab.ca site layouts"
372
383
  test_files:
373
384
  - spec/ama_layout/breadcrumb_builder_spec.rb
385
+ - spec/ama_layout/controllers/ama_layout/api/v1/notifications_controller_spec.rb
374
386
  - spec/ama_layout/controllers/pages_controller_spec.rb
375
387
  - spec/ama_layout/decorators/moneris_decorator_spec.rb
376
388
  - spec/ama_layout/decorators/navigation_decorator_spec.rb
377
389
  - spec/ama_layout/decorators/navigation_item_decorator_spec.rb
390
+ - spec/ama_layout/decorators/notification_decorator_spec.rb
378
391
  - spec/ama_layout/fixtures/navigation.yml
379
392
  - spec/ama_layout/fixtures/real_date_picker.html
380
393
  - spec/ama_layout/javascripts/real_date_picker_spec.coffee
@@ -382,6 +395,7 @@ test_files:
382
395
  - spec/ama_layout/navigation_helper_spec.rb
383
396
  - spec/ama_layout/navigation_item_spec.rb
384
397
  - spec/ama_layout/navigation_spec.rb
398
+ - spec/ama_layout/notification_scrubber_spec.rb
385
399
  - spec/ama_layout/notification_set_spec.rb
386
400
  - spec/ama_layout/notification_spec.rb
387
401
  - spec/ama_layout/notifications/abstract_store_spec.rb