mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-04 04:04:36 +08:00
Merge pull request #188 from biosistemika/global-notifications
Global notifications
This commit is contained in:
commit
61cb9651c7
21 changed files with 449 additions and 21 deletions
|
@ -1,12 +1,60 @@
|
|||
/* Loading overlay for search */
|
||||
$("#search-bar").submit(function (){
|
||||
if( $("#update-canvas") ){
|
||||
$(document.body).spin(true);
|
||||
setTimeout(function(){
|
||||
$(".spinner").remove();
|
||||
}, 1000);
|
||||
} else {
|
||||
animateSpinner();
|
||||
}
|
||||
});
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
/* Loading overlay for search */
|
||||
$("#search-bar").submit(function (){
|
||||
if( $("#update-canvas") ){
|
||||
$(document.body).spin(true);
|
||||
setTimeout(function(){
|
||||
$(".spinner").remove();
|
||||
}, 1000);
|
||||
} else {
|
||||
animateSpinner();
|
||||
}
|
||||
});
|
||||
|
||||
function loadDropdownNotifications() {
|
||||
var button = $('#notifications-dropdown');
|
||||
button
|
||||
.on('click', function() {
|
||||
$.ajax({
|
||||
url: button.attr('data-href'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
beforeSend: animateSpinner($('.notifications-dropdown-header'), true),
|
||||
success: function(data) {
|
||||
$('.notifications-dropdown-header')
|
||||
.nextAll('li.notification')
|
||||
.remove();
|
||||
$('.notifications-dropdown-header')
|
||||
.after(data.html);
|
||||
animateSpinner($('.notifications-dropdown-header'), false);
|
||||
}
|
||||
});
|
||||
$('#count-notifications').hide();
|
||||
});
|
||||
}
|
||||
|
||||
function loadUnseenNotificationsNumber() {
|
||||
var notificationCount = $('#count-notifications');
|
||||
$.ajax({
|
||||
url: notificationCount.attr('data-href'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
notificationCount.html('');
|
||||
if ( data.notificationNmber > 0 ) {
|
||||
notificationCount.html(data.notificationNmber);
|
||||
notificationCount.show();
|
||||
} else {
|
||||
notificationCount.hide();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// init
|
||||
loadDropdownNotifications();
|
||||
loadUnseenNotificationsNumber();
|
||||
})();
|
||||
|
|
|
@ -72,6 +72,93 @@ table {
|
|||
max-width: 400px;
|
||||
}
|
||||
|
||||
#notifications-dropdown {
|
||||
.fa-bell {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#count-notifications {
|
||||
background-color: $color-theme-primary;
|
||||
border-radius: 5px;
|
||||
color: $color-wild-sand;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin-left: 10px;
|
||||
margin-top: -10px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width:768px) {
|
||||
#count-notifications {
|
||||
position: absolute !important;
|
||||
margin-left: -4px !important;
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-notifications {
|
||||
max-height: 500px;
|
||||
min-width: 450px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
|
||||
.notification {
|
||||
border-bottom: 1px solid $color-alto;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: $color-concrete;
|
||||
}
|
||||
}
|
||||
|
||||
.unseen {
|
||||
border-left: 4px solid $color-theme-primary;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
margin-left: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.assignment {
|
||||
background-color: $color-theme-primary;
|
||||
border-radius: 50%;
|
||||
color: $color-wild-sand;
|
||||
font-size: 15px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.system_message {
|
||||
background-color: $color-theme-secondary;
|
||||
border-radius: 50%;
|
||||
color: $color-wild-sand;
|
||||
font-size: 13px;
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.notifications-dropdown-header {
|
||||
background-color: $color-theme-primary;
|
||||
color: $color-wild-sand;
|
||||
font-weight: bold;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.notifications-dropdown-footer {
|
||||
background-color: $color-mystic;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#search-menu {
|
||||
padding-right: 0;
|
||||
|
||||
|
|
28
app/controllers/user_notifications_controller.rb
Normal file
28
app/controllers/user_notifications_controller.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
class UserNotificationsController < ApplicationController
|
||||
def recent_notifications
|
||||
@recent_notifications = UserNotification.recent_notifications(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'recent_notifications.html.erb'
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
UserNotification.seen_by_user(current_user)
|
||||
end
|
||||
|
||||
def unseen_notification
|
||||
@number = UserNotification.unseen_notification_count(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: {
|
||||
notificationNmber: @number
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -211,15 +211,23 @@ class Users::SettingsController < ApplicationController
|
|||
user: @new_user_org.user,
|
||||
organization: @new_user_org.organization
|
||||
).exists? && @new_user_org.save
|
||||
AppMailer.delay.invitation_to_organization(@new_user_org.user, @user_organization.user, @new_user_org.organization)
|
||||
AppMailer.delay.invitation_to_organization(@new_user_org.user,
|
||||
@user_organization.user,
|
||||
@new_user_org.organization)
|
||||
|
||||
generate_notification(@user_organization.user,
|
||||
@new_user_org.user,
|
||||
@new_user_org.role_str,
|
||||
@new_user_org.organization)
|
||||
|
||||
flash[:notice] = I18n.t(
|
||||
"users.settings.organizations.edit.modal_add_user.existing_flash_success",
|
||||
'users.settings.organizations.edit.modal_add_user.existing_flash_success',
|
||||
user: @new_user_org.user.full_name,
|
||||
role: @new_user_org.role_str
|
||||
)
|
||||
else
|
||||
flash[:alert] =
|
||||
I18n.t("users.settings.organizations.edit.modal_add_user.existing_flash_error")
|
||||
I18n.t('users.settings.organizations.edit.modal_add_user.existing_flash_error')
|
||||
end
|
||||
|
||||
# Either way, redirect back to organization page
|
||||
|
@ -520,4 +528,21 @@ class Users::SettingsController < ApplicationController
|
|||
)
|
||||
end
|
||||
|
||||
def generate_notification(user, target_user, role, org)
|
||||
title = I18n.t('activities.assign_user_to_organization',
|
||||
assigned_user: target_user.name,
|
||||
role: role,
|
||||
organization: org.name,
|
||||
assigned_by_user: user.name)
|
||||
|
||||
message = "#{I18n.t('search.index.organization')} #{org.name}"
|
||||
notification = Notification.create(
|
||||
type_of: :assignment,
|
||||
title:
|
||||
ActionController::Base.helpers.sanitize(title),
|
||||
message:
|
||||
ActionController::Base.helpers.sanitize(message),
|
||||
)
|
||||
UserNotification.create(notification: notification, user: target_user)
|
||||
end
|
||||
end
|
||||
|
|
16
app/helpers/notifications_helper.rb
Normal file
16
app/helpers/notifications_helper.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
module NotificationsHelper
|
||||
def create_system_notification(title, message)
|
||||
notification = Notification.new
|
||||
notification.title = title
|
||||
notification.message = message
|
||||
notification.type_of = :system_message
|
||||
notification.transaction do
|
||||
User.where.not(confirmed_at: nil).find_each do |u|
|
||||
UserNotification
|
||||
.new(user: u, notification: notification, checked: false)
|
||||
.save!
|
||||
end
|
||||
notification.save!
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
class Activity < ActiveRecord::Base
|
||||
after_create :generate_notification
|
||||
|
||||
enum type_of: [
|
||||
:create_project,
|
||||
:rename_project,
|
||||
|
@ -48,4 +50,32 @@ class Activity < ActiveRecord::Base
|
|||
belongs_to :project, inverse_of: :activities
|
||||
belongs_to :my_module, inverse_of: :activities
|
||||
belongs_to :user, inverse_of: :activities
|
||||
|
||||
private
|
||||
|
||||
def generate_notification
|
||||
if %w(assign_user_to_project assign_user_to_module).include? type_of
|
||||
notification_type = :assignment
|
||||
else
|
||||
notification_type = :recent_changes
|
||||
end
|
||||
|
||||
task_m = "| #{I18n.t('search.index.module')} #{my_module.name}" if my_module
|
||||
notification = Notification.create(
|
||||
type_of: notification_type,
|
||||
title:
|
||||
ActionController::Base.helpers.sanitize(message, tags: %w(strong a)),
|
||||
message:
|
||||
ActionController::Base
|
||||
.helpers.sanitize(
|
||||
"#{I18n.t('search.index.project')} #{project.name} #{task_m}"
|
||||
),
|
||||
generator_user_id: user.id
|
||||
)
|
||||
|
||||
project.users.each do |project_user|
|
||||
next if project_user == user
|
||||
UserNotification.create(notification: notification, user: project_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
13
app/models/notification.rb
Normal file
13
app/models/notification.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class Notification < ActiveRecord::Base
|
||||
has_many :user_notifications, inverse_of: :notification
|
||||
has_many :users, through: :user_notifications
|
||||
belongs_to :generator_user, class_name: 'User'
|
||||
|
||||
enum type_of: [:assignment, :recent_changes, :system_message]
|
||||
|
||||
def already_seen(user)
|
||||
UserNotification.where(notification: self, user: user)
|
||||
.pluck(:checked)
|
||||
.first
|
||||
end
|
||||
end
|
|
@ -84,7 +84,8 @@ class User < ActiveRecord::Base
|
|||
has_many :added_protocols, class_name: 'Protocol', foreign_key: 'added_by_id', inverse_of: :added_by
|
||||
has_many :archived_protocols, class_name: 'Protocol', foreign_key: 'archived_by_id', inverse_of: :archived_by
|
||||
has_many :restored_protocols, class_name: 'Protocol', foreign_key: 'restored_by_id', inverse_of: :restored_by
|
||||
|
||||
has_many :user_notifications, inverse_of: :user
|
||||
has_many :notifications, through: :user_notifications
|
||||
# If other errors besides parameter "avatar" exist,
|
||||
# they will propagate to "avatar" also, so remove them
|
||||
# and put all other (more specific ones) in it
|
||||
|
@ -260,4 +261,3 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
22
app/models/user_notification.rb
Normal file
22
app/models/user_notification.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
class UserNotification < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :notification
|
||||
|
||||
def self.recent_notifications(user)
|
||||
Notification.joins(:user_notifications)
|
||||
.where('user_notifications.user_id = ?', user.id)
|
||||
.order(created_at: :DESC)
|
||||
.limit(10)
|
||||
end
|
||||
|
||||
def self.unseen_notification_count(user)
|
||||
where('user_id = ? AND checked = false', user.id).count
|
||||
end
|
||||
|
||||
def self.seen_by_user(user)
|
||||
where(user: user).map do |n|
|
||||
n.checked = true
|
||||
n.save
|
||||
end
|
||||
end
|
||||
end
|
|
@ -54,8 +54,26 @@
|
|||
</ul>
|
||||
|
||||
<div>
|
||||
<!-- help -->
|
||||
<!-- profile info -->
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#"
|
||||
id="notifications-dropdown"
|
||||
class="dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
role="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
data-href="<%= recent_notifications_url(current_user) %>">
|
||||
<%= fa_icon 'bell'%>
|
||||
<span id="count-notifications"
|
||||
data-href="<%= unseen_notification_url(current_user) %>"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-notifications">
|
||||
<li class="notifications-dropdown-header"><span><%= t('notifications.title') %></span><span class="pull-right"><%= t('nav.user.settings') %></span></li>
|
||||
<li class="notifications-dropdown-footer">link to method goes here</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" id="help-link" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-info-sign"></span>
|
||||
|
@ -69,10 +87,8 @@
|
|||
<li><%= link_to t('nav.help.contact'), CONTACT_URL, target: "_blank" %></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- profile info -->
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<span><%= t('nav.user_greeting', full_name: current_user.full_name) %></span>
|
||||
|
|
28
app/views/user_notifications/_recent_notifications.html.erb
Normal file
28
app/views/user_notifications/_recent_notifications.html.erb
Normal file
|
@ -0,0 +1,28 @@
|
|||
<% @recent_notifications.each do |notification| %>
|
||||
<li class="notification <%= 'unseen' unless notification.already_seen(current_user) %>">
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<% if notification.type_of == 'recent_changes' %>
|
||||
<div class="text-center">
|
||||
<%= image_tag avatar_path(notification.generator_user, :icon_small), class: 'avatar' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if notification.type_of == 'assignment' %>
|
||||
<div class="text-center">
|
||||
<span class="assignment"><%= fa_icon 'newspaper-o' %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if notification.type_of == 'system_message' %>
|
||||
<div class="text-center">
|
||||
<span class="system_message"><i class="glyphicon glyphicon-tower" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-10">
|
||||
<strong><%= notification.title.html_safe %></strong> <br>
|
||||
<%= l(notification.created_at, format: :full) %> | <%= notification.message %>
|
||||
</div>
|
||||
</div>
|
||||
<li>
|
||||
<% end %>
|
|
@ -1057,6 +1057,7 @@ en:
|
|||
delete_step_comment: "<i>%{user}</i> deleted comment on Step %{step} <strong>%{step_name}</strong>."
|
||||
edit_result_comment: "<i>%{user}</i> edited comment on result <strong>%{result}</strong>."
|
||||
delete_result_comment: "<i>%{user}</i> deleted comment on result <strong>%{result}</strong>."
|
||||
assign_user_to_organization: "<i>%{assigned_user}</i> was added as %{role} to organization <strong>%{organization}</strong> by <i>%{assigned_by_user}</i>."
|
||||
|
||||
user_my_modules:
|
||||
new:
|
||||
|
@ -1508,6 +1509,8 @@ en:
|
|||
sentence_seven_html: "<strong>Info tab</strong> <br>In the upper right corner of the Dashboard you can now access the Info button, where you can find links to support on how to use sciNote features (e.g., Tutorials, FAQ) or how to change your current sciNote Plan (e.g., Professional support and customization, Plans). In case you have some other questions or suggestions, click on the Contact us link."
|
||||
confim: "OK, got it"
|
||||
|
||||
notifications:
|
||||
title: "Notifications"
|
||||
# This section contains general words that can be used in any parts of
|
||||
# application.
|
||||
|
||||
|
|
|
@ -32,6 +32,17 @@ Rails.application.routes.draw do
|
|||
get "users/settings/user_organizations/:user_organization_id/destroy_html", to: "users/settings#destroy_user_organization_html", as: "destroy_user_organization_html"
|
||||
delete "users/settings/user_organizations/:user_organization_id", to: "users/settings#destroy_user_organization", as: "destroy_user_organization"
|
||||
|
||||
# Notifications
|
||||
get 'users/:id/recent_notifications',
|
||||
to: 'user_notifications#recent_notifications',
|
||||
as: 'recent_notifications',
|
||||
defaults: { format: 'json' }
|
||||
|
||||
get 'users/:id/unseen_notification',
|
||||
to: 'user_notifications#unseen_notification',
|
||||
as: 'unseen_notification',
|
||||
defaults: { format: 'json' }
|
||||
|
||||
resources :organizations, only: [] do
|
||||
resources :samples, only: [:new, :create]
|
||||
resources :sample_types, only: [:new, :create]
|
||||
|
|
14
db/migrate/20160928114119_create_notifications.rb
Normal file
14
db/migrate/20160928114119_create_notifications.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
class CreateNotifications < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :notifications do |t|
|
||||
t.string :title
|
||||
t.string :message
|
||||
t.integer :type_of, null: false
|
||||
t.integer :generator_user_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
add_index :notifications, :created_at
|
||||
add_foreign_key :notifications, :users, column: :generator_user_id
|
||||
end
|
||||
end
|
11
db/migrate/20160928114915_create_user_notifications.rb
Normal file
11
db/migrate/20160928114915_create_user_notifications.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class CreateUserNotifications < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :user_notifications do |t|
|
||||
t.belongs_to :user, index: true, foreign_key: true
|
||||
t.belongs_to :notification, index: true, foreign_key: true
|
||||
t.boolean :checked, default: false
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
27
db/schema.rb
27
db/schema.rb
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160809074757) do
|
||||
ActiveRecord::Schema.define(version: 20160928114915) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -226,6 +226,17 @@ ActiveRecord::Schema.define(version: 20160809074757) do
|
|||
add_index "my_modules", ["name"], name: "index_my_modules_on_name", using: :gist
|
||||
add_index "my_modules", ["restored_by_id"], name: "index_my_modules_on_restored_by_id", using: :btree
|
||||
|
||||
create_table "notifications", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.string "message"
|
||||
t.integer "type_of", null: false
|
||||
t.integer "generator_user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "notifications", ["created_at"], name: "index_notifications_on_created_at", using: :btree
|
||||
|
||||
create_table "organizations", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.datetime "created_at", null: false
|
||||
|
@ -578,6 +589,17 @@ ActiveRecord::Schema.define(version: 20160809074757) do
|
|||
add_index "user_my_modules", ["my_module_id"], name: "index_user_my_modules_on_my_module_id", using: :btree
|
||||
add_index "user_my_modules", ["user_id"], name: "index_user_my_modules_on_user_id", using: :btree
|
||||
|
||||
create_table "user_notifications", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "notification_id"
|
||||
t.boolean "checked", default: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "user_notifications", ["notification_id"], name: "index_user_notifications_on_notification_id", using: :btree
|
||||
add_index "user_notifications", ["user_id"], name: "index_user_notifications_on_user_id", using: :btree
|
||||
|
||||
create_table "user_organizations", force: :cascade do |t|
|
||||
t.integer "role", default: 1, null: false
|
||||
t.integer "user_id", null: false
|
||||
|
@ -681,6 +703,7 @@ ActiveRecord::Schema.define(version: 20160809074757) do
|
|||
add_foreign_key "my_modules", "users", column: "created_by_id"
|
||||
add_foreign_key "my_modules", "users", column: "last_modified_by_id"
|
||||
add_foreign_key "my_modules", "users", column: "restored_by_id"
|
||||
add_foreign_key "notifications", "users", column: "generator_user_id"
|
||||
add_foreign_key "organizations", "users", column: "created_by_id"
|
||||
add_foreign_key "organizations", "users", column: "last_modified_by_id"
|
||||
add_foreign_key "project_comments", "comments"
|
||||
|
@ -758,6 +781,8 @@ ActiveRecord::Schema.define(version: 20160809074757) do
|
|||
add_foreign_key "user_my_modules", "my_modules"
|
||||
add_foreign_key "user_my_modules", "users"
|
||||
add_foreign_key "user_my_modules", "users", column: "assigned_by_id"
|
||||
add_foreign_key "user_notifications", "notifications"
|
||||
add_foreign_key "user_notifications", "users"
|
||||
add_foreign_key "user_organizations", "organizations"
|
||||
add_foreign_key "user_organizations", "users"
|
||||
add_foreign_key "user_organizations", "users", column: "assigned_by_id"
|
||||
|
|
10
lib/tasks/notifications.rake
Normal file
10
lib/tasks/notifications.rake
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace :notifications do
|
||||
|
||||
desc 'Creates new system notification for all active users'
|
||||
task :new_release => :environment do
|
||||
include NotificationsHelper
|
||||
puts 'Creation of system notification for all active users with link to release notes'
|
||||
create_system_notification('New release', 'http://scinote.net/docs/release-notes/')
|
||||
end
|
||||
|
||||
end
|
11
test/fixtures/notifications.yml
vendored
Normal file
11
test/fixtures/notifications.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
title: MyString
|
||||
message: MyString
|
||||
type_of: 1
|
||||
|
||||
two:
|
||||
title: MyString
|
||||
message: MyString
|
||||
type_of: 1
|
11
test/fixtures/user_notifications.yml
vendored
Normal file
11
test/fixtures/user_notifications.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
user_id:
|
||||
notification_id:
|
||||
checked: false
|
||||
|
||||
two:
|
||||
user_id:
|
||||
notification_id:
|
||||
checked: false
|
12
test/models/notification_test.rb
Normal file
12
test/models/notification_test.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
require 'test_helper'
|
||||
|
||||
class NotificationTest < ActiveSupport::TestCase
|
||||
should have_db_column(:title).of_type(:string)
|
||||
should have_db_column(:message).of_type(:text)
|
||||
should have_db_column(:type_of).of_type(:integer)
|
||||
should have_db_column(:created_at).of_type(:datetime)
|
||||
should have_db_column(:updated_at).of_type(:datetime)
|
||||
|
||||
should have_many(:user_notifications)
|
||||
should have_many(:users)
|
||||
end
|
7
test/models/user_notification_test.rb
Normal file
7
test/models/user_notification_test.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require 'test_helper'
|
||||
|
||||
class UserNotificationTest < ActiveSupport::TestCase
|
||||
should have_db_column(:checked).of_type(:boolean)
|
||||
should belong_to(:user)
|
||||
should belong_to(:notification)
|
||||
end
|
Loading…
Add table
Reference in a new issue