Passing spec for user product information

This commit is contained in:
2014-04-23 17:06:46 +02:00
parent ea498cb9c5
commit 546e4499ea
42 changed files with 190 additions and 482 deletions
+3 -3
View File
@@ -21,9 +21,9 @@ group :assets do
gem 'sass-rails' #, '~> 4.0.2' gem 'sass-rails' #, '~> 4.0.2'
gem 'coffee-rails' #, '~> 3.2.1' gem 'coffee-rails' #, '~> 3.2.1'
#gem 'twitter-bootstrap-rails' #gem 'twitter-bootstrap-rails'
gem 'bootstrap-sass', '~>2.3' #gem 'bootstrap-sass', '~>2.3'
gem 'bourbon' #gem 'bourbon'
gem 'compass-rails' #gem 'compass-rails'
gem 'js-routes' gem 'js-routes'
gem "font-awesome-rails" gem "font-awesome-rails"
-13
View File
@@ -90,8 +90,6 @@ GEM
barber (>= 0.4.1) barber (>= 0.4.1)
emblem-source emblem-source
bcrypt (3.1.7) bcrypt (3.1.7)
bootstrap-sass (2.3.2.2)
sass (~> 3.2)
bourbon (3.2.0) bourbon (3.2.0)
sass (~> 3.2) sass (~> 3.2)
thor thor
@@ -105,7 +103,6 @@ GEM
capybara-webkit (1.1.0) capybara-webkit (1.1.0)
capybara (~> 2.0, >= 2.0.2) capybara (~> 2.0, >= 2.0.2)
json json
chunky_png (1.3.0)
climate_control (0.0.3) climate_control (0.0.3)
activesupport (>= 3.0) activesupport (>= 3.0)
cocaine (0.5.4) cocaine (0.5.4)
@@ -118,12 +115,6 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.7.0) coffee-script-source (1.7.0)
compass (0.12.6)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.2.19)
compass-rails (1.1.6)
compass (>= 0.12.2)
connection_pool (1.2.0) connection_pool (1.2.0)
cookiejar (0.3.2) cookiejar (0.3.2)
couchbase (1.3.7) couchbase (1.3.7)
@@ -201,7 +192,6 @@ GEM
foundation-rails (5.2.2.0) foundation-rails (5.2.2.0)
railties (>= 3.1.0) railties (>= 3.1.0)
sass (>= 3.2.0) sass (>= 3.2.0)
fssm (0.2.10)
fuubar (1.3.2) fuubar (1.3.2)
rspec (>= 2.14.0, < 3.1.0) rspec (>= 2.14.0, < 3.1.0)
ruby-progressbar (~> 1.3) ruby-progressbar (~> 1.3)
@@ -388,13 +378,10 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
active_decorator active_decorator
bootstrap-sass (~> 2.3)
bourbon
capybara capybara
capybara-webkit capybara-webkit
cmtool! cmtool!
coffee-rails coffee-rails
compass-rails
couch_potato! couch_potato!
couchbase couchbase
couchbase-docstore couchbase-docstore
+1 -1
View File
@@ -13,7 +13,7 @@
//= require jquery //= require jquery
//= require jquery_ujs //= require jquery_ujs
//= require jquery.ui.all //= require jquery.ui.all
//= require bootstrap // require bootstrap
// require twitter/bootstrap // require twitter/bootstrap
//= require_directory . //= require_directory .
//= require_self //= require_self
@@ -58,7 +58,7 @@ App.ApplicationController = Ember.Controller.extend
if list.get('join_requests').toArray().length if list.get('join_requests').toArray().length
@transitionToRoute 'join_requests' @transitionToRoute 'join_requests'
callback.call(@) if callback callback.call(@) if callback
error = (emberError)=> error = @ajaxError (emberError)=>
# if jqXHR.status == 404 officially, now assume close list on error # if jqXHR.status == 404 officially, now assume close list on error
#@redirect_to 'index', message: 'the_list_has_been_closed' #@redirect_to 'index', message: 'the_list_has_been_closed'
console.log "Error: #{emberError.message}" if emberError.message console.log "Error: #{emberError.message}" if emberError.message
@@ -1,10 +1,11 @@
ControllerExtensions = Ember.Mixin.create ControllerExtensions = Ember.Mixin.create
ajaxError: (callback)-> ajaxError: (callback)->
handler = (jqXHR, textStatus, errorThrown)=> handler = (emberError)=>
console.log "Error: #{textStatus}: #{errorThrown}" console.log "Error: status #{emberError.status}"
callback.call(@, jqXHR) if emberError.status == 401
if jqXHR.status == 401
App.__container__.lookup('route:application').unauthorized() App.__container__.lookup('route:application').unauthorized()
else
callback.call(@, emberError)
handler handler
showModal: (options={})-> showModal: (options={})->
$(document).foundation('reflow') # needed (stupid!!!) $(document).foundation('reflow') # needed (stupid!!!)
@@ -12,6 +13,7 @@ ControllerExtensions = Ember.Mixin.create
@set 'controllers.application.modal.title', options.title if options.title @set 'controllers.application.modal.title', options.title if options.title
@set 'controllers.application.modal.content', options.content if options.content @set 'controllers.application.modal.content', options.content if options.content
Ember.ArrayController.reopen ControllerExtensions Ember.ArrayController.reopen ControllerExtensions
Ember.Controller.reopen ControllerExtensions
Ember.Controller.reopen Ember.Controller.reopen
needs: ['application'] needs: ['application']
secured: (callback)-> secured: (callback)->
@@ -14,6 +14,7 @@ App.ApplicationRoute = Ember.Route.extend
Qstorage.setItem('auth_token', '') Qstorage.setItem('auth_token', '')
@controllerFor('application').set 'list', null @controllerFor('application').set 'list', null
App.obtain_token(t('messages.unauthorized')) App.obtain_token(t('messages.unauthorized'))
@controllerFor('application').redirect_to 'index', message: 'unauthorized'
actions: actions:
openModal: (modalName, model)-> openModal: (modalName, model)->
@controllerFor(modalName).set('model', model) @controllerFor(modalName).set('model', model)
@@ -59,6 +59,7 @@ header.top-menu
App.MenuItemListNeedsHelpView App.MenuItemListNeedsHelpView
App.MenuItemListNeedsPaymentView App.MenuItemListNeedsPaymentView
section.extra-info section.extra-info
if list
.supplier-info-row .supplier-info-row
.supplier-name= list.supplier.name .supplier-name= list.supplier.name
.table-number .table-number
@@ -45,7 +45,7 @@
hr hr
ul.product_category-products ul.product_category-products
each product in product_category.products each product in product_category.products
li li class="order-product-#{unbound product.id}"
if product.description if product.description
button.show-product-description{action showProductDescription product} button.show-product-description{action showProductDescription product}
span span
@@ -1,217 +0,0 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
// require bootstrap-transition
// require bootstrap-affix
// require bootstrap-alert
// require bootstrap-button
// require bootstrap-carousel
// require bootstrap-collapse
// require bootstrap-dropdown
// require bootstrap-modal
// require bootstrap-scrollspy
// require bootstrap-tab
// require bootstrap-tooltip
// require bootstrap-popover
// require bootstrap-typeahead
//= require bootstrap
//= require qwaiter
//= require supplier/order
//= require supplier/list
//= require mustache
//= require faye
//= require_directory .
//= require_self
var path_mapping = {
user_root: '/index',
join_occupied_table: '/join_occupied_table',
list_products_for_table: '/list_products_for_table',
list_products: '/list_products',
active_list: '/active_list',
history_list: '/history_list',
obtain_token: '/obtain_token',
lists_history: '/list_history'
}
var $translations = {
en: {
messages: <%= I18n.t('messages', locale: :en).to_json %>,
confirmations: {
},
// Moved to yml
list_needs_help: {
help_is_on_its_way: 'Help is already on its way',
title: 'Request a waiter',
content: 'Request a waiter to your table'
},
// Moved to yml
list_needs_payment: {
payment_already_requested: 'You already asked for the bill',
title: 'Ask for the check',
content: 'Do you want to pay?'
},
selected_products: {
order: 'Order',
clear: 'Clear'
},
join_request: {
title: 'Join request',
body: '%{email} wants to join the table',
reject: 'Reject',
approve: 'Approve',
requestor: {
title: 'This table is occupied',
go_back: 'Back',
show_the_products: 'Show the menu',
join_this_table: 'Join this table',
waiting_for_confirmation: 'Waiting for approval of the person on this table...'
}
},
// Moved to yml
move_table: {
cannot_move_to_occupied_table: 'You cannot move to an occupied table',
moved_to_another_table: 'The table is changed.',
confirmation_title: 'Move to another table?',
confirmation_body: 'Do you want to move to another table?'
},
models: <%= I18n.t('activemodel.models', locale: :en).to_json %>,
attributes: <%= I18n.t('activemodel.attributes', locale: :en).to_json %>,
<%= I18n.t('user', locale: :en).to_json[1..-2] %>
},
nl: {
messages: <%= I18n.t('messages', locale: :nl).to_json %>,
confirmations: {
},
// Moved to yml
list_needs_help: {
help_is_on_its_way: 'Er wordt al iemand naar je tafel gestuurd',
title: 'Ik heb een vraag',
content: 'Wil je een vraag stellen?'
},
// Moved to yml
list_needs_payment: {
payment_already_requested: 'De rekening is reeds gevraagd',
title: 'Vraag om de rekening',
content: 'Wil je betalen?'
},
selected_products: {
order: 'Bestellen',
clear: 'Leegmaken'
},
join_request: {
title: 'Lijst deling',
body: '%{email} wil ook op jouw lijst bestellen',
reject: 'Afwijzen',
approve: 'Toestaan',
requestor: {
title: 'Deze tafel is bezet',
go_back: 'Terug',
show_the_products: 'Toon het menu',
join_this_table: 'Ook bestellen aan deze tafel',
waiting_for_confirmation: 'Wachten op toestemming van huidige gebruikers om hier te kunnen bestellen...'
}
},
move_table: {
cannot_move_to_occupied_table: 'Je kan niet verhuizen naar een tafel die reeds gebruikt wordt.',
moved_to_another_table: 'De tafel is gewijzigd.',
confirmation_title: 'Naar een andere tafel verhuizen?',
confirmation_body: 'Wil je aan een andere tafel gaan zitten?'
},
models: <%= I18n.t('activemodel.models', locale: :nl).to_json %>,
attributes: <%= I18n.t('activemodel.attributes', locale: :nl).to_json %>,
<%= I18n.t('user', locale: :nl).to_json[1..-2] %>
}
}
function redirect_to(mapping, variables){
window.redirecting = true;
variables || (variables = {});
var vars = [];
for(var name in variables){
vars.push(name + '=' +variables[name]);
Qstorage.setItem(name, variables[name]);
}
window.location.href = QMobile.root_url() + path_mapping[mapping] + '.html'
}
function direct_to_site(mapping, variables){
variables || (variables = {});
var vars = []
for(var name in variables){
vars.push(name + '=' +variables[name])
}
window.location = data_host + path_mapping[mapping] + '.html?' + vars.join('&')
}
function currency(num) {
return Qwaiter.currency(num);
}
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
function t(path, vars){
vars || (vars = {});
var parts = path.split('.');
var locale = Qstorage.getItem('locale') || 'en';
var accessor = '$translations.'+locale+'["' + parts.join('"]["')+ '"]';
var result;
try{
result = eval(accessor);
} catch(err){
result = parts[parts.length - 1].capitalize();
}
if(!result) return parts[parts.length - 1].capitalize();
$.each(vars, function(v, value){ result = result.replace('%{'+v+'}', value)});
return result;
}
$.ajaxSetup({
error: function(xhr, ajaxOptions, error, another){
if(xhr.status == 401){
redirect_to('obtain_token');
}else if(xhr.status == 0){
QMobile.connection_problem();
}
}
});
$(function(){
if(Qstorage.getItem('message')){
var container = $('.alert-success');
var msg_finder = Qstorage.getItem('message');
if(msg_finder.indexOf('.') == -1) msg_finder = 'messages.'+msg_finder;
container.find('div').text(t(msg_finder));
container.show();
Qstorage.removeItem('message');
}
if(Qstorage.getItem('list_closed')){
var container = $('.alert-error');
container.find('div').text(t('messages.the_list_has_been_closed'));
container.show();
Qstorage.removeItem('list_closed');
}
setTranslations();
});
function setLocale(locale){
Qstorage.setItem('locale', locale);
setTranslations();
}
function Qupdate(selector){
setTranslations(selector);
}
function setTranslations(selector){
var list = $('#top-navigation-list');
var locale = Qstorage.getItem('locale');
list.find('.locale').show();
list.find('.locale-'+locale).hide();
if(selector){
$(selector).find('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
}else{
$('[data-t]').each(function(){$(this).text(t($(this).attr('data-t')))})
}
}
-136
View File
@@ -1,136 +0,0 @@
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
@@ -1,5 +1,3 @@
@import ./foundation_and_overrides
.form-row .form-row
@extend .row @extend .row
.form-label .form-label
@@ -1,6 +1,3 @@
@import constants
@import font-awesome
@import foundation_and_overrides
header.top-menu header.top-menu
height: 90px height: 90px
background-color: transparent background-color: transparent
@@ -0,0 +1,7 @@
//$qbrown: #634227
$qbrown: #853d15
$qbrown-active: lighten($qbrown, 20%)
$green: #7BB459 //Heineken
//$wood: image-url('textures/wood001-vertical.jpg')
$wood: image-url('textures/theme1.jpg')
$background-brown: #57351f
@@ -1,4 +1,3 @@
@import foundation
.home-panel .home-panel
+panel() +panel()
margin: 30px auto 20px auto margin: 30px auto 20px auto
@@ -1,4 +1,3 @@
@import ./foundation_and_overrides
.join-request-container .join-request-container
.user-email .user-email
padding-left: 12px padding-left: 12px
@@ -1,4 +1,3 @@
@import "foundation_and_overrides"
.lists-overview-entry .lists-overview-entry
+grid-column(12) +grid-column(12)
@media #{$medium-only} @media #{$medium-only}
@@ -0,0 +1,35 @@
ul.product_category-products
list-style: none
.product_category-title
cursor: pointer
.icon
@extend .fa
@extend .fa-arrow-down
color: #ccc
padding-right: 10px
&.collapsed
@extend .fa-arrow-right
.product_category-products
.product-price
float: right
.show-product-description
+button($bg: $secondary-color)
+button-icon-only
margin-right: 7px
span
@extend .fa
@extend .fa-info
@extend .fa-lg
.no-product-description
// Empty space to match the product description for layout
display: inline-block
width: 1.65rem
.add-product-to-list
+button($bg: $secondary-color)
+button-icon-only
float: right
margin-left: 5px
span
@extend .fa
@extend .fa-plus
@extend .fa-lg
@@ -1,5 +1,3 @@
@import foundation_and_overrides
@import font-awesome
ul.product-orders ul.product-orders
list-style: none list-style: none
li li
@@ -1,8 +1,5 @@
@import constants
@import font-awesome
@import foundation_and_overrides
#ember-app-container #ember-app-container
background-image: $wood background-image: image-url('textures/theme1.jpg')
background-repeat: repeat background-repeat: repeat
main.main-section main.main-section
+panel($bg:rgba(200,200,200,0.8)) +panel($bg:rgba(200,200,200,0.8))
@@ -1,3 +1,15 @@
//= require ./foundation_and_overrides @import ./qconstants
//= require font-awesome @import ./foundation_and_overrides
//= require_directory . @import font-awesome
@import constants
@import ./structure
@import ./menu_main
@import ./menu_side
@import ./qmodal
@import ./qproduct_orders
@import ./qproduct_categories
@import ./form_additions
@import ./qindex
@import ./qlists
@import ./qjoin_requests
@@ -13,8 +13,6 @@
// $rem-base: 16px; // $rem-base: 16px;
// Allows the use of rem-calc() or lower-bound() in your settings // Allows the use of rem-calc() or lower-bound() in your settings
a.unused-class
display: inline-block
@import "foundation/functions" @import "foundation/functions"
// $experimental: true; // $experimental: true;
@@ -1,4 +1,3 @@
@import constants
aside.side-menu aside.side-menu
background-color: #444 background-color: #444
position: fixed position: fixed
@@ -1,37 +0,0 @@
//@import ./foundation_and_overrides
//@import font-awesome
//ul.product_category-products
//list-style: none
//.product_category-title
//cursor: pointer
//.icon
//@extend .fa
//@extend .fa-arrow-down
//color: #ccc
//padding-right: 10px
//&.collapsed
//@extend .fa-arrow-right
//.product_category-products
//.product-price
//float: right
//.show-product-description
//+button($bg: $secondary-color)
//+button-icon-only
//margin-right: 7px
//span
//@extend .fa
//@extend .fa-info
//@extend .fa-lg
//.no-product-description
//// Empty space to match the product description for layout
//display: inline-block
//width: 1.65rem
//.add-product-to-list
//+button($bg: $secondary-color)
//+button-icon-only
//float: right
//margin-left: 5px
//span
//@extend .fa
//@extend .fa-plus
//@extend .fa-lg
+1 -1
View File
@@ -8,7 +8,7 @@ class DashboardController < ApplicationController
# Testing action # Testing action
def select_qrcode def select_qrcode
#@tables = Table.all.sample(2) | List.active.map(&:table) #@tables = Table.all.sample(2) | List.active.map(&:table)
@tables = Supplier.first.tables.sample(5) | List.active.map(&:table) @tables = (current_supplier || Supplier.first).tables.sample(5) | List.active.map(&:table)
respond_to do |format| respond_to do |format|
format.html { render layout: 'phone' } format.html { render layout: 'phone' }
format.json { render json: @tables.to_json } format.json { render json: @tables.to_json }
@@ -21,7 +21,7 @@ module Suppliers
respond_to do |format| respond_to do |format|
format.html # index.html.erb format.html # index.html.erb
format.json { render json: @lists } format.json { render json: @lists, each_serializer: ListSerializer }
end end
end end
+1
View File
@@ -29,6 +29,7 @@ class Product
private private
def persist_product_category_ids def persist_product_category_ids
return unless defined?(@product_category_ids) # Do not do anything if nothing happened to this attribute
@product_category_ids ||= [] @product_category_ids ||= []
existing_product_categories = product_categories existing_product_categories = product_categories
+1 -1
View File
@@ -1,4 +1,4 @@
class UserExtendedSupplierSerializer < Qwaiter::Serializer class UserSupplierSerializer < Qwaiter::Serializer
self.root = :supplier self.root = :supplier
attributes :extended_version, :open, :name attributes :extended_version, :open, :name
+1 -1
View File
@@ -101,7 +101,7 @@ module Qwaiter
# Enable the asset pipeline # Enable the asset pipeline
config.assets.enabled = true config.assets.enabled = true
config.assets.precompile += ['supplier/application.css', 'user/application.css', 'qr_sheet/application.css', 'waiter/application.css'] #config.assets.precompile += ['supplier/application.css', 'user/application.css', 'qr_sheet/application.css', 'waiter/application.css']
config.default_url_options = {format: 'html'} config.default_url_options = {format: 'html'}
config.to_prepare do config.to_prepare do
+5
View File
@@ -53,4 +53,9 @@ Qwaiter::Application.configure do
# Expands the lines which load the assets # Expands the lines which load the assets
config.assets.debug = true config.assets.debug = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
end end
+8 -4
View File
@@ -11,12 +11,13 @@ Qwaiter::Application.configure do
config.eager_load = true config.eager_load = true
# Full error reports are disabled and caching is turned on # Full error reports are disabled and caching is turned on
config.consider_all_requests_local = false config.consider_all_requests_local = true
config.action_controller.perform_caching = true config.action_controller.perform_caching = false
config.action_controller.action_on_unpermitted_parameters = :log config.action_controller.action_on_unpermitted_parameters = :log
# Disable Rails's static asset server (Apache or nginx will already do this) # Configure static asset server for tests with Cache-Control for performance.
config.serve_static_assets = false config.serve_static_assets = true
config.static_cache_control = 'public, max-age=3600'
# Compress JavaScripts and CSS # Compress JavaScripts and CSS
config.assets.compress = true config.assets.compress = true
@@ -85,4 +86,7 @@ Qwaiter::Application.configure do
# Log the query plan for queries taking more than this (works # Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL) # with SQLite, MySQL, and PostgreSQL)
# config.active_record.auto_explain_threshold_in_seconds = 0.5 # config.active_record.auto_explain_threshold_in_seconds = 0.5
#
# # Print deprecation notices to the stderr.
config.active_support.deprecation = :stder
end end
+3
View File
@@ -13,8 +13,11 @@ Qwaiter::Application.configure do
config.eager_load = true config.eager_load = true
# Configure static asset server for tests with Cache-Control for performance # Configure static asset server for tests with Cache-Control for performance
config.assets.compile = true
config.assets.digest = false
config.serve_static_assets = true config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600" config.static_cache_control = "public, max-age=3600"
config.assets.compress = false
config.ember.variant = :development config.ember.variant = :development
+22
View File
@@ -0,0 +1,22 @@
# Be sure to restart your server when you modify this file.
# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.
# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.
development:
secret_key_base: 9ec349cd45bb7bd16cdfa40d2deeeb39e8b287f23ac39aa64ded980af40fb002db5d1c9bdc91bc0ce1dc12f89c2ab86c07394c305fefffe2fb01fb00be281f4f
test:
secret_key_base: 0cef7a55e2fbd104a5cb4539434a628489f833c67c1386583ed2b89ffa492bf3b05e98547a72eda9760f9482c765e52b1ea3cc94b57394cdee5b3debfd7912ec
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
+14
View File
@@ -2,5 +2,19 @@ module Qwaiter
class Serializer < ActiveModel::Serializer class Serializer < ActiveModel::Serializer
attribute :_id, key: :id attribute :_id, key: :id
attributes :created_at, :updated_at attributes :created_at, :updated_at
# Bug in rails 4.1 serializing symbols in jsonify
def to_json(*args)
as_json.to_json(*args)
end
end
end
require 'active_model/array_serializer'
module ActiveModel
class ArraySerializer
# Bug in rails 4.1 serializing symbols in jsonify
def to_json(*args)
as_json.to_json(*args)
end
end end
end end
@@ -5,8 +5,7 @@ Feature: Getting product information during an order
Given There is an open supplier with a menu Given There is an open supplier with a menu
And the product 'Heineken beer' has description 'Brewed in Amsterdam' And the product 'Heineken beer' has description 'Brewed in Amsterdam'
And I am signed in as a user And I am signed in as a user
#And I open the debugger
And I am on the user homepage And I am on the user homepage
#When the user scans a table QR code When the user scans a table QR code
#And the user clicks on the more info button for the product with name 'Heineken beer' And the user clicks on the more info button for the product with name 'Heineken beer'
#Then the page should have content 'Brewed in Amsterdam' Then the user page should have product information 'Brewed in Amsterdam'
@@ -1,5 +1,6 @@
step "the product :product_name has description :product_description" do |product_name, product_description| step "the product :product_name has description :product_description" do |product_name, product_description|
product = @product && @product.name == product_name ? @product : Product.find_by_name(product_name) #product = @product && @product.name == product_name ? @product : Product.find_by_name(product_name)
product = Product.find_by_name(product_name)
product.description = product_description product.description = product_description
product.save or raise "Cannot save product: #{product.errors.full_messages.to_sentence}" product.save or raise "Cannot save product: #{product.errors.full_messages.to_sentence}"
@product ||= product @product ||= product
@@ -1,16 +1,3 @@
step "the user scans a table QR code" do
step 'there is a table'
page.execute_script "Quser.actions_for_table({table_id: '#{@table.id}'})"
end
step "another user scans the QR code on the table" do
step 'there is another signed in user user'
visit user_root_path
binding.pry
page.execute_script "Quser.actions_for_table({table_id: '#{@table.id}'})"
end
step 'there is a table' do step 'there is a table' do
step 'there is a section' step 'there is a section'
@table ||= create :table, section: @section, supplier: @supplier @table ||= create :table, section: @section, supplier: @supplier
@@ -1,3 +1,16 @@
step "the user scans a table QR code" do
step 'there is a table'
#page.execute_script "Quser.actions_for_table({table_id: '#{@table.id}'})"
page.execute_script "App.__container__.lookup('route:application').transitionTo('table','#{@table.id}')"
end
step "another user scans the QR code on the table" do
step 'there is another signed in user user'
visit user_root_path
#page.execute_script "Quser.actions_for_table({table_id: '#{@table.id}'})"
page.execute_script "App.__container__.lookup('route:application').transitionTo('table','#{@table.id}')"
end
step "I am on the user homepage" do step "I am on the user homepage" do
step "the user is on the homepage" step "the user is on the homepage"
end end
+9 -5
View File
@@ -1,11 +1,15 @@
step "There is an open supplier with a menu" do step "There is an open supplier with a menu" do
step 'there is a confirmed and open supplier' step 'there is a confirmed and open supplier'
@category_beer = create :product_category, name: 'Beer', supplier: @supplier
@category_lunch = create :product_category, name: 'Lunch', supplier: @supplier
@heineken_beer = create :product, name: 'Heineken beer', supplier: @supplier, price: 2.34
@apple_pie= create :product, name: 'Apple pie', supplier: @supplier, price: 4.28 @apple_pie= create :product, name: 'Apple pie', supplier: @supplier, price: 4.28
@heineken_beer.add_product_category @category_beer @heineken_beer = create :product, name: 'Heineken beer', supplier: @supplier, price: 2.34
@apple_pie.add_product_category @category_lunch
@category_beer = create :product_category, name: 'Beer', supplier: @supplier, product_ids: [@heineken_beer.id]
@category_lunch = create :product_category, name: 'Lunch', supplier: @supplier, product_ids: [@apple_pie.id]
#@heineken_beer.add_product_category @category_beer
#@category_beer.save
#@category_lunch.save
#@apple_pie.add_product_category @category_lunch
#@apple_pie.save
end end
step "the supplier is in :time_zone" do |time_zone| step "the supplier is in :time_zone" do |time_zone|
@@ -3,10 +3,6 @@ step "there is another table" do
@other_table = create :table, number: 89, section: @section, supplier: @supplier @other_table = create :table, number: 89, section: @section, supplier: @supplier
end end
step "the user scans a QR code of another not occupied table" do
page.execute_script "Quser.actions_for_table({table_id: '#{@other_table.id}'})"
end
step "the user should see a popup asking the user if he would like to change table" do step "the user should see a popup asking the user if he would like to change table" do
move_table_body = page.evaluate_script "t('move_table.confirmation_body')" move_table_body = page.evaluate_script "t('move_table.confirmation_body')"
move_table_body.should be_present move_table_body.should be_present
@@ -35,6 +31,10 @@ step "there is another table with an active list of another user" do
end end
step "the user scans a QR code of another not occupied table" do
page.execute_script "Quser.actions_for_table({table_id: '#{@other_table.id}'})"
end
step "the user scans a QR code of another occupied table" do step "the user scans a QR code of another occupied table" do
# same as not, since this is just a scan action. Whether the table # same as not, since this is just a scan action. Whether the table
# is occupied is a responsibility of other steps # is occupied is a responsibility of other steps
@@ -32,3 +32,7 @@ step "the user clicks on the more info button for the product with name :product
product = @product && @product.name == product_name ? @product : Product.find_by_name(product_name) product = @product && @product.name == product_name ? @product : Product.find_by_name(product_name)
find(".order-product-#{product.id} .show-product-description").click find(".order-product-#{product.id} .show-product-description").click
end end
step "the user page should have product information :product_description" do |product_description|
page.should have_content product_description
end
+12
View File
@@ -0,0 +1,12 @@
require 'spec_helper'
describe 'Serializers' do
let(:serializer_classes){ Dir.glob(Rails.root.join('app/serializers/*_serializer.rb')).map{|f| File.basename(f).sub(/\.rb$/,'').classify.constantize}}
describe 'classes' do
it 'inherits from Qwaiter::Serializer' do
serializer_classes.each do |serializer|
serializer.ancestors.should include Qwaiter::Serializer
end
end
end
end