office_clerk 0.0.1

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.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +73 -0
  3. data/.rubocop.yml +6 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +63 -0
  6. data/Gemfile.lock +367 -0
  7. data/Guardfile +28 -0
  8. data/README.md +44 -0
  9. data/Rakefile +6 -0
  10. data/app/assets/images/admin/baskets-2.jpg +0 -0
  11. data/app/assets/images/admin/baskets.jpg +0 -0
  12. data/app/assets/images/admin/categories-2.jpg +0 -0
  13. data/app/assets/images/admin/categories.jpg +0 -0
  14. data/app/assets/images/admin/clerks-2.jpg +0 -0
  15. data/app/assets/images/admin/clerks.jpg +0 -0
  16. data/app/assets/images/admin/orders-2.jpg +0 -0
  17. data/app/assets/images/admin/orders.jpg +0 -0
  18. data/app/assets/images/admin/products-2.jpg +0 -0
  19. data/app/assets/images/admin/products.jpg +0 -0
  20. data/app/assets/images/admin/purchases-2.jpg +0 -0
  21. data/app/assets/images/admin/purchases.jpg +0 -0
  22. data/app/assets/images/admin/suppliers-2.jpg +0 -0
  23. data/app/assets/images/admin/suppliers.jpg +0 -0
  24. data/app/assets/images/alpha.png +0 -0
  25. data/app/assets/images/down-icon.png +0 -0
  26. data/app/assets/images/header.gif +0 -0
  27. data/app/assets/images/hihih.jpg +0 -0
  28. data/app/assets/images/hue.png +0 -0
  29. data/app/assets/images/koe.jpg +0 -0
  30. data/app/assets/images/missing.png +0 -0
  31. data/app/assets/images/saturation.png +0 -0
  32. data/app/assets/images/shop/basket.jpg +0 -0
  33. data/app/assets/images/shop/farfalla-logo.jpg +0 -0
  34. data/app/assets/images/shop/header.gif +0 -0
  35. data/app/assets/images/shop/header.jpg +0 -0
  36. data/app/assets/images/shop/header.png +0 -0
  37. data/app/assets/images/shop/kansi.jpg +0 -0
  38. data/app/assets/images/shop/kansi.png +0 -0
  39. data/app/assets/images/shop/logo.png +0 -0
  40. data/app/assets/images/shop/menu-gourmet.jpg +0 -0
  41. data/app/assets/images/shop/menu-hius.jpg +0 -0
  42. data/app/assets/images/shop/menu-huonetuoksu.jpg +0 -0
  43. data/app/assets/images/shop/menu-info.jpg +0 -0
  44. data/app/assets/images/shop/menu-kasvo.jpg +0 -0
  45. data/app/assets/images/shop/menu-laukut.jpg +0 -0
  46. data/app/assets/images/shop/menu-luomu.jpg +0 -0
  47. data/app/assets/images/shop/menu-men.jpg +0 -0
  48. data/app/assets/images/shop/menu-oljy.jpg +0 -0
  49. data/app/assets/images/shop/menu-tuoksu1.jpg +0 -0
  50. data/app/assets/images/shop/menu-vaatteet.jpg +0 -0
  51. data/app/assets/images/shop/menu-valaisin.jpg +0 -0
  52. data/app/assets/images/shop/menu-vartalo.jpg +0 -0
  53. data/app/assets/images/shop/spacer.gif +0 -0
  54. data/app/assets/images/shop/tausta.jpg +0 -0
  55. data/app/assets/images/shop/tervetuloa.gif +0 -0
  56. data/app/assets/images/shop/valk.png +0 -0
  57. data/app/assets/images/shop/valk3.png +0 -0
  58. data/app/assets/images/shop/violetti-lev.jpg +0 -0
  59. data/app/assets/images/shop/violetti.jpg +0 -0
  60. data/app/assets/images/ui-anim_basic_16x16.gif +0 -0
  61. data/app/assets/images/up-icon.png +0 -0
  62. data/app/assets/javascripts/admin.js +29 -0
  63. data/app/assets/javascripts/shop.js +30 -0
  64. data/app/assets/stylesheets/admin.css.scss +129 -0
  65. data/app/assets/stylesheets/shop-receipt.css.scss +80 -0
  66. data/app/assets/stylesheets/shop.css.scss +403 -0
  67. data/app/controllers/admin_controller.rb +23 -0
  68. data/app/controllers/application_controller.rb +41 -0
  69. data/app/controllers/baskets_controller.rb +176 -0
  70. data/app/controllers/categories_controller.rb +69 -0
  71. data/app/controllers/clerks_controller.rb +64 -0
  72. data/app/controllers/orders_controller.rb +57 -0
  73. data/app/controllers/products_controller.rb +126 -0
  74. data/app/controllers/purchases_controller.rb +72 -0
  75. data/app/controllers/sessions_controller.rb +46 -0
  76. data/app/controllers/shop_controller.rb +90 -0
  77. data/app/controllers/suppliers_controller.rb +63 -0
  78. data/app/helpers/admin_helper.rb +28 -0
  79. data/app/helpers/application_helper.rb +25 -0
  80. data/app/helpers/baskets_helper.rb +4 -0
  81. data/app/helpers/categories_helper.rb +4 -0
  82. data/app/helpers/orders_helper.rb +4 -0
  83. data/app/helpers/products_helper.rb +4 -0
  84. data/app/helpers/purchases_helper.rb +4 -0
  85. data/app/helpers/shop_helper.rb +17 -0
  86. data/app/helpers/suppliers_helper.rb +4 -0
  87. data/app/mailers/.keep +0 -0
  88. data/app/models/basket.rb +114 -0
  89. data/app/models/category.rb +27 -0
  90. data/app/models/clerk.rb +46 -0
  91. data/app/models/item.rb +26 -0
  92. data/app/models/order.rb +72 -0
  93. data/app/models/product.rb +100 -0
  94. data/app/models/purchase.rb +26 -0
  95. data/app/models/supplier.rb +15 -0
  96. data/app/views/addresses/_form_fields.html.haml +4 -0
  97. data/app/views/addresses/show.html.haml +23 -0
  98. data/app/views/baskets/_small.html.haml +25 -0
  99. data/app/views/baskets/edit.html.haml +74 -0
  100. data/app/views/baskets/index.html.haml +55 -0
  101. data/app/views/baskets/show.html.haml +18 -0
  102. data/app/views/categories/_treeview.html.haml +8 -0
  103. data/app/views/categories/_triple.html.haml +12 -0
  104. data/app/views/categories/edit.html.haml +36 -0
  105. data/app/views/categories/index.html.haml +49 -0
  106. data/app/views/categories/show.html.haml +30 -0
  107. data/app/views/clerks/edit.html.haml +20 -0
  108. data/app/views/clerks/index.html.haml +37 -0
  109. data/app/views/clerks/show.html.haml +19 -0
  110. data/app/views/layouts/_admin_menu.html.haml +14 -0
  111. data/app/views/layouts/_google.haml +8 -0
  112. data/app/views/layouts/_messages.html.haml +5 -0
  113. data/app/views/layouts/admin.html.haml +42 -0
  114. data/app/views/layouts/shop.html.haml +96 -0
  115. data/app/views/orders/edit.html.haml +25 -0
  116. data/app/views/orders/index.html.haml +93 -0
  117. data/app/views/orders/show.html.haml +37 -0
  118. data/app/views/products/_line.html.haml +25 -0
  119. data/app/views/products/_name.html.haml +4 -0
  120. data/app/views/products/_online.html.haml +2 -0
  121. data/app/views/products/_triple.html.haml +12 -0
  122. data/app/views/products/edit.html.haml +42 -0
  123. data/app/views/products/index.html.haml +86 -0
  124. data/app/views/products/show.html.haml +94 -0
  125. data/app/views/purchases/edit.html.haml +9 -0
  126. data/app/views/purchases/index.html.haml +52 -0
  127. data/app/views/purchases/show.html.haml +32 -0
  128. data/app/views/sessions/new.html.haml +10 -0
  129. data/app/views/sessions/new_clerk.html.haml +22 -0
  130. data/app/views/shop/_groups.html.haml +8 -0
  131. data/app/views/shop/_menu.html.haml +5 -0
  132. data/app/views/shop/_sub.html.haml +0 -0
  133. data/app/views/shop/checkout.haml +142 -0
  134. data/app/views/shop/group.html.haml +9 -0
  135. data/app/views/shop/main_group.html.haml +9 -0
  136. data/app/views/shop/order.haml +104 -0
  137. data/app/views/shop/product.html.haml +67 -0
  138. data/app/views/shop/product_list.html.haml +50 -0
  139. data/app/views/shop/saved_search.html +6 -0
  140. data/app/views/shop/sub_group.html.haml +19 -0
  141. data/app/views/shop/tuotteista.html.haml +40 -0
  142. data/app/views/shop/welcome.html.haml +103 -0
  143. data/app/views/suppliers/edit.html.haml +10 -0
  144. data/app/views/suppliers/index.html.haml +40 -0
  145. data/app/views/suppliers/show.html.haml +27 -0
  146. data/bin/bundle +3 -0
  147. data/bin/rails +8 -0
  148. data/bin/rake +8 -0
  149. data/bin/rspec +7 -0
  150. data/bin/spring +18 -0
  151. data/config.ru +7 -0
  152. data/config/application.example.yml +13 -0
  153. data/config/application.rb +59 -0
  154. data/config/application.yml +13 -0
  155. data/config/boot.rb +7 -0
  156. data/config/database.yml +25 -0
  157. data/config/environment.rb +6 -0
  158. data/config/environments/development.rb +31 -0
  159. data/config/environments/production.rb +80 -0
  160. data/config/environments/test.rb +36 -0
  161. data/config/i18n-tasks.yml +11 -0
  162. data/config/initializers/attack.rb +32 -0
  163. data/config/initializers/backtrace_silencers.rb +7 -0
  164. data/config/initializers/filter_parameter_logging.rb +4 -0
  165. data/config/initializers/inflections.rb +16 -0
  166. data/config/initializers/migrate.rb +6 -0
  167. data/config/initializers/mime_types.rb +6 -0
  168. data/config/initializers/secret_token.rb +12 -0
  169. data/config/initializers/session_store.rb +3 -0
  170. data/config/initializers/simple_form.rb +149 -0
  171. data/config/initializers/simple_form_bootstrap.rb +48 -0
  172. data/config/initializers/wrap_parameters.rb +14 -0
  173. data/config/locales/config.yml +23 -0
  174. data/config/locales/en.yml +183 -0
  175. data/config/locales/fi.yml +211 -0
  176. data/config/routes.rb +108 -0
  177. data/db/migrate/20131224171442_clerks.rb +15 -0
  178. data/db/migrate/20131226110406_suppliers.rb +9 -0
  179. data/db/migrate/20131226143612_categories.rb +18 -0
  180. data/db/migrate/20131226143747_items.rb +14 -0
  181. data/db/migrate/20131226144134_orders.rb +21 -0
  182. data/db/migrate/20131226144316_baskets.rb +12 -0
  183. data/db/migrate/20131226151151_purchases.rb +11 -0
  184. data/db/migrate/20131226151332_products.rb +27 -0
  185. data/db/schema.rb +138 -0
  186. data/db/seeds.rb +4 -0
  187. data/lib/assets/.keep +0 -0
  188. data/lib/office_clerk.rb +20 -0
  189. data/lib/office_clerk/shipping_method.rb +35 -0
  190. data/lib/tasks/.keep +0 -0
  191. data/lib/tasks/import.rake +33 -0
  192. data/lib/templates/haml/scaffold/_form.html.haml +8 -0
  193. data/office_clerk.gemspec +46 -0
  194. data/public/404.html +58 -0
  195. data/public/422.html +58 -0
  196. data/public/500.html +57 -0
  197. data/public/favicon.ico +0 -0
  198. data/public/humans.txt +20 -0
  199. data/public/robots.txt +5 -0
  200. data/spec/controllers/baskets_controller_spec.rb +112 -0
  201. data/spec/controllers/categories_controller_spec.rb +133 -0
  202. data/spec/controllers/clerks_controller_spec.rb +70 -0
  203. data/spec/controllers/orders_controller_spec.rb +105 -0
  204. data/spec/controllers/products_controller_spec.rb +138 -0
  205. data/spec/controllers/purchases_controller_spec.rb +123 -0
  206. data/spec/controllers/sessions_controller_spec.rb +18 -0
  207. data/spec/controllers/suppliers_controller_spec.rb +137 -0
  208. data/spec/factories/addresses.rb +11 -0
  209. data/spec/factories/baskets.rb +15 -0
  210. data/spec/factories/categories.rb +8 -0
  211. data/spec/factories/clerks.rb +15 -0
  212. data/spec/factories/items.rb +19 -0
  213. data/spec/factories/orders.rb +9 -0
  214. data/spec/factories/products.rb +10 -0
  215. data/spec/factories/purchases.rb +10 -0
  216. data/spec/factories/suppliers.rb +7 -0
  217. data/spec/features/baskets/buttons_spec.rb +35 -0
  218. data/spec/features/baskets/edit_spec.rb +50 -0
  219. data/spec/features/baskets/index_spec.rb +12 -0
  220. data/spec/features/baskets/search_spec.rb +33 -0
  221. data/spec/features/baskets/show_spec.rb +21 -0
  222. data/spec/features/categories_spec.rb +21 -0
  223. data/spec/features/clerks_spec.rb +21 -0
  224. data/spec/features/orders_spec.rb +14 -0
  225. data/spec/features/products/index_spec.rb +30 -0
  226. data/spec/features/products/new_spec.rb +20 -0
  227. data/spec/features/purchases_spec.rb +14 -0
  228. data/spec/features/shops_spec.rb +18 -0
  229. data/spec/features/suppliers_spec.rb +18 -0
  230. data/spec/models/baskets/inventory_spec.rb +34 -0
  231. data/spec/models/baskets/items_spec.rb +37 -0
  232. data/spec/models/baskets/products_spec.rb +31 -0
  233. data/spec/models/category_spec.rb +18 -0
  234. data/spec/models/clerk/email_spec.rb +69 -0
  235. data/spec/models/clerk/password_spec.rb +83 -0
  236. data/spec/models/item_spec.rb +33 -0
  237. data/spec/models/locale_spec.rb +17 -0
  238. data/spec/models/order_spec.rb +19 -0
  239. data/spec/models/product_spec.rb +29 -0
  240. data/spec/models/purchase_spec.rb +8 -0
  241. data/spec/models/supplier_spec.rb +8 -0
  242. data/spec/routing/baskets_routing_spec.rb +35 -0
  243. data/spec/routing/categories_routing_spec.rb +35 -0
  244. data/spec/routing/orders_routing_spec.rb +35 -0
  245. data/spec/routing/products_routing_spec.rb +35 -0
  246. data/spec/routing/purchases_routing_spec.rb +35 -0
  247. data/spec/routing/suppliers_routing_spec.rb +35 -0
  248. data/spec/spec_helper.rb +74 -0
  249. data/spec/support/request_helper.rb +31 -0
  250. data/test/fixtures/baskets.yml +41993 -0
  251. data/test/fixtures/categories.yml +638 -0
  252. data/test/fixtures/clerks.yml +694 -0
  253. data/test/fixtures/items.yml +83651 -0
  254. data/test/fixtures/orders.yml +58918 -0
  255. data/test/fixtures/products.yml +110904 -0
  256. data/test/fixtures/purchases.yml +1755 -0
  257. data/test/fixtures/suppliers.yml +341 -0
  258. data/todo +8 -0
  259. metadata +607 -0
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Orders" do
4
+ before(:each) do
5
+ sign_in
6
+ end
7
+ it "lists orders" do
8
+ visit_path orders_path
9
+ end
10
+ it "should render" do
11
+ order = create :order
12
+ visit_path order_path order
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe "GET /products" do
4
+ before :each do
5
+ sign_in
6
+ visit_path products_path
7
+ end
8
+ it "lists products" do
9
+ end
10
+ end
11
+ describe "product filtering" do
12
+ before :each do
13
+ 20.times { create :product }
14
+ sign_in
15
+ visit products_path
16
+ end
17
+ it "filters by price" do
18
+ fill_in "q[price_lteq]", :with => '10'
19
+ click_button( I18n.t(:filter))
20
+ end
21
+ end
22
+ describe "edit product" do
23
+ before :each do
24
+ sign_in
25
+ end
26
+ it "renders" do
27
+ product = create :product
28
+ visit_path edit_product_path(product)
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ feature "new product" do
4
+ before :each do
5
+ sign_in
6
+ visit_path new_product_path
7
+ expect(page).to have_content I18n.t(:product)
8
+ fill_in "product[name]", :with => 'product 12'
9
+ fill_in "product[price]", :with => '12'
10
+ end
11
+ it "submits ok" do
12
+ click_button( I18n.t(:create))
13
+ expect(page).to have_content I18n.t(:create_success)
14
+ end
15
+ scenario "redirects ok" do
16
+ fill_in "product_price", :with => ''
17
+ click_button( I18n.t(:create))
18
+ expect(page).to have_content I18n.t("errors.messages.not_a_number")
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Purchases" do
4
+ before(:each) do
5
+ sign_in
6
+ end
7
+ it "lists purchases" do
8
+ visit_path purchases_path
9
+ end
10
+ it "shows" do
11
+ purchase = create(:purchase)
12
+ visit_path purchase_path(purchase)
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Shops" do
4
+ describe "GET /prod" do
5
+ it "get something" do
6
+ p = create :product , :online => true
7
+ g = create :category
8
+ visit_path shop_product_path(:link => p.link)
9
+ expect(status_code).to be(200)
10
+ end
11
+
12
+ it "redirects for wrong input" do
13
+ visit shop_product_path(:link => "nonexistant")
14
+ expect(page.current_path).to include "group"
15
+ expect(status_code).to be(200)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Suppliers" do
4
+ before(:each) do
5
+ sign_in
6
+ end
7
+ it "lists suppliers" do
8
+ visit_path suppliers_path
9
+ end
10
+ it "shows" do
11
+ s = create(:supplier)
12
+ visit_path supplier_path(s)
13
+ end
14
+ it "edits" do
15
+ s = create(:supplier)
16
+ visit_path edit_supplier_path(s)
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Basket inventory" do
4
+ it "deducts ok and adjusts inventory" do
5
+ basket = create :basket_2_items
6
+ inv1 = basket.items.first.product.inventory - basket.items.first.quantity
7
+ inv2 = basket.items.last.product.inventory - basket.items.last.quantity
8
+ expect(basket.deduct!).to be 3
9
+ basket.reload
10
+ expect(basket.items.first.product.inventory).to eq inv1
11
+ expect(basket.items.last.product.inventory).to eq inv2
12
+ end
13
+ it "receives ok and adjusts inventory" do
14
+ basket = create :basket_2_items
15
+ inv1 = basket.items.first.product.inventory + basket.items.first.quantity
16
+ inv2 = basket.items.last.product.inventory + basket.items.last.quantity
17
+ expect(basket.receive!).to be 3
18
+ basket.reload
19
+ expect(basket.items.first.product.inventory).to eq inv1
20
+ expect(basket.items.last.product.inventory).to eq inv2
21
+ end
22
+ it "locks after receive" do
23
+ basket = create :basket_2_items
24
+ expect(basket.receive!).to be 3
25
+ expect(basket.locked).not_to be nil
26
+ expect { basket.receive! }.to raise_error
27
+ end
28
+ it "locks after deduct" do
29
+ basket = create :basket_2_items
30
+ basket.deduct!
31
+ expect(basket.locked).not_to be nil
32
+ expect { basket.deduct! }.to raise_error
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Basket totals" do
4
+ it "creates proper quantities" do
5
+ basket = create :basket_3_items
6
+ end
7
+
8
+ it "calculates tax for 2" do
9
+ basket = create :basket_2_items
10
+ expect(basket.items.length).to be 2
11
+ taxes = basket.taxes
12
+ expect(taxes.values.first).to eq basket.total_tax.to_f
13
+ end
14
+ it "updates total on add" do
15
+ basket = create :basket_2_items
16
+ items = basket.items
17
+ total = items.first.price * items.first.quantity + items.last.price * items.last.quantity
18
+ expect(basket.total_price).to eq total
19
+ # assume the same tax (as per factory)
20
+ expect(basket.total_tax).to eq total * items.first.tax / 100
21
+ end
22
+ it "updates total on destroy" do
23
+ basket = create :basket_2_items
24
+ total = basket.items.first.price
25
+ tax = total * basket.items.first.tax / 100
26
+ basket.items.delete basket.items.last
27
+ basket.save!
28
+ expect(basket.total_price).to eq total
29
+ expect(basket.total_tax).to eq tax
30
+ end
31
+ it "destroys" do
32
+ basket = create :basket_2_items
33
+ basket.items.delete basket.items.last
34
+ basket.save!
35
+ expect(basket.items.length).to be 1
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Basket do
4
+ it "creates basket" do
5
+ basket = build :basket
6
+ expect(basket.save).to be true
7
+ expect(basket.total_tax).to eq(0.0)
8
+ expect(basket.total_price).to eq(0.0)
9
+ end
10
+ it "adds a product" do
11
+ basket = create :basket
12
+ expect(basket.items.length).to be 0
13
+ product = create :product
14
+ basket.add_product product
15
+ expect(basket.items.length).to be 1
16
+ expect(basket.items.first.quantity).to be 1
17
+ end
18
+ it "adds 2 products without duplication" do
19
+ basket = create :basket
20
+ prod = create :product
21
+ basket.add_product prod
22
+ basket.add_product prod
23
+ expect(basket.items.length).to be 1
24
+ expect(basket.items.first.quantity).to be 2
25
+ end
26
+ it "adds nil" do
27
+ basket = create :basket
28
+ basket.add_product nil
29
+ expect(basket.items.length).to be 0
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Category do
4
+ it "validates a name" do
5
+ pro = Category.new
6
+ expect(pro.save).to be false
7
+ end
8
+
9
+ it "saves ok" do
10
+ pro = Category.new :name => "some name"
11
+ expect(pro.save).to be true
12
+ end
13
+
14
+ it "factory works" do
15
+ pro = build :category
16
+ expect(pro.save).to be true
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clerk do
4
+
5
+ it "should create a new instance given a valid attribute" do
6
+ create(:clerk)
7
+ end
8
+
9
+ it "should require an email address" do
10
+ no_email_clerk = build(:clerk , :email => "")
11
+ expect(no_email_clerk).not_to be_valid
12
+ end
13
+
14
+ it "should accept valid email addresses" do
15
+ addresses = %w[clerk@foo.com THE_USER@foo.bar.org first.last@foo.jp]
16
+ addresses.each do |address|
17
+ valid_email_clerk = create(:clerk , :email => address)
18
+ expect(valid_email_clerk.valid?).to be true
19
+ end
20
+ end
21
+
22
+ it "should reject invalid email addresses" do
23
+ addresses = %w[clerk@foo,com clerk_at_foo.org example.clerk@foo.]
24
+ addresses.each do |address|
25
+ invalid_email_clerk = build(:clerk , :email => address)
26
+ expect(invalid_email_clerk).not_to be_valid
27
+ end
28
+ end
29
+
30
+ it "should reject duplicate email addresses" do
31
+ create(:clerk , :email => "sama@sama.net")
32
+ clerk_with_duplicate_email = build(:clerk , :email => "sama@sama.net")
33
+ clerk_with_duplicate_email.save
34
+ expect(clerk_with_duplicate_email).not_to be_valid
35
+ end
36
+
37
+ it "should reject email addresses identical up to case" do
38
+ upcased_email = "BIGMAIL@MAIL.com"
39
+ create(:clerk ,:email => upcased_email)
40
+ clerk_with_duplicate_email = build(:clerk , :email => upcased_email.downcase )
41
+ clerk_with_duplicate_email.save
42
+ #should work but doesn, postponed
43
+ # clerk_with_duplicate_email.not_to be_valid
44
+ end
45
+
46
+
47
+ it "should be valid" do
48
+ expect(create(:clerk).valid?).to be true
49
+ end
50
+
51
+ it "should require well formed email" do
52
+ clerk = build(:clerk, :email => 'foo@bar@example.com')
53
+ clerk.save
54
+ expect(clerk.errors[:email]).not_to be nil
55
+ end
56
+
57
+ it "should validate uniqueness of email" do
58
+ create(:clerk, :email => 'bar@example.com').save!
59
+ clerk = build(:clerk, :email => 'bar@example.com')
60
+ clerk.save
61
+ expect(clerk.errors[:email]).not_to be nil
62
+ end
63
+
64
+ # would be nice, just doesn't work yet
65
+ # it "should not allow odd characters in name" do
66
+ # create(:clerk, :name => 'odd ^&(@)').should have(1).error_on(:name)
67
+ # end
68
+
69
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clerk do
4
+
5
+ describe "passwords" do
6
+
7
+ it "should have a password attribute" do
8
+ expect(create(:clerk)).to respond_to(:password)
9
+ end
10
+
11
+ it "should have a password confirmation attribute" do
12
+ expect(create(:clerk)).to respond_to(:password_confirmation)
13
+ end
14
+ end
15
+
16
+ describe "password validations" do
17
+
18
+ it "should require a password" do
19
+ cl = build(:clerk , :password => "", :password_confirmation => "")
20
+ expect(cl).not_to be_valid
21
+ end
22
+
23
+ it "should require a matching password confirmation" do
24
+ clerk = build(:clerk , :password_confirmation => "invalid")
25
+ expect(clerk).not_to be_valid
26
+ end
27
+
28
+ end
29
+
30
+ describe "password encryption" do
31
+
32
+ it "should have an encrypted password attribute" do
33
+ expect(create(:clerk)).to respond_to(:encrypted_password)
34
+ end
35
+
36
+ it "should set the encrypted password attribute" do
37
+ expect(create(:clerk).encrypted_password).not_to be_blank
38
+ end
39
+
40
+ end
41
+
42
+ it "should require password" do
43
+ clerk = build(:clerk , :password => '')
44
+ clerk.save
45
+ expect(clerk.errors[:password]).not_to be nil
46
+ end
47
+
48
+
49
+ # would be nice, just doesn't work yet
50
+ # it "should not allow odd characters in name" do
51
+ # create(:clerk, :name => 'odd ^&(@)').should have(1).error_on(:name)
52
+ # end
53
+
54
+ it "should validate password is longer than 3 characters" do
55
+ clerk = build(:clerk, :password => 'bad')
56
+ clerk.save
57
+ expect(clerk.errors[:password]).not_to be nil
58
+ end
59
+
60
+ it "should require matching password confirmation" do
61
+ clerk = build(:clerk, :password_confirmation => 'nonmatching')
62
+ clerk.save
63
+ expect(clerk.errors[:password]).not_to be_nil
64
+ end
65
+
66
+ it "should generate password hash and salt on create" do
67
+ clerk = create(:clerk)
68
+ clerk.save!
69
+ expect(clerk.encrypted_password).not_to be nil
70
+ expect(clerk.password_salt).not_to be_nil
71
+ end
72
+
73
+ it "should authenticate" do
74
+ clerk = create(:clerk)
75
+ expect(clerk.valid_password?('password')).to be true
76
+ end
77
+
78
+ it "should not authenticate bad password" do
79
+ clerk = create(:clerk)
80
+ expect(clerk.valid_password?('badpassword')).to be false
81
+ end
82
+
83
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Item do
4
+ it "saves factory" do
5
+ i = build :item
6
+ expect(i.save).to be true
7
+ end
8
+ it "has quantity" do
9
+ item = create :item
10
+ expect(item.quantity).to be 1
11
+ item2 = create :item22
12
+ expect(item2.quantity).to be 2
13
+ expect(item.name).not_to eq item2.name
14
+ end
15
+
16
+ it "calcualtes taxes" do
17
+ [create(:item) , create(:item2) , create(:item22)].each do |c|
18
+ expect(c.tax_amount).to eq ((c.tax * c.price*c.quantity) / 100.0).round(2)
19
+ end
20
+ end
21
+ it "calcualtes total" do
22
+ [create(:item) , create(:item2) , create(:item22)].each do |c|
23
+ expect(c.total).to eq (c.quantity * c.price).round(2)
24
+ end
25
+ end
26
+ it "has products" do
27
+ [create(:item) , create(:item2) , create(:item22)].each do |c|
28
+ expect(c.product.full_name).not_to be blank?
29
+ expect(c.product.price).not_to be nil
30
+ expect(c.product.tax).not_to be nil
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ require "i18n-spec"
2
+
3
+ RSpec.describe 'locale:' do
4
+
5
+ Dir.glob('config/locales/*.yml') do |locale_file|
6
+ next if locale_file == "config/locales/config.yml"
7
+ context locale_file do
8
+ it { is_expected.to be_parseable }
9
+ it { is_expected.to have_valid_pluralization_keys }
10
+ it { is_expected.not_to have_missing_pluralization_keys }
11
+ it { is_expected.to have_one_top_level_namespace }
12
+ it { is_expected.not_to have_legacy_interpolations }
13
+ it { is_expected.to have_a_valid_locale }
14
+ it { is_expected.to be_a_complete_translation_of 'config/locales/en.yml' }
15
+ end
16
+ end
17
+ end