mirror of
https://github.com/ENSL/ensl.org.git
synced 2025-01-14 13:51:26 +00:00
Merge pull request #15 from cblanc/shoutbox_tweaks
Shoutbox Client-side validation
This commit is contained in:
commit
bc3723191b
11 changed files with 255 additions and 68 deletions
|
@ -193,7 +193,7 @@ GEM
|
|||
rake (10.3.2)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
rmagick (2.13.2)
|
||||
rmagick (2.13.4)
|
||||
rspec-core (2.14.8)
|
||||
rspec-expectations (2.14.5)
|
||||
diff-lcs (>= 1.1.3, < 2.0)
|
||||
|
@ -298,7 +298,7 @@ DEPENDENCIES
|
|||
quiet_assets (~> 1.0.2)
|
||||
rails (~> 3.2.19)
|
||||
rails_autolink (~> 1.1.5)
|
||||
rmagick (~> 2.13.2)
|
||||
rmagick (~> 2.13.4)
|
||||
rspec-rails (~> 2.14.1)
|
||||
sanitize (~> 2.1.0)
|
||||
sass (~> 3.3.4)
|
||||
|
|
|
@ -6,43 +6,5 @@
|
|||
//= require tinymce-jquery
|
||||
//= require yetii
|
||||
//= require local
|
||||
//= require_self
|
||||
|
||||
$ ->
|
||||
$('#logout').click ->
|
||||
$(this).closest('form').submit()
|
||||
|
||||
$('select').each (i, el) ->
|
||||
$select = $(el)
|
||||
|
||||
$select.wrap '<div class="select-wrapper" />'
|
||||
$select.on 'DOMSubtreeModified', (event) ->
|
||||
$el = $(this)
|
||||
$wrapper = $el.parent()
|
||||
|
||||
if $el.is("[disabled]")
|
||||
$wrapper.addClass 'disabled'
|
||||
else
|
||||
$wrapper.removeClass 'disabled'
|
||||
|
||||
$select.trigger 'DOMSubtreeModified'
|
||||
|
||||
$('a[href=#form_submit]').click ->
|
||||
$(this).closest('form').submit()
|
||||
return false
|
||||
|
||||
$('select.autosubmit').change ->
|
||||
$(this).closest('form').submit()
|
||||
|
||||
$('#notification').delay(3000).fadeOut()
|
||||
|
||||
$('#steam-search a').click (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
$search = $('#steam-search')
|
||||
id = $search.data 'user-id'
|
||||
|
||||
$search.html "<p>Searching...</p>"
|
||||
|
||||
$.get "/api/v1/users/#{id}", (data) ->
|
||||
$search.html "<a href='#{data.steam.url}'>Steam Profile: #{data.steam.nickname}</a>"
|
||||
//= require shoutbox
|
||||
//= require misc
|
38
app/assets/javascripts/misc.js.coffee
Normal file
38
app/assets/javascripts/misc.js.coffee
Normal file
|
@ -0,0 +1,38 @@
|
|||
$ ->
|
||||
$('#logout').click ->
|
||||
$(this).closest('form').submit()
|
||||
|
||||
$('select').each (i, el) ->
|
||||
$select = $(el)
|
||||
|
||||
$select.wrap '<div class="select-wrapper" />'
|
||||
$select.on 'DOMSubtreeModified', (event) ->
|
||||
$el = $(this)
|
||||
$wrapper = $el.parent()
|
||||
|
||||
if $el.is("[disabled]")
|
||||
$wrapper.addClass 'disabled'
|
||||
else
|
||||
$wrapper.removeClass 'disabled'
|
||||
|
||||
$select.trigger 'DOMSubtreeModified'
|
||||
|
||||
$('a[href=#form_submit]').click ->
|
||||
$(this).closest('form').submit()
|
||||
return false
|
||||
|
||||
$('select.autosubmit').change ->
|
||||
$(this).closest('form').submit()
|
||||
|
||||
$('#notification').delay(3000).fadeOut()
|
||||
|
||||
$('#steam-search a').click (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
$search = $('#steam-search')
|
||||
id = $search.data 'user-id'
|
||||
|
||||
$search.html "<p>Searching...</p>"
|
||||
|
||||
$.get "/api/v1/users/#{id}", (data) ->
|
||||
$search.html "<a href='#{data.steam.url}'>Steam Profile: #{data.steam.nickname}</a>"
|
76
app/assets/javascripts/shoutbox.js
Normal file
76
app/assets/javascripts/shoutbox.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Shoutbox Controller manages input validation on shoutmsg form
|
||||
|
||||
function ShoutboxController (options) {
|
||||
if (!(this instanceof ShoutboxController)) {
|
||||
return new ShoutboxController(options);
|
||||
}
|
||||
this.options = options;
|
||||
this.$context = options.context;
|
||||
if (this.$context.length) {
|
||||
this.init(options);
|
||||
} else {
|
||||
console.log("Unable to initialize shoutbox controller. No context provided");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Initialise shoutbox state
|
||||
ShoutboxController.prototype.init = function (options) {
|
||||
var self = this;
|
||||
self.$input = self.$context.find(".shout_input");
|
||||
self.$button = self.$context.find('input[type="submit"]');
|
||||
self.$messageBox = null;
|
||||
self.$input.bind("keyup change", function () {
|
||||
if (self.$input.val().length > 100) {
|
||||
self.disableShoutbox();
|
||||
} else {
|
||||
self.enableShoutbox();
|
||||
}
|
||||
});
|
||||
return self;
|
||||
};
|
||||
|
||||
// Displays a message if `message` present, otherwise removes message elemt
|
||||
ShoutboxController.prototype.writeMessage = function (message) {
|
||||
if (message === undefined) return this.removeMessageBox();
|
||||
this.createMessageBox().html(message);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Adds message box to DOM and cache
|
||||
ShoutboxController.prototype.createMessageBox = function () {
|
||||
if (this.$messageBox) return this.$messageBox;
|
||||
this.$messageBox = $("<p/>", {class: "shout-warning"}).appendTo(this.$context.find(".fields"));
|
||||
return this.$messageBox;
|
||||
};
|
||||
|
||||
// Removes message box from DOM and cache
|
||||
ShoutboxController.prototype.removeMessageBox = function () {
|
||||
if (this.$messageBox) {
|
||||
this.$messageBox.remove();
|
||||
this.$messageBox = null;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
// Returns true if button is disabled
|
||||
ShoutboxController.prototype.isDisabled = function () {
|
||||
return this.$button.prop("disabled") === true;
|
||||
};
|
||||
|
||||
// Disables Input Button
|
||||
ShoutboxController.prototype.disableShoutbox = function () {
|
||||
var chars = this.$input.val().length;
|
||||
this.writeMessage(["Maximum shout length exceeded (",chars,"/100)"].join(""));
|
||||
this.$button.prop("disabled", true);
|
||||
};
|
||||
|
||||
// Removes any warnings and enableds shoutbox submit
|
||||
ShoutboxController.prototype.enableShoutbox = function () {
|
||||
if (!this.$button.prop("disabled")) {
|
||||
return this;
|
||||
}
|
||||
// Remove any warnings
|
||||
this.writeMessage();
|
||||
this.$button.prop("disabled", false);
|
||||
};
|
|
@ -29,11 +29,4 @@ class ShoutmsgsController < ApplicationController
|
|||
@shoutmsg.destroy
|
||||
redirect_to_back
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def render_shoutmsgs shoutable_type = nil, shoutable_id = nil
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,3 +17,11 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
ShoutboxController({
|
||||
context: $('<%= "#new_#{shoutmsg.domain}" %>')
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -3,4 +3,12 @@ FactoryGirl.define do
|
|||
sequence(:name) { |n| "Category #{n}" }
|
||||
sequence(:sort) { |n| n }
|
||||
end
|
||||
|
||||
trait :news do
|
||||
domain Category::DOMAIN_NEWS
|
||||
end
|
||||
|
||||
trait :game do
|
||||
domain Category::DOMAIN_GAMES
|
||||
end
|
||||
end
|
13
spec/factories/gather.rb
Normal file
13
spec/factories/gather.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
FactoryGirl.define do
|
||||
factory :gather do
|
||||
association :category, factory: [:category, :game]
|
||||
end
|
||||
|
||||
trait :running do
|
||||
status Gather::STATE_RUNNING
|
||||
end
|
||||
|
||||
trait :picking do
|
||||
status Gather::STATE_PICKING
|
||||
end
|
||||
end
|
37
spec/features/gathers/gathers_spec.rb
Normal file
37
spec/features/gathers/gathers_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'Gathers', js: true do
|
||||
let!(:user) { create :user }
|
||||
let!(:gather) { create :gather, :running }
|
||||
|
||||
feature 'Shoutbox' do
|
||||
background do
|
||||
sign_in_as user
|
||||
end
|
||||
|
||||
scenario 'create shout' do
|
||||
visit gather_path(gather)
|
||||
shout = rand(100000).to_s
|
||||
fill_in "shout_Gather_#{gather.id}_text", with: shout
|
||||
click_button 'Shout!'
|
||||
expect(page).to have_content(shout)
|
||||
end
|
||||
|
||||
scenario 'enter more than 100 characters' do
|
||||
valid_shout = 100.times.map { "a" }.join
|
||||
invalid_shout = 101.times.map { "a" }.join
|
||||
visit gather_path(gather)
|
||||
expect(page).to_not have_content("Maximum shout length exceeded")
|
||||
fill_in "shout_Gather_#{gather.id}_text", with: invalid_shout
|
||||
expect(page).to have_content("Maximum shout length exceeded")
|
||||
fill_in "shout_Gather_#{gather.id}_text", with: valid_shout
|
||||
expect(page).to_not have_content("Maximum shout length exceeded")
|
||||
end
|
||||
|
||||
scenario 'creating shout while banned' do
|
||||
Ban.create! ban_type: Ban::TYPE_MUTE, expiry: Time.now + 10.days, user_name: user.username
|
||||
visit root_path
|
||||
expect(find("#sidebar")).to have_content "You have been muted."
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +1,34 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'Shoutbox' do
|
||||
feature 'Shoutbox', js: true do
|
||||
let!(:user) { create :user }
|
||||
|
||||
background do
|
||||
@user = create :user
|
||||
sign_in_as @user
|
||||
visit root_path
|
||||
sign_in_as user
|
||||
end
|
||||
|
||||
feature 'user creates a shout', js: true do
|
||||
scenario 'shouting with valid content' do
|
||||
shout = rand(100000).to_s
|
||||
fill_in 'shoutbox_text', with: shout
|
||||
click_button 'Shout!'
|
||||
expect(page).to have_content(shout)
|
||||
end
|
||||
scenario 'creating a valid shout' do
|
||||
visit root_path
|
||||
shout = rand(100000).to_s
|
||||
fill_in 'shoutbox_text', with: shout
|
||||
click_button 'Shout!'
|
||||
expect(page).to have_content(shout)
|
||||
end
|
||||
|
||||
scenario 'unable to while banned' do
|
||||
@user.bans.create! ban_type: Ban::TYPE_MUTE, expiry: Time.now + 10.days
|
||||
shout = rand(100000).to_s
|
||||
fill_in 'shoutbox_text', with: shout
|
||||
click_button 'Shout!'
|
||||
expect(page).to_not have_content(shout)
|
||||
end
|
||||
scenario 'enter more than 100 characters' do
|
||||
valid_shout = 100.times.map { "a" }.join
|
||||
invalid_shout = 101.times.map { "a" }.join
|
||||
visit root_path
|
||||
expect(page).to_not have_content("Maximum shout length exceeded")
|
||||
fill_in 'shoutbox_text', with: invalid_shout
|
||||
expect(page).to have_content("Maximum shout length exceeded")
|
||||
fill_in 'shoutbox_text', with: valid_shout
|
||||
expect(page).to_not have_content("Maximum shout length exceeded")
|
||||
end
|
||||
|
||||
scenario 'creating shout while banned' do
|
||||
Ban.create! ban_type: Ban::TYPE_MUTE, expiry: Time.now + 10.days, user_name: user.username
|
||||
visit root_path
|
||||
expect(find("#sidebar")).to have_content "You have been muted."
|
||||
end
|
||||
end
|
44
spec/models/user_spec.rb
Normal file
44
spec/models/user_spec.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# username :string(255)
|
||||
# password :string(255)
|
||||
# firstname :string(255)
|
||||
# lastname :string(255)
|
||||
# email :string(255)
|
||||
# steamid :string(255)
|
||||
# team_id :integer
|
||||
# lastvisit :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# lastip :string(255)
|
||||
# country :string(255)
|
||||
# birthdate :date
|
||||
# time_zone :string(255)
|
||||
# version :integer
|
||||
# public_email :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
let!(:user) { create :user }
|
||||
|
||||
describe "#banned?" do
|
||||
it "returns false if user is not banned" do
|
||||
expect(user.banned?).to be_false
|
||||
end
|
||||
|
||||
it "returns true if user is banned" do
|
||||
ban = Ban.create! ban_type: Ban::TYPE_SITE, expiry: Time.now + 10.days, user_name: user.username
|
||||
expect(user.banned?).to be_true
|
||||
end
|
||||
|
||||
it "returns true for specific bans" do
|
||||
ban = Ban.create! ban_type: Ban::TYPE_MUTE, expiry: Time.now + 10.days, user_name: user.username
|
||||
expect(user.banned? Ban::TYPE_MUTE).to be_true
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue