Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to make tests more consistent #1565

Merged
merged 37 commits into from
Dec 21, 2016
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
dc7f7cf
Fixes to inventory tests
brent-hoover Aug 11, 2016
2db705b
Create new versions of cart fixtures that create less "random" versio…
brent-hoover Aug 12, 2016
4216401
Eliminate unneeded originals entries
brent-hoover Aug 12, 2016
e5e9712
Put expectations in callbacks rather than putting in sleeps
brent-hoover Aug 12, 2016
ebeccbc
Make this global wait more visible
brent-hoover Aug 12, 2016
81af995
Merge branch 'development' into brent-inventory-tests-stage2
brent-hoover Aug 16, 2016
689519d
The quantity on remove quantity should always be 1 now that we are us…
brent-hoover Aug 16, 2016
1600a86
Allow direct importing of inventory function
brent-hoover Aug 17, 2016
4cc48f2
creating createCart function
brent-hoover Aug 17, 2016
2e93d6c
test for createCart function
brent-hoover Aug 17, 2016
00b61db
Directly call registerInventory to avoid permissions check that doesn…
brent-hoover Aug 17, 2016
721f386
Add singleVariant version of addProduct
brent-hoover Aug 17, 2016
c78a35b
Trying to get these tests to run reliably by trying to normalize the …
brent-hoover Aug 17, 2016
aa0c479
createCart function
brent-hoover Aug 17, 2016
754ae97
test for createCart function
brent-hoover Aug 17, 2016
3d473e6
Change currency symbol for PHP (wut?)
brent-hoover Aug 17, 2016
9ab7b5c
Db-normalized inventory tests
brent-hoover Aug 17, 2016
13736c1
Just blindly increase this timeout
brent-hoover Aug 17, 2016
52d32e2
Add comment explaining why we need this long timeout
brent-hoover Aug 17, 2016
68fa01d
Remove Logger
brent-hoover Aug 17, 2016
cf704b5
Merge branch 'development' into brent-inventory-tests-stage2
brent-hoover Sep 19, 2016
4259e90
Merge branch 'development' into brent-inventory-tests-stage2
brent-hoover Sep 20, 2016
1c5bd14
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
brent-hoover Nov 11, 2016
1e90a19
Extend timeout on cart test
brent-hoover Nov 11, 2016
dc03a3c
Add sleep for createVariant tests
brent-hoover Nov 11, 2016
85efcdb
Quiet inventory register logging that I should not have put there anyway
brent-hoover Nov 11, 2016
f7023af
Don't operate on product if it's not found
brent-hoover Nov 11, 2016
8b08831
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
brent-hoover Nov 11, 2016
92e1e9a
Update to fixed publication-collector
brent-hoover Nov 11, 2016
dde3153
Increase timeout on discount test
brent-hoover Nov 11, 2016
a801613
Update publication-collector
brent-hoover Nov 11, 2016
74e50b5
Don't call Alert in a server method
brent-hoover Nov 11, 2016
4f50e4c
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
brent-hoover Nov 21, 2016
ea14652
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
brent-hoover Dec 6, 2016
37c5856
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
brent-hoover Dec 20, 2016
7ba926b
Merge branch 'release-0.18.0' into brent-inventory-tests-stage2
Dec 21, 2016
bbfb815
Lint cleanup
Dec 21, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,14 @@ tmeasday:publish-counts
vsivsi:job-collection
react-meteor-data
percolate:migrations
johanbrook:[email protected]


# Testing packages
dburles:factory
dispatch:mocha
practicalmeteor:chai
practicalmeteor:sinon
johanbrook:publication-collector

# Performance & Debugging Tools
# meteorhacks:fast-render # improve initial page loads
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe("discounts methods", function () {
// });

it("should delete rate with discounts permission", function (done) {
this.timeout(5000);
sandbox.stub(Roles, "userIsInRole", () => true);
const discountInsertSpy = sandbox.spy(Discounts, "insert");
const discountId = Meteor.call("discounts/addRate", rate);
Expand Down
1 change: 0 additions & 1 deletion imports/plugins/included/inventory/server/hooks/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ Products.after.insert((userId, doc) => {
if (doc.type !== "variant") {
return false;
}
// Meteor.call("inventory/register", doc);
registerInventory(doc);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,43 @@
/* eslint dot-notation: 0 */
import { Meteor } from "meteor/meteor";
import { Inventory, Orders, Cart } from "/lib/collections";
import { Reaction, Logger } from "/server/api";
import { Inventory, Orders, Products } from "/lib/collections";
import { Reaction } from "/server/api";
import { expect } from "meteor/practicalmeteor:chai";
import { sinon } from "meteor/practicalmeteor:sinon";
import Fixtures from "/server/imports/fixtures";
import { getShop } from "/server/imports/fixtures/shops";
import { createCart } from "/server/imports/fixtures/cart";
import { addProductSingleVariant } from "/server/imports/fixtures/products";
import { registerInventory } from "../methods/inventory";

Fixtures();

function reduceCart(cart) {
Cart.update(cart._id, {
$set: {
"items.0.quantity": 1
}
});
Cart.update(cart._id, {
$set: {
"items.1.quantity": 1
}
});
Cart.update(cart._id, {
$pull: {
"items.$.quantity": { $gt: 1 }
}
});

function resetInventory() {
Inventory.remove({});
const products = Products.find().fetch();
for (let product of products) {
registerInventory(product);
}
}

describe("Inventory Hooks", function () {
this.timeout(50000);
let originals;
let sandbox;
let cart;

before(function () {
originals = {
mergeCart: Meteor.server.method_handlers["cart/mergeCart"],
createCart: Meteor.server.method_handlers["cart/createCart"],
copyCartToOrder: Meteor.server.method_handlers["cart/copyCartToOrder"],
addToCart: Meteor.server.method_handlers["cart/addToCart"],
setShipmentAddress: Meteor.server.method_handlers["cart/setShipmentAddress"],
setPaymentAddress: Meteor.server.method_handlers["cart/setPaymentAddress"]
copyCartToOrder: Meteor.server.method_handlers["cart/copyCartToOrder"]
};
});

beforeEach(function () {
sandbox = sinon.sandbox.create();
Products.direct.remove({});
const { product, variant } = addProductSingleVariant();
cart = createCart(product._id, variant._id);
resetInventory();
});

afterEach(function () {
Expand All @@ -61,27 +55,20 @@ describe("Inventory Hooks", function () {
it("should move allocated inventory to 'sold' when an order is created", function () {
sandbox.stub(Meteor.server.method_handlers, "orders/sendNotification", function () {
check(arguments, [Match.Any]);
Logger.warn("running stub notification");
return true;
});
Inventory.direct.remove({});
const cart = Factory.create("cartToOrder");
reduceCart(cart);
sandbox.stub(Reaction, "hasPermission", () => true);
sandbox.stub(Reaction, "getShopId", function () {
return cart.shopId;
});
const shop = getShop();
const product = cart.items[0];
const inventoryItem = Inventory.insert({
const inventoryItem = Inventory.findOne({
productId: product.productId,
variantId: product.variants._id,
shopId: shop._id,
workflow: {
status: "reserved"
},
orderItemId: product._id
shopId: cart.shopId
});
expect(inventoryItem).to.not.be.undefined;
// because the cart fixture does not trigger hooks we need to allocate inventory manually
Inventory.update(inventoryItem._id,
{
$set: {
Expand All @@ -94,43 +81,34 @@ describe("Inventory Hooks", function () {
const updatedInventoryItem = Inventory.findOne({
productId: product.productId,
variantId: product.variants._id,
shopId: shop._id,
shopId: cart.shopId,
orderItemId: product._id
});
expect(updatedInventoryItem.workflow.status).to.equal("sold");
});

it.skip("should move allocated inventory to 'shipped' when an order is shipped", function (done) {
this.timeout(5000);
it("should move allocated inventory to 'shipped' when an order is shipped", function (done) {
sandbox.stub(Meteor.server.method_handlers, "orders/sendNotification", function () {
check(arguments, [Match.Any]);
Logger.warn("running stub notification");
return true;
});
sandbox.stub(Reaction, "hasPermission", () => true);
Inventory.direct.remove({});
const cart = Factory.create("cartToOrder");
reduceCart(cart);
sandbox.stub(Reaction, "getShopId", function () {
return cart.shopId;
});
const shop = getShop();
const product = cart.items[0];
const inventoryItem = Inventory.insert({
productId: product.productId,
variantId: product.variants._id,
shopId: shop._id,
workflow: {
status: "reserved"
},
orderItemId: product._id
const cartProduct = cart.items[0];
const inventoryItem = Inventory.findOne({
productId: cartProduct.productId,
variantId: cartProduct.variants._id,
shopId: cart.shopId
});
expect(inventoryItem).to.not.be.undefined;
// because the cart fixture does not trigger hooks we need to allocate inventory manuall
Inventory.update(inventoryItem._id,
{
$set: {
"workflow.status": "reserved",
"orderItemId": product._id
"orderItemId": cartProduct._id
}
});
spyOnMethod("copyCartToOrder", cart.userId);
Expand Down
152 changes: 72 additions & 80 deletions imports/plugins/included/inventory/server/methods/inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { Inventory } from "/lib/collections";
import * as Schemas from "/lib/collections/schemas";
import { Logger, Reaction } from "/server/api";


/**
* inventory/register
* @summary check a product and update Inventory collection with inventory documents.
* @param {Object} product - valid Schemas.Product object
* @return {Number} - returns the total amount of new inventory created
*/
export function registerInventory(product) {
check(product, Match.OneOf(Schemas.ProductVariant, Schemas.Product));
let type;
Expand Down Expand Up @@ -77,92 +82,79 @@ export function registerInventory(product) {
return totalNewInventory;
}

Meteor.methods({
/**
* inventory/register
* @summary check a product and update Inventory collection with inventory documents.
* @param {Object} product - valid Schemas.Product object
* @return {Number} - returns the total amount of new inventory created
*/
"inventory/register": function (product) {
if (!Reaction.hasPermission("createProduct")) {
throw new Meteor.Error(403, "Access Denied");
}
registerInventory(product);
},
/**
* inventory/adjust
* @summary adjust existing inventory when changes are made we get the
* inventoryQuantity for each product variant, and compare the qty to the qty
* in the inventory records we will add inventoryItems as needed to have the
* same amount as the inventoryQuantity but when deleting, we'll refuse to
* delete anything not workflow.status = "new"
*
* @param {Object} product - Schemas.Product object
* @return {[undefined]} returns undefined
* @todo should be variant
*/
"inventory/adjust": function (product) {
check(product, Match.OneOf(Schemas.Product, Schemas.ProductVariant));
let type;
let results;
// adds or updates inventory collection with this product
switch (product.type) {
case "variant":
check(product, Schemas.ProductVariant);
type = "variant";
break;
default:
check(product, Schemas.Product);
type = "simple";
}
// user needs createProduct permission to adjust inventory
if (!Reaction.hasPermission("createProduct")) {
throw new Meteor.Error(403, "Access Denied");
}
// this.unblock();
function adjustInventory(product) {
let type;
let results;
// adds or updates inventory collection with this product
switch (product.type) {
case "variant":
check(product, Schemas.ProductVariant);
type = "variant";
break;
default:
check(product, Schemas.Product);
type = "simple";
}
// user needs createProduct permission to adjust inventory
if (!Reaction.hasPermission("createProduct")) {
throw new Meteor.Error(403, "Access Denied");
}
// this.unblock();

// Quantity and variants of this product's variant inventory
if (type === "variant") {
const variant = {
_id: product._id,
qty: product.inventoryQuantity || 0
};
// Quantity and variants of this product's variant inventory
if (type === "variant") {
const variant = {
_id: product._id,
qty: product.inventoryQuantity || 0
};

const inventory = Inventory.find({
productId: product.ancestors[0],
variantId: product._id
});
const itemCount = inventory.count();
const inventory = Inventory.find({
productId: product.ancestors[0],
variantId: product._id
});
const itemCount = inventory.count();

if (itemCount !== variant.qty) {
if (itemCount < variant.qty) {
// we need to register some new variants to inventory
results = itemCount + Meteor.call("inventory/register", product);
} else if (itemCount > variant.qty) {
// determine how many records to delete
const removeQty = itemCount - variant.qty;
// we're only going to delete records that are new
const removeInventory = Inventory.find({
"variantId": variant._id,
"workflow.status": "new"
}, {
sort: {
updatedAt: -1
},
limit: removeQty
}).fetch();
if (itemCount !== variant.qty) {
if (itemCount < variant.qty) {
// we need to register some new variants to inventory
results = itemCount + Meteor.call("inventory/register", product);
} else if (itemCount > variant.qty) {
// determine how many records to delete
const removeQty = itemCount - variant.qty;
// we're only going to delete records that are new
const removeInventory = Inventory.find({
"variantId": variant._id,
"workflow.status": "new"
}, {
sort: {
updatedAt: -1
},
limit: removeQty
}).fetch();

results = itemCount;
// delete latest inventory "status:new" records
for (const inventoryItem of removeInventory) {
results -= Meteor.call("inventory/remove", inventoryItem);
// we could add handling for the case when aren't enough "new" items
}
Logger.info(`adjust variant ${variant._id} from ${itemCount} to ${results}`);
results = itemCount;
// delete latest inventory "status:new" records
for (const inventoryItem of removeInventory) {
results -= Meteor.call("inventory/remove", inventoryItem);
// we could add handling for the case when aren't enough "new" items
}
}
Logger.info(
`adjust variant ${variant._id} from ${itemCount} to ${results}`
);
}
}
}

Meteor.methods({
"inventory/register": function (product) {
if (!Reaction.hasPermission("createProduct")) {
throw new Meteor.Error(403, "Access Denied");
}
registerInventory(product);
},
"inventory/adjust": function (product) { // TODO: this should be variant
check(product, Match.OneOf(Schemas.Product, Schemas.ProductVariant));
adjustInventory(product);
}
});
2 changes: 1 addition & 1 deletion imports/plugins/included/inventory/server/startup/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Hooks.Events.add("afterCoreInit", () => {
if (!inventory) {
const products = Products.find().fetch();
for (const product of products) {
Logger.info(`Registering product ${product.title}`);
Logger.debug(`Registering product ${product.title}`);
registerInventory(product);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@ describe("Submit payment", function () {
});

it("should call Example API with card and payment data", function () {
this.timeout(3000);
// this is a ridiculous timeout for a test that should run in subseconds
// but a bug in the Meteor test runner (or something) seems to make this test stall
// it actually stalls after the entire test is completed
this.timeout(30000);
const cardData = {
name: "Test User",
number: "4242424242424242",
Expand Down
2 changes: 1 addition & 1 deletion private/data/Shops.json
Original file line number Diff line number Diff line change
Expand Up @@ -3434,7 +3434,7 @@
},
"PHP": {
"format": "%s %v",
"symbol": "PHP"
"symbol": ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just sneaking this in there, eh? 👍

},
"PLN": {
"format": "%s%v",
Expand Down
4 changes: 4 additions & 0 deletions server/global.app-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
before(function () {
this.timeout(6000);
Meteor._sleepForMs(500);
});
Loading