Adds SFRA 6.0
This commit is contained in:
@@ -0,0 +1,584 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
|
||||
describe('forms', function () {
|
||||
var buildObj = function (obj) {
|
||||
Object.keys(obj).forEach(function (key) {
|
||||
this[key] = obj[key];
|
||||
}, this);
|
||||
};
|
||||
var FormGroup = function (obj) { this.init.call(this, obj); };
|
||||
FormGroup.prototype.init = buildObj;
|
||||
var FormAction = function (obj) { this.init.call(this, obj); };
|
||||
FormAction.prototype.init = buildObj;
|
||||
var FormField = function (obj) { this.init.call(this, obj); };
|
||||
FormField.prototype.init = buildObj;
|
||||
var formsRequire = proxyquire('../../../../cartridges/modules/server/forms/forms', {
|
||||
'dw/web/FormField': FormField,
|
||||
'dw/web/FormAction': FormAction,
|
||||
'dw/web/FormGroup': FormGroup,
|
||||
'./formField': proxyquire('../../../../cartridges/modules/server/forms/formField', {
|
||||
'dw/web/Resource': { msg: function (value) { return value; } },
|
||||
'dw/util/SecureEncoder': { forHtmlInDoubleQuoteAttribute: function (something) { return something; } }
|
||||
})
|
||||
});
|
||||
|
||||
it('should load a form', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isTrue(currentForm.valid);
|
||||
assert.isNull(currentForm.error);
|
||||
assert.equal(currentForm.htmlName, 'dwfrm_address');
|
||||
assert.isNotNull(currentForm.firstName);
|
||||
});
|
||||
|
||||
it('should load a form with correct string form fields', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.firstName);
|
||||
assert.equal(currentForm.firstName.value, 'Jon');
|
||||
assert.equal(currentForm.firstName.htmlValue, 'Jon');
|
||||
assert.isTrue(currentForm.firstName.valid);
|
||||
assert.isUndefined(currentForm.firstName.error);
|
||||
assert.isTrue(currentForm.firstName.mandatory);
|
||||
assert.equal(currentForm.firstName.label, 'hello');
|
||||
assert.equal(currentForm.firstName.attributes, 'name="dwfrm_address_firstName" required aria-required="true" value="Jon" maxLength="50" minLength="1" pattern="/[a-zA-Z]*/"');
|
||||
assert.equal(currentForm.firstName.formType, 'formField');
|
||||
});
|
||||
|
||||
it('should load a form with correct bool form fields', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
boolField: new FormField({
|
||||
value: true,
|
||||
selected: true,
|
||||
checked: true,
|
||||
htmlValue: true,
|
||||
htmlName: 'dwfrm_address_boolField',
|
||||
dynamicHtmlName: 'dwfrm_address_boolField_a89sa7d9f8a7sd',
|
||||
type: 2,
|
||||
FIELD_TYPE_BOOLEAN: 2,
|
||||
valid: false,
|
||||
error: 'Found an issue'
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.boolField);
|
||||
assert.equal(currentForm.boolField.value, true);
|
||||
assert.equal(currentForm.boolField.htmlValue, true);
|
||||
assert.isFalse(currentForm.boolField.valid);
|
||||
assert.equal(currentForm.boolField.error, 'Found an issue');
|
||||
assert.equal(currentForm.boolField.attributes, 'name="dwfrm_address_boolField" checked="true" value="true"');
|
||||
assert.equal(currentForm.boolField.formType, 'formField');
|
||||
});
|
||||
|
||||
it('should invalidate bool form field if mandatory flag is true and checked attribute false', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
boolField: new FormField({
|
||||
value: true,
|
||||
selected: false,
|
||||
valid: true,
|
||||
checked: false,
|
||||
htmlValue: true,
|
||||
htmlName: 'dwfrm_address_boolField',
|
||||
dynamicHtmlName: 'dwfrm_address_boolField_a89sa7d9f8a7sd',
|
||||
type: 2,
|
||||
mandatory: true,
|
||||
FIELD_TYPE_BOOLEAN: 2,
|
||||
error: 'Found an issue',
|
||||
invalidateFormElement: function () {
|
||||
this.valid = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.boolField);
|
||||
assert.equal(currentForm.boolField.value, true);
|
||||
assert.equal(currentForm.boolField.htmlValue, true);
|
||||
assert.equal(currentForm.boolField.formType, 'formField');
|
||||
assert.isFalse(currentForm.boolField.valid);
|
||||
assert.equal(currentForm.boolField.error, 'Found an issue');
|
||||
assert.equal(currentForm.boolField.attributes, 'name="dwfrm_address_boolField" required aria-required="true" value="true"');
|
||||
});
|
||||
|
||||
it('should load a form with correct int form fields', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
intField: new FormField({
|
||||
value: null,
|
||||
htmlValue: null,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_intField',
|
||||
dynamicHtmlName: 'dwfrm_address_intField_as8df7asd98',
|
||||
type: 3,
|
||||
FIELD_TYPE_INTEGER: 3,
|
||||
maxValue: 999,
|
||||
minValue: 1,
|
||||
valid: true
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.intField);
|
||||
assert.equal(currentForm.intField.value, null);
|
||||
assert.equal(currentForm.intField.htmlValue, '');
|
||||
assert.isTrue(currentForm.intField.valid);
|
||||
assert.isUndefined(currentForm.intField.error);
|
||||
assert.isTrue(currentForm.intField.mandatory);
|
||||
assert.equal(currentForm.intField.attributes, 'name="dwfrm_address_intField" required aria-required="true" value="" max="999" min="1"');
|
||||
assert.equal(currentForm.intField.formType, 'formField');
|
||||
});
|
||||
|
||||
it('should load a form with correct date form fields', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
dateField: new FormField({
|
||||
value: null,
|
||||
htmlValue: null,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_dateField',
|
||||
dynamicHtmlName: 'dwfrm_address_dateField_as8df7asd98',
|
||||
type: 4,
|
||||
FIELD_TYPE_DATE: 4,
|
||||
valid: true
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.dateField);
|
||||
assert.equal(currentForm.dateField.value, null);
|
||||
assert.equal(currentForm.dateField.htmlValue, '');
|
||||
assert.isTrue(currentForm.dateField.valid);
|
||||
assert.isUndefined(currentForm.dateField.error);
|
||||
assert.isTrue(currentForm.dateField.mandatory);
|
||||
assert.equal(currentForm.dateField.attributes, 'name="dwfrm_address_dateField" required aria-required="true" value=""');
|
||||
assert.equal(currentForm.dateField.formType, 'formField');
|
||||
});
|
||||
|
||||
it('should load a form with correct string form field with options', function () {
|
||||
var Options = function () {};
|
||||
Options.prototype = [];
|
||||
var options = new Options();
|
||||
options.push({
|
||||
checked: false,
|
||||
htmlValue: 'hello',
|
||||
optionId: 1,
|
||||
selected: false,
|
||||
value: 'hello'
|
||||
});
|
||||
options.push({
|
||||
checked: true,
|
||||
htmlValue: 'goodbye',
|
||||
optionId: 2,
|
||||
selected: true,
|
||||
value: 'goodbye',
|
||||
label: 'label'
|
||||
});
|
||||
options.optionsCount = 2;
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
options: options,
|
||||
selectedOption: {
|
||||
optionId: 2
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.firstName);
|
||||
assert.isNotNull(currentForm.firstName.options);
|
||||
assert.equal(currentForm.firstName.options.length, 2);
|
||||
assert.equal(currentForm.firstName.options[0].id, 1);
|
||||
assert.isFalse(currentForm.firstName.options[0].selected);
|
||||
assert.equal(currentForm.firstName.options[1].id, 2);
|
||||
assert.isTrue(currentForm.firstName.options[1].selected);
|
||||
assert.equal(currentForm.firstName.selectedOption, 2);
|
||||
assert.equal(currentForm.firstName.formType, 'formField');
|
||||
});
|
||||
|
||||
it('should load a form with correct actions', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
action: new FormAction({
|
||||
submitted: false,
|
||||
triggered: false
|
||||
}),
|
||||
action2: new FormAction({
|
||||
description: 'Some action',
|
||||
label: 'My action',
|
||||
submitted: true,
|
||||
triggered: true
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.action);
|
||||
assert.isFalse(currentForm.action.submitted);
|
||||
assert.isFalse(currentForm.action.triggered);
|
||||
assert.isNull(currentForm.action.description);
|
||||
assert.isNotNull(currentForm.action2);
|
||||
assert.isTrue(currentForm.action2.submitted);
|
||||
assert.isTrue(currentForm.action2.triggered);
|
||||
assert.equal(currentForm.action2.description, 'Some action');
|
||||
assert.equal(currentForm.action2.label, 'My action');
|
||||
assert.equal(currentForm.action.formType, 'formAction');
|
||||
assert.equal(currentForm.action2.formType, 'formAction');
|
||||
});
|
||||
it('should load a form with another form embeded', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
innerForm: new FormGroup({
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address_innerForm',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_a90a9s8fasd',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_innerForm_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
assert.isNotNull(currentForm.innerForm.firstName);
|
||||
assert.equal(currentForm.innerForm.firstName.value, 'Jon');
|
||||
assert.equal(currentForm.innerForm.firstName.htmlValue, 'Jon');
|
||||
assert.isTrue(currentForm.innerForm.firstName.valid);
|
||||
assert.isUndefined(currentForm.innerForm.firstName.error);
|
||||
assert.isTrue(currentForm.innerForm.firstName.mandatory);
|
||||
assert.equal(currentForm.innerForm.firstName.label, 'hello');
|
||||
assert.equal(currentForm.innerForm.firstName.attributes, 'name="dwfrm_address_innerForm_firstName" required aria-required="true" value="Jon" maxLength="50" minLength="1" pattern="/[a-zA-Z]*/"');
|
||||
assert.equal(currentForm.innerForm.formType, 'formGroup');
|
||||
assert.equal(currentForm.innerForm.firstName.formType, 'formField');
|
||||
});
|
||||
it('should return updated attributes after form clear', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
shippingaddress: {
|
||||
valid: true,
|
||||
error: 'null',
|
||||
htmlName: 'dwfrm_shippingaddress',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_a98dfa9sd8',
|
||||
intField: new FormField({
|
||||
value: 10,
|
||||
htmlValue: 10,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_shippingaddress_intField',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_intField_as8df7asd98',
|
||||
type: 3,
|
||||
FIELD_TYPE_INTEGER: 3,
|
||||
maxValue: 999,
|
||||
minValue: 1,
|
||||
valid: true
|
||||
}),
|
||||
clearFormElement: function () {
|
||||
this.intField.value = 0;
|
||||
this.intField.htmlValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('shippingaddress');
|
||||
assert.equal(currentForm.intField.attributes, 'name="dwfrm_shippingaddress_intField" required aria-required="true" value="10" max="999" min="1"');
|
||||
currentForm.clear();
|
||||
assert.equal(currentForm.intField.attributes, 'name="dwfrm_shippingaddress_intField" required aria-required="true" value="0" max="999" min="1"');
|
||||
});
|
||||
it('should update htmlValue when value is updated', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
shippingaddress: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_shippingaddress',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_a98dfa9sd8',
|
||||
intField: new FormField({
|
||||
value: 10,
|
||||
htmlValue: 10,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_shippingaddress_intField',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_intField_as8df7asd98',
|
||||
type: 3,
|
||||
FIELD_TYPE_INTEGER: 3,
|
||||
maxValue: 999,
|
||||
minValue: 1,
|
||||
valid: true
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('shippingaddress');
|
||||
assert.equal(currentForm.intField.htmlValue, 10);
|
||||
currentForm.intField.value = 22;
|
||||
assert.equal(currentForm.intField.value, 22);
|
||||
});
|
||||
|
||||
it('should copy the values of a form to an object', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
shippingaddress: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_shippingaddress',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_a98dfa9sd8',
|
||||
intField: new FormField({
|
||||
value: 10,
|
||||
htmlValue: 10,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_shippingaddress_intField',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_intField_as8df7asd98',
|
||||
type: 3,
|
||||
FIELD_TYPE_INTEGER: 3,
|
||||
maxValue: 999,
|
||||
minValue: 1,
|
||||
valid: true
|
||||
}),
|
||||
innerForm: new FormGroup({
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address_innerForm',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_a90a9s8fasd',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_innerForm_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
}),
|
||||
innerForm: new FormGroup({
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address_innerForm',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_a90a9s8fasd',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_innerForm_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var expectedObject = {
|
||||
intField: 10,
|
||||
innerForm: {
|
||||
firstName: 'Jon',
|
||||
innerForm: {
|
||||
firstName: 'Jon'
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('shippingaddress');
|
||||
var result = currentForm.toObject();
|
||||
assert.deepEqual(expectedObject, result);
|
||||
});
|
||||
|
||||
it('should copy the values of an object to a form', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
shippingaddress: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_shippingaddress',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_a98dfa9sd8',
|
||||
intField: new FormField({
|
||||
value: 10,
|
||||
htmlValue: 10,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_shippingaddress_intField',
|
||||
dynamicHtmlName: 'dwfrm_shippingaddress_intField_as8df7asd98',
|
||||
type: 3,
|
||||
FIELD_TYPE_INTEGER: 3,
|
||||
maxValue: 999,
|
||||
minValue: 1,
|
||||
valid: true
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var object = { intField: 22 };
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('shippingaddress');
|
||||
assert.equal(currentForm.intField.value, 10);
|
||||
currentForm.copyFrom(object);
|
||||
assert.equal(currentForm.intField.value, 22);
|
||||
});
|
||||
it('should copy the values of an object to a nested form', function () {
|
||||
var session = {
|
||||
forms: {
|
||||
address: {
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address',
|
||||
dynamicHtmlName: 'dwfrm_address_a98dfa9sd8',
|
||||
innerForm: new FormGroup({
|
||||
valid: true,
|
||||
error: null,
|
||||
htmlName: 'dwfrm_address_innerForm',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_a90a9s8fasd',
|
||||
firstName: new FormField({
|
||||
value: 'Jon',
|
||||
htmlValue: 'Jon',
|
||||
valid: true,
|
||||
mandatory: true,
|
||||
htmlName: 'dwfrm_address_innerForm_firstName',
|
||||
dynamicHtmlName: 'dwfrm_address_innerForm_firstName_asdf8979asd8f',
|
||||
type: 1,
|
||||
FIELD_TYPE_STRING: 1,
|
||||
label: 'hello',
|
||||
regEx: '/[a-zA-Z]*/',
|
||||
maxLength: 50,
|
||||
minLength: 1
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
var forms = formsRequire(session);
|
||||
var currentForm = forms.getForm('address');
|
||||
var object = { firstName: 'Sally' };
|
||||
assert.equal(currentForm.innerForm.firstName.value, 'Jon');
|
||||
currentForm.copyFrom(object);
|
||||
assert.equal(currentForm.innerForm.firstName.value, 'Sally');
|
||||
});
|
||||
});
|
@@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var sinon = require('sinon');
|
||||
var middleware = require('../../../../cartridges/modules/server/middleware');
|
||||
|
||||
describe('middleware', function () {
|
||||
var next = null;
|
||||
var req = {};
|
||||
|
||||
beforeEach(function () {
|
||||
next = sinon.spy();
|
||||
req = {};
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
next.reset();
|
||||
});
|
||||
|
||||
it('should call next for http method', function () {
|
||||
req.https = false;
|
||||
middleware.http(req, null, next);
|
||||
assert.isTrue(next.calledOnce);
|
||||
});
|
||||
|
||||
it('should call next with error for http method', function () {
|
||||
req.https = true;
|
||||
middleware.http(req, null, next);
|
||||
assert.instanceOf(next.firstCall.args[0], Error);
|
||||
});
|
||||
|
||||
|
||||
it('should call next for https method', function () {
|
||||
req.https = true;
|
||||
middleware.https(req, null, next);
|
||||
assert.isTrue(next.calledOnce);
|
||||
});
|
||||
|
||||
it('should call next with error for https method', function () {
|
||||
req.https = false;
|
||||
middleware.https(req, null, next);
|
||||
assert.instanceOf(next.firstCall.args[0], Error);
|
||||
});
|
||||
|
||||
it('should call next for get method', function () {
|
||||
req.httpMethod = 'GET';
|
||||
middleware.get(req, null, next);
|
||||
assert.isTrue(next.calledOnce);
|
||||
});
|
||||
|
||||
it('should call next with error for get method', function () {
|
||||
req.httpMethod = 'PUT';
|
||||
middleware.get(req, null, next);
|
||||
assert.instanceOf(next.firstCall.args[0], Error);
|
||||
});
|
||||
|
||||
it('should call next for post method', function () {
|
||||
req.httpMethod = 'POST';
|
||||
middleware.post(req, null, next);
|
||||
assert.isTrue(next.calledOnce);
|
||||
});
|
||||
|
||||
it('should call next with error for post method', function () {
|
||||
req.httpMethod = 'DELETE';
|
||||
middleware.get(req, null, next);
|
||||
assert.instanceOf(next.firstCall.args[0], Error);
|
||||
});
|
||||
|
||||
it('should call next for include', function () {
|
||||
req.includeRequest = true;
|
||||
middleware.include(req, null, next);
|
||||
assert.isTrue(next.calledOnce);
|
||||
});
|
||||
|
||||
it('should call next with error for include', function () {
|
||||
req.includeRequest = false;
|
||||
middleware.include(req, null, next);
|
||||
assert.instanceOf(next.firstCall.args[0], Error);
|
||||
});
|
||||
});
|
@@ -0,0 +1,206 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var sinon = require('sinon');
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var QueryString;
|
||||
var logSpy;
|
||||
|
||||
describe('querystring', function () {
|
||||
beforeEach(function () {
|
||||
logSpy = sinon.spy();
|
||||
QueryString = proxyquire('../../../../cartridges/modules/server/queryString', {
|
||||
'dw/system/Logger': {
|
||||
warn: logSpy
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('options parsing', function () {
|
||||
it('should parse product option query parameters', function () {
|
||||
var params = 'dwopt_microsoft-xbox360-console_consoleWarranty=002&' +
|
||||
'dwopt_microsoft-xbox360-console_gpsWarranty=003&' +
|
||||
'dwopt_microsoft-xbox360-console_gps_warranty=003';
|
||||
var querystring = new QueryString(params);
|
||||
assert.deepEqual([{
|
||||
optionId: 'gps_warranty',
|
||||
productId: 'microsoft-xbox360-console',
|
||||
selectedValueId: '003'
|
||||
}, {
|
||||
optionId: 'gpsWarranty',
|
||||
productId: 'microsoft-xbox360-console',
|
||||
selectedValueId: '003'
|
||||
}, {
|
||||
optionId: 'consoleWarranty',
|
||||
productId: 'microsoft-xbox360-console',
|
||||
selectedValueId: '002'
|
||||
}], querystring.options);
|
||||
});
|
||||
|
||||
it('should parse product option for product with underscore', function () {
|
||||
var params = 'dwopt_microsoft__xbox360__console_consoleWarranty=002&' +
|
||||
'dwopt_microsoft__xbox360__console_gpsWarranty=003&' +
|
||||
'dwopt_microsoft__xbox360__console_gps_warranty=003';
|
||||
var querystring = new QueryString(params);
|
||||
assert.deepEqual([{
|
||||
optionId: 'gps_warranty',
|
||||
productId: 'microsoft_xbox360_console',
|
||||
selectedValueId: '003'
|
||||
}, {
|
||||
optionId: 'gpsWarranty',
|
||||
productId: 'microsoft_xbox360_console',
|
||||
selectedValueId: '003'
|
||||
}, {
|
||||
optionId: 'consoleWarranty',
|
||||
productId: 'microsoft_xbox360_console',
|
||||
selectedValueId: '002'
|
||||
}], querystring.options);
|
||||
});
|
||||
|
||||
it('should output options query params', function () {
|
||||
var params = 'dwopt_microsoft-xbox360-console_consoleWarranty=002&' +
|
||||
'dwopt_microsoft-xbox360-console_gpsWarranty=003';
|
||||
var querystring = new QueryString(params);
|
||||
var paramsOutput = querystring.toString();
|
||||
assert.equal(paramsOutput, 'dwopt_microsoft-xbox360-console_consoleWarranty=002&' +
|
||||
'dwopt_microsoft-xbox360-console_gpsWarranty=003');
|
||||
});
|
||||
|
||||
it('should output options query params for product with underscore', function () {
|
||||
var params = 'dwopt_microsoft__xbox360__console_console_Warranty=002&' +
|
||||
'dwopt_microsoft__xbox360__console_gpsWarranty=003';
|
||||
var querystring = new QueryString(params);
|
||||
var paramsOutput = querystring.toString();
|
||||
assert.equal(paramsOutput, 'dwopt_microsoft__xbox360__console_console_Warranty=002&' +
|
||||
'dwopt_microsoft__xbox360__console_gpsWarranty=003');
|
||||
});
|
||||
it('creates a single key "x=y" when options is not an array', function () {
|
||||
var params = 'dwopt_microsoft__xbox360__console_console_Warranty=002&' +
|
||||
'dwopt_microsoft__xbox360__console_gpsWarranty=003';
|
||||
var rangeResult = new QueryString(params);
|
||||
rangeResult.options = 'a simple string';
|
||||
var paramsOutput = rangeResult.toString();
|
||||
assert.equal(paramsOutput, 'options=a%20simple%20string');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('variation attribute parsing', function () {
|
||||
it('should parse product variation query parameters', function () {
|
||||
var params = 'dwvar_P12345_color=blue&dwvar_P12345_pv_size=L&pid=P12345';
|
||||
var querystring = new QueryString(params);
|
||||
assert.deepEqual({
|
||||
color: {
|
||||
id: 'P12345',
|
||||
value: 'blue'
|
||||
},
|
||||
pv_size: {
|
||||
id: 'P12345',
|
||||
value: 'L'
|
||||
}
|
||||
}, querystring.variables);
|
||||
});
|
||||
|
||||
it('should parse product variation param for product with underscores', function () {
|
||||
var params = 'dwvar_my__test__product_color=blue&dwvar_my__test__product_pv_size=L&pid=P12345';
|
||||
var querystring = new QueryString(params);
|
||||
assert.deepEqual({
|
||||
color: {
|
||||
id: 'my_test_product',
|
||||
value: 'blue'
|
||||
},
|
||||
pv_size: {
|
||||
id: 'my_test_product',
|
||||
value: 'L'
|
||||
}
|
||||
}, querystring.variables);
|
||||
});
|
||||
it('creates a single key "x=y" when variables is not an object', function () {
|
||||
var params = 'dwvar_my__test__product_color=blue&dwvar_my__test__product_pv_size=L';
|
||||
var rangeResult = new QueryString(params);
|
||||
rangeResult.variables = 'a simple string';
|
||||
var paramsOutput = rangeResult.toString();
|
||||
assert.equal(paramsOutput, 'variables=a%20simple%20string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('search refinements preferences parsing', function () {
|
||||
it('should parse search refinement preference query parameters', function () {
|
||||
var params = 'prefn1=pref1&prefv1=pref1Value&prefn2=pref2&prefv2=pref2Value';
|
||||
var result = new QueryString(params);
|
||||
assert.deepEqual(result.preferences, {
|
||||
pref1: 'pref1Value',
|
||||
pref2: 'pref2Value'
|
||||
});
|
||||
});
|
||||
|
||||
it('should output preferences query params', function () {
|
||||
var params = 'prefn1=pref1&prefv1=pref1Value&prefn2=pref2&prefv2=pref2Value';
|
||||
var result = new QueryString(params);
|
||||
var paramsOutput = result.toString();
|
||||
assert.equal(paramsOutput, 'prefn1=pref1&prefn2=pref2&prefv1=pref1Value&prefv2=pref2Value');
|
||||
});
|
||||
|
||||
it('should parse search refinement preference range query parameters', function () {
|
||||
var rangeParams = 'prefn1=prefName&prefmin1=0&prefmax1=100';
|
||||
var rangeResult = new QueryString(rangeParams);
|
||||
assert.deepEqual(rangeResult.preferences, {
|
||||
prefName: {
|
||||
min: '0',
|
||||
max: '100'
|
||||
}
|
||||
});
|
||||
});
|
||||
it('should output range preference query params', function () {
|
||||
var rangeParams = 'prefn1=prefName&prefmin1=0&prefmax1=100';
|
||||
var rangeResult = new QueryString(rangeParams);
|
||||
var paramsOutput = rangeResult.toString();
|
||||
assert.deepEqual(paramsOutput, 'prefmax1=100&prefmin1=0&prefn1=prefName');
|
||||
});
|
||||
it('outputs range preference without "undefined" when one or more query params is empty or "undefined"', function () {
|
||||
var rangeParams = 'prefv1=&prefn1=prefName&prefmin1=0&prefmax1=100';
|
||||
var rangeResult = new QueryString(rangeParams);
|
||||
var paramsOutput = rangeResult.toString();
|
||||
assert.deepEqual(paramsOutput, 'prefmax1=100&prefmin1=0&prefn1=prefName');
|
||||
});
|
||||
it('warns via Logger when one or more query params is empty or "undefined"', function () {
|
||||
var rangeParams = 'prefv1=&prefn1=prefName&prefmin1=0&prefmax1=100';
|
||||
var rangeResult = new QueryString(rangeParams);
|
||||
var paramsOutput = rangeResult.toString(); // eslint-disable-line no-unused-vars
|
||||
assert.equal(logSpy.args[0][0], 'We were passed a key "undefined in the preferences object in queryString.js');
|
||||
});
|
||||
it('creates a single key "x=y" when preferences is not an object', function () {
|
||||
var rangeParams = 'prefv1=&prefn1=prefName&prefmin1=0&prefmax1=100';
|
||||
var rangeResult = new QueryString(rangeParams);
|
||||
rangeResult.preferences = 'a simple string';
|
||||
var paramsOutput = rangeResult.toString();
|
||||
assert.equal(paramsOutput, 'preferences=a%20simple%20string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('handling special characters', function () {
|
||||
it('should handle the \'+\' with a \'%20\' which leads to a \' \'', function () {
|
||||
var params = '?trackOrderNumber=01&trackOrderPostal=EC1A+1BB';
|
||||
var result = new QueryString(params);
|
||||
|
||||
assert.equal(result.trackOrderPostal, 'EC1A 1BB');
|
||||
});
|
||||
});
|
||||
|
||||
describe('handling url encoding of querystring', function () {
|
||||
it('should handle encoding properly', function () {
|
||||
var params = '?dwvar_P12345_Maat=37%2B&pid=P12345';
|
||||
var result = new QueryString(params);
|
||||
assert.equal(result.toString(), 'dwvar_P12345_Maat=37%2B&pid=P12345');
|
||||
});
|
||||
});
|
||||
|
||||
describe('handling duplicate parameters in querystring', function () {
|
||||
it('should return an array', function () {
|
||||
var params = '?one=uno&cheese=1&cheese=2&cheese=3&brand=sony&brand=samsung&cheese=4';
|
||||
var result = new QueryString(params);
|
||||
assert.deepEqual(result.one, 'uno');
|
||||
assert.deepEqual(result.cheese, ['4', '3', '2', '1']);
|
||||
assert.deepEqual(result.brand, ['samsung', 'sony']);
|
||||
});
|
||||
});
|
||||
});
|
@@ -0,0 +1,178 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var sinon = require('sinon');
|
||||
|
||||
describe('render', function () {
|
||||
var render = null;
|
||||
var ismlRender = sinon.spy();
|
||||
var pageDesignerRender = sinon.spy();
|
||||
|
||||
var response = {
|
||||
base: {
|
||||
writer: {
|
||||
print: sinon.spy()
|
||||
}
|
||||
},
|
||||
setContentType: sinon.spy(),
|
||||
viewData: {},
|
||||
renderings: [],
|
||||
view: null
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
global.XML = function (xmlString) {
|
||||
var parseString = require('xml2js').parseString;
|
||||
|
||||
return parseString(xmlString, 'text/xml', function (error) {
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render = proxyquire('../../../../cartridges/modules/server/render', {
|
||||
'dw/template/ISML': {
|
||||
renderTemplate: ismlRender
|
||||
},
|
||||
'dw/experience/PageMgr': {
|
||||
renderPage: pageDesignerRender
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
ismlRender.reset();
|
||||
pageDesignerRender.reset();
|
||||
response.base.writer.print.reset();
|
||||
response.setContentType.reset();
|
||||
response.viewData = {};
|
||||
response.renderings = [];
|
||||
});
|
||||
|
||||
it('should correctly render a template', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'isml', view: 'name' });
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(ismlRender.calledOnce);
|
||||
});
|
||||
|
||||
it('should pass data correctly to the view', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'isml', view: 'template' });
|
||||
response.viewData = { name: 'value' };
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(ismlRender.calledWith('template', sinon.match({ name: 'value' })));
|
||||
});
|
||||
|
||||
it('should correctly render a page', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'page', page: 'page' });
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(pageDesignerRender.calledOnce);
|
||||
});
|
||||
|
||||
it('should pass data correctly to the view of the page being rendered', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'page', page: 'page2' });
|
||||
response.viewData = { decorator: 'decorator' };
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(response.base.writer.print.calledOnce);
|
||||
assert.isTrue(pageDesignerRender.calledWith('page2', '{"decorator":"decorator"}'));
|
||||
});
|
||||
|
||||
it('should render a json output', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'json' });
|
||||
response.viewData = { name: 'value' };
|
||||
render.applyRenderings(response);
|
||||
|
||||
|
||||
assert.isTrue(response.setContentType.calledWith('application/json'));
|
||||
assert.isTrue(response.base.writer.print.calledOnce);
|
||||
});
|
||||
|
||||
it('should render valid xml output', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'xml' });
|
||||
response.viewData = {
|
||||
key1: 'value1',
|
||||
key2: 'value2',
|
||||
xml: '<xmlKey></xmlKey>'
|
||||
};
|
||||
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(response.setContentType.calledWith('application/xml'));
|
||||
assert.isTrue(response.base.writer.print.calledOnce);
|
||||
});
|
||||
|
||||
it('should throw an exception when invalid XML is provided', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'xml' });
|
||||
response.viewData = { xml: '<x>I am not valid XML<y>' };
|
||||
|
||||
try {
|
||||
render.applyRenderings(response);
|
||||
} catch (e) {
|
||||
assert.isNotNull(e);
|
||||
}
|
||||
});
|
||||
|
||||
it('should print output', function () {
|
||||
response.renderings.push({ type: 'print', message: 'crazyMessage' });
|
||||
render.applyRenderings(response);
|
||||
|
||||
assert.isTrue(response.base.writer.print.calledOnce);
|
||||
assert.isTrue(response.base.writer.print.calledWith('crazyMessage'));
|
||||
});
|
||||
|
||||
it('should render error page when template failed', function () {
|
||||
var renderMock = proxyquire('../../../../cartridges/modules/server/render', {
|
||||
'dw/template/ISML': {
|
||||
renderTemplate: function () {
|
||||
throw new Error('hello');
|
||||
}
|
||||
},
|
||||
'dw/experience/PageMgr': {
|
||||
renderPage: function () {
|
||||
throw new Error('Hello Darkness');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
response.renderings.push({ type: 'render', subType: 'isml', view: 'template' });
|
||||
|
||||
try {
|
||||
renderMock.applyRenderings(response);
|
||||
} catch (e) {
|
||||
assert.isNotNull(e);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw error when no rendering step has been called', function () {
|
||||
try {
|
||||
render.applyRenderings(response);
|
||||
} catch (e) {
|
||||
assert.isNotNull(e);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw error when unidentified Type', function () {
|
||||
response.renderings.push({ type: 'blah', subType: 'blah', view: 'template' });
|
||||
|
||||
try {
|
||||
render.applyRenderings(response);
|
||||
} catch (e) {
|
||||
assert.isNotNull(e);
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw error when unidentified subType', function () {
|
||||
response.renderings.push({ type: 'render', subType: 'blah', view: 'template' });
|
||||
|
||||
try {
|
||||
render.applyRenderings(response);
|
||||
} catch (e) {
|
||||
assert.isNotNull(e);
|
||||
}
|
||||
});
|
||||
});
|
@@ -0,0 +1,515 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var sinon = require('sinon');
|
||||
|
||||
var ArrayList = require('../../../mocks/dw.util.Collection');
|
||||
|
||||
var Request = proxyquire('../../../../cartridges/modules/server/request', {
|
||||
'dw/util/Locale': {
|
||||
getLocale: function () {
|
||||
return { ID: 'en_US', country: 'US' };
|
||||
}
|
||||
},
|
||||
'dw/util/Currency': {
|
||||
getCurrency: function () {
|
||||
return 'currency';
|
||||
}
|
||||
},
|
||||
'*/cartridge/config/countries': [
|
||||
{
|
||||
'id': 'en_US',
|
||||
'currencyCode': 'USD',
|
||||
'alternativeCurrencyCodes': ['CAD']
|
||||
}, {
|
||||
'id': 'en_GB',
|
||||
'currencyCode': 'GBP'
|
||||
}, {
|
||||
'id': 'ja_JP',
|
||||
'currencyCode': 'JPY'
|
||||
}, {
|
||||
'id': 'zh_CN',
|
||||
'currencyCode': 'CNY'
|
||||
}, {
|
||||
'id': 'fr_FR',
|
||||
'currencyCode': 'EUR'
|
||||
}, {
|
||||
'id': 'it_IT',
|
||||
'currencyCode': 'EUR'
|
||||
}]
|
||||
});
|
||||
|
||||
var session = {
|
||||
setCurrency: function () { return; }
|
||||
};
|
||||
|
||||
var setCurrencyStub = sinon.stub(session, 'setCurrency');
|
||||
|
||||
function createFakeRequest(overrides) {
|
||||
overrides = overrides || {}; // eslint-disable-line no-param-reassign
|
||||
var globalRequest = {
|
||||
httpMethod: 'GET',
|
||||
httpHost: 'localhost',
|
||||
httpPath: '/Product-Show',
|
||||
httpQueryString: '',
|
||||
httpParameterMap: {
|
||||
requestBodyAsString: ''
|
||||
},
|
||||
isHttpSecure: function () {
|
||||
return false;
|
||||
},
|
||||
getHttpReferer: function () {
|
||||
return 'https://www.salesforce.com';
|
||||
},
|
||||
getHttpRemoteAddress: function () {
|
||||
return '0.0.0.0';
|
||||
},
|
||||
geolocation: {
|
||||
countryCode: 'US',
|
||||
latitude: 42.4019,
|
||||
longitude: -71.1193
|
||||
},
|
||||
customer: {
|
||||
authenticated: true,
|
||||
profile: {
|
||||
firstName: 'John',
|
||||
lastName: 'Snow',
|
||||
email: 'jsnow@starks.com',
|
||||
phoneHome: '1234567890',
|
||||
credentials: {
|
||||
login: 'jsnow@starks.com'
|
||||
},
|
||||
wallet: {
|
||||
paymentInstruments: new ArrayList([
|
||||
{
|
||||
creditCardHolder: 'someName',
|
||||
maskedCreditCardNumber: 'someMaskedNumber',
|
||||
creditCardType: 'someCardType',
|
||||
creditCardExpirationMonth: 'someMonth',
|
||||
creditCardExpirationYear: 'someYear',
|
||||
UUID: 'someUUID',
|
||||
creditCardNumber: 'someNumber'
|
||||
}
|
||||
])
|
||||
}
|
||||
},
|
||||
addressBook: {
|
||||
preferredAddress: {
|
||||
address1: '15 South Point Drive',
|
||||
address2: null,
|
||||
city: 'Boston',
|
||||
countryCode: {
|
||||
displayValue: 'United States',
|
||||
value: 'US'
|
||||
},
|
||||
firstName: 'John',
|
||||
lastName: 'Snow',
|
||||
ID: 'Home',
|
||||
postalCode: '02125',
|
||||
stateCode: 'MA',
|
||||
postBox: '2134',
|
||||
salutation: null,
|
||||
secondName: null,
|
||||
suffix: null,
|
||||
suite: '302',
|
||||
title: 'Dr'
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
locale: 'ab_YZ',
|
||||
pageMetaData: {
|
||||
title: '',
|
||||
description: '',
|
||||
keywords: '',
|
||||
pageMetaTags: [{}],
|
||||
addPageMetaTags: function (pageMetaTags) {
|
||||
this.pageMetaTags = pageMetaTags;
|
||||
},
|
||||
setTitle: function (title) {
|
||||
this.title = title;
|
||||
},
|
||||
setDescription: function (description) {
|
||||
this.description = description;
|
||||
},
|
||||
setKeywords: function (keywords) {
|
||||
this.keywords = keywords;
|
||||
}
|
||||
},
|
||||
session: {
|
||||
currency: {
|
||||
currencyCode: 'XYZ',
|
||||
defaultFractionDigits: 10,
|
||||
name: 'Volodin Dollars',
|
||||
symbol: '៛'
|
||||
},
|
||||
custom: {
|
||||
rememberMe: true
|
||||
},
|
||||
privacyCache: {
|
||||
get: function (key) { // eslint-disable-line no-unused-vars
|
||||
return this.key;
|
||||
},
|
||||
set: function (value) { // eslint-disable-line no-unused-vars
|
||||
this.key = value;
|
||||
},
|
||||
key: 'value'
|
||||
},
|
||||
clickStream: {
|
||||
clicks: {
|
||||
toArray: function () {
|
||||
return [{
|
||||
host: 'clickObj.host',
|
||||
locale: 'clickObj.locale',
|
||||
path: 'clickObj.path',
|
||||
pipelineName: 'clickObj-pipelineName',
|
||||
queryString: 'clickObj.queryString',
|
||||
referer: 'clickObj.referer',
|
||||
remoteAddress: 'clickObj.remoteAddress',
|
||||
timestamp: 'clickObj.timestamp',
|
||||
url: 'clickObj.url',
|
||||
userAgent: 'clickObj.userAgent'
|
||||
}];
|
||||
}
|
||||
},
|
||||
partial: false
|
||||
},
|
||||
setCurrency: setCurrencyStub
|
||||
}
|
||||
};
|
||||
Object.keys(overrides).forEach(function (key) {
|
||||
globalRequest[key] = overrides[key];
|
||||
});
|
||||
return globalRequest;
|
||||
}
|
||||
|
||||
describe('request', function () {
|
||||
afterEach(function () {
|
||||
setCurrencyStub.reset();
|
||||
});
|
||||
|
||||
it('should parse empty query string', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.isObject(req.querystring);
|
||||
assert.equal(Object.keys(req.querystring).length, 0);
|
||||
assert.equal(req.querystring.toString(), '');
|
||||
});
|
||||
|
||||
it('should parse simple query string', function () {
|
||||
var req = new Request(createFakeRequest({ httpQueryString: 'id=22&name=foo' }), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.isObject(req.querystring);
|
||||
assert.equal(req.querystring.id, 22);
|
||||
assert.equal(req.querystring.name, 'foo');
|
||||
assert.equal(req.querystring.toString(), 'id=22&name=foo');
|
||||
});
|
||||
|
||||
it('should parse query string with variables', function () {
|
||||
var req = new Request(createFakeRequest({
|
||||
httpQueryString: 'dwvar_bar_size=32&dwvar_foo_color=1111'
|
||||
}), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.querystring.variables.color.id, 'foo');
|
||||
assert.equal(req.querystring.variables.color.value, '1111');
|
||||
assert.equal(req.querystring.variables.size.id, 'bar');
|
||||
assert.equal(req.querystring.variables.size.value, '32');
|
||||
assert.notProperty(req.querystring, 'dwvar_foo_color');
|
||||
assert.notProperty(req.querystring, 'dwvar_bar_size');
|
||||
assert.equal(req.querystring.toString(), 'dwvar_bar_size=32&dwvar_foo_color=1111');
|
||||
});
|
||||
|
||||
it('should parse query string with incorrectly formatted variables', function () {
|
||||
var req = new Request(createFakeRequest({
|
||||
httpQueryString: 'dwvar_color=1111&dwvar_size=32'
|
||||
}), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.querystring.dwvar_color, '1111');
|
||||
assert.equal(req.querystring.dwvar_size, '32');
|
||||
assert.notProperty(req.querystring, 'variables');
|
||||
assert.equal(req.querystring.toString(), 'dwvar_color=1111&dwvar_size=32');
|
||||
});
|
||||
|
||||
it('should contain correct geolocation object and properties', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.geolocation.countryCode, 'US');
|
||||
assert.equal(req.geolocation.latitude, 42.4019);
|
||||
assert.equal(req.geolocation.longitude, -71.1193);
|
||||
});
|
||||
|
||||
it('should contain correct current customer profile and properties', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.currentCustomer.profile.firstName, 'John');
|
||||
assert.equal(req.currentCustomer.profile.lastName, 'Snow');
|
||||
assert.equal(req.currentCustomer.profile.email, 'jsnow@starks.com');
|
||||
assert.equal(req.currentCustomer.profile.phone, '1234567890');
|
||||
});
|
||||
|
||||
it('should contain correct customer credentials when customer unauthenticated', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.customer.authenticated = false;
|
||||
var req = new Request(fakeRequest, fakeRequest.customer, createFakeRequest().session);
|
||||
assert.equal(req.currentCustomer.credentials.username, 'jsnow@starks.com');
|
||||
});
|
||||
|
||||
it('should contain correct current customer address book and properties', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedResult = createFakeRequest();
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.address1,
|
||||
'15 South Point Drive'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.address2,
|
||||
null
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.city,
|
||||
'Boston'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.countryCode.displayValue,
|
||||
'United States'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.countryCode.value,
|
||||
'US'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.firstName,
|
||||
'John'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.lastName,
|
||||
'Snow'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.ID,
|
||||
'Home'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.stateCode,
|
||||
'MA'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.postalCode,
|
||||
'02125'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.postBox,
|
||||
'2134'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.salutation,
|
||||
null
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.secondName,
|
||||
null
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.suffix,
|
||||
null
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.suite,
|
||||
'302'
|
||||
);
|
||||
assert.equal(
|
||||
req.currentCustomer.addressBook.preferredAddress.title,
|
||||
'Dr'
|
||||
);
|
||||
assert.deepEqual(
|
||||
req.currentCustomer.addressBook.preferredAddress.raw,
|
||||
expectedResult.customer.addressBook.preferredAddress
|
||||
);
|
||||
});
|
||||
|
||||
it('should contain correct current customer wallet and properties', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedResult = createFakeRequest();
|
||||
assert.deepEqual(
|
||||
req.currentCustomer.wallet.paymentInstrument,
|
||||
expectedResult.customer.profile.wallet.paymentInstruments[0]
|
||||
);
|
||||
});
|
||||
|
||||
it('should not fail if customer does not exist', function () {
|
||||
var req = new Request(createFakeRequest({ customer: null }), null, createFakeRequest().session);
|
||||
assert.equal(req.host, 'localhost');
|
||||
});
|
||||
|
||||
it('should not fail if customer does not have a profile', function () {
|
||||
var req = new Request(createFakeRequest({ customer: { profile: null } }), { profile: null }, createFakeRequest().session);
|
||||
assert.equal(req.currentCustomer.raw.profile, null);
|
||||
});
|
||||
|
||||
it('should retrieve form properties', function () {
|
||||
var items = {
|
||||
one: { rawValue: 1 },
|
||||
two: { rawValue: 2 },
|
||||
three: { rawValue: 3 },
|
||||
submitted: { },
|
||||
id: { rawValue: 22 },
|
||||
name: { rawValue: 'foo' }
|
||||
};
|
||||
var httpParamMap = {
|
||||
parameterNames: {
|
||||
iterator: function () {
|
||||
var index = 0;
|
||||
return {
|
||||
hasNext: function () {
|
||||
return index < Object.keys(items).length - 1;
|
||||
},
|
||||
next: function () {
|
||||
var value = Object.keys(items)[index];
|
||||
index++;
|
||||
return value;
|
||||
}
|
||||
};
|
||||
},
|
||||
length: Object.keys(items).length
|
||||
},
|
||||
get: function (name) {
|
||||
return items[name];
|
||||
}
|
||||
};
|
||||
var req = new Request(
|
||||
createFakeRequest({ httpParameterMap: httpParamMap, httpQueryString: 'id=22&name=foo' }),
|
||||
null,
|
||||
createFakeRequest().session
|
||||
);
|
||||
assert.equal(req.form.one, 1);
|
||||
assert.equal(req.form.two, 2);
|
||||
assert.equal(req.form.three, 3);
|
||||
assert.isUndefined(req.form.submitted);
|
||||
assert.isUndefined(req.form.id);
|
||||
});
|
||||
|
||||
it('should contain locale ID', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedResult = createFakeRequest();
|
||||
assert.deepEqual(
|
||||
req.locale.id,
|
||||
expectedResult.locale
|
||||
);
|
||||
});
|
||||
|
||||
it('should contain session currency', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedResult = createFakeRequest();
|
||||
assert.deepEqual(
|
||||
req.locale.currency,
|
||||
expectedResult.session.currency
|
||||
);
|
||||
});
|
||||
|
||||
it('should contain session privacy', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedResult = req.session.raw.privacyCache.get('key');
|
||||
assert.equal(expectedResult, 'value');
|
||||
});
|
||||
|
||||
it('should contain session clickStream', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
var expectedClick = {
|
||||
host: 'clickObj.host',
|
||||
locale: 'clickObj.locale',
|
||||
path: 'clickObj.path',
|
||||
pipelineName: 'clickObj-pipelineName',
|
||||
queryString: 'clickObj.queryString',
|
||||
referer: 'clickObj.referer',
|
||||
remoteAddress: 'clickObj.remoteAddress',
|
||||
timestamp: 'clickObj.timestamp',
|
||||
url: 'clickObj.url',
|
||||
userAgent: 'clickObj.userAgent'
|
||||
};
|
||||
|
||||
var expectedResult = {
|
||||
clicks: [expectedClick],
|
||||
first: expectedClick,
|
||||
last: expectedClick,
|
||||
partial: false
|
||||
};
|
||||
|
||||
assert.deepEqual(req.session.clickStream, expectedResult);
|
||||
});
|
||||
|
||||
it('should call setCurrency once', function () {
|
||||
new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.isTrue(setCurrencyStub.calledOnce);
|
||||
});
|
||||
|
||||
it('should not call setCurrency when currency is a alternative currency code', function () {
|
||||
var fakeRequest = createFakeRequest({
|
||||
locale: 'en_US'
|
||||
});
|
||||
fakeRequest.session.currency.currencyCode = 'CAD';
|
||||
new Request(fakeRequest, fakeRequest.customer, fakeRequest.session);
|
||||
assert.isFalse(setCurrencyStub.calledOnce);
|
||||
});
|
||||
|
||||
|
||||
it('should contain correct geolocation object and properties wehn co geolocation exists', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
delete fakeRequest.geolocation;
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.geolocation.countryCode, 'US');
|
||||
assert.equal(req.geolocation.latitude, 90.0000);
|
||||
assert.equal(req.geolocation.longitude, 0.0000);
|
||||
});
|
||||
|
||||
it('should contain the correct referer', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.referer, 'https://www.salesforce.com');
|
||||
});
|
||||
|
||||
it('should contain the correct remote address', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.remoteAddress, '0.0.0.0');
|
||||
});
|
||||
|
||||
it('should not get body as string for a GET request', function () {
|
||||
var req = new Request(createFakeRequest(), createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.body, null);
|
||||
});
|
||||
|
||||
it('should get body as string for a POST request', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.httpMethod = 'POST';
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.body, '');
|
||||
});
|
||||
|
||||
it('should get body as string for a PUT request', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.httpMethod = 'PUT';
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.body, '');
|
||||
});
|
||||
|
||||
it('should get pageMetaData title', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.pageMetaData.setTitle('TestTitle');
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.pageMetaData.title, 'TestTitle');
|
||||
});
|
||||
|
||||
it('should get pageMetaData description', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.pageMetaData.setDescription('TestDescription');
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.pageMetaData.description, 'TestDescription');
|
||||
});
|
||||
|
||||
it('should get pageMetaData keywords', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.pageMetaData.setKeywords('TestKeywords');
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.equal(req.pageMetaData.keywords, 'TestKeywords');
|
||||
});
|
||||
|
||||
it('should get pageMetaData pageMetaTags', function () {
|
||||
var fakeRequest = createFakeRequest();
|
||||
fakeRequest.pageMetaData.addPageMetaTags([{ title: true, content: 'TestTitle' }]);
|
||||
var req = new Request(fakeRequest, createFakeRequest().customer, createFakeRequest().session);
|
||||
assert.deepEqual(req.pageMetaData.pageMetaTags, [{ title: true, content: 'TestTitle' }]);
|
||||
});
|
||||
});
|
@@ -0,0 +1,187 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var sinon = require('sinon');
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var Response = proxyquire('../../../../cartridges/modules/server/response', {
|
||||
'*/cartridge/config/httpHeadersConf': [
|
||||
{
|
||||
'id': 'someName',
|
||||
'value': 'someValue'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var res = {
|
||||
redirect: function () {},
|
||||
setHttpHeader: sinon.spy(),
|
||||
setContentType: sinon.spy(),
|
||||
setStatus: sinon.spy()
|
||||
};
|
||||
|
||||
describe('response', function () {
|
||||
it('should create response object with passed-in base', function () {
|
||||
var response = new Response(res);
|
||||
assert.property(response, 'base');
|
||||
assert.property(response.base, 'redirect');
|
||||
});
|
||||
|
||||
it('should correctly set view and viewData', function () {
|
||||
var response = new Response(res);
|
||||
response.render('test', { name: 'value' });
|
||||
assert.equal(response.view, 'test');
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
});
|
||||
|
||||
it('should extend viewData', function () {
|
||||
var response = new Response(res);
|
||||
response.setViewData({ name: 'value' });
|
||||
response.setViewData({ foo: 'bar' });
|
||||
response.render('test', { name: 'test' });
|
||||
assert.equal(response.viewData.name, 'test');
|
||||
assert.equal(response.viewData.foo, 'bar');
|
||||
});
|
||||
|
||||
it('should correctly store a page rendering and set viewData', function () {
|
||||
var response = new Response(res);
|
||||
response.page('test', { name: 'value' });
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
assert.equal(response.renderings.length, 1);
|
||||
assert.deepEqual(response.renderings[0], {
|
||||
type: 'render', subType: 'page', page: 'test', aspectAttributes: undefined
|
||||
});
|
||||
});
|
||||
|
||||
it('should correctly store a page rendering with aspectAttributes and set viewData', function () {
|
||||
var response = new Response(res);
|
||||
response.page('test', { name: 'value' }, { test: 'foo' });
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
assert.equal(response.renderings.length, 1);
|
||||
assert.deepEqual(response.renderings[0], {
|
||||
type: 'render', subType: 'page', page: 'test', aspectAttributes: { test: 'foo' }
|
||||
});
|
||||
});
|
||||
|
||||
it('should extend viewData for page', function () {
|
||||
var response = new Response(res);
|
||||
response.setViewData({ name: 'value' });
|
||||
response.setViewData({ foo: 'bar' });
|
||||
response.page('page', { name: 'test' });
|
||||
assert.equal(response.viewData.name, 'test');
|
||||
assert.equal(response.viewData.foo, 'bar');
|
||||
});
|
||||
|
||||
it('should not extend viewData with non-objects', function () {
|
||||
var response = new Response(res);
|
||||
response.setViewData({ name: 'value' });
|
||||
response.setViewData(function () {});
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
});
|
||||
|
||||
it('should correctly set json', function () {
|
||||
var response = new Response(res);
|
||||
response.json({ name: 'value' });
|
||||
assert.isTrue(response.isJson);
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
});
|
||||
|
||||
it('should correctly set xml', function () {
|
||||
var response = new Response(res);
|
||||
response.xml('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
|
||||
assert.isTrue(response.isXml);
|
||||
assert.equal(response.viewData.xml, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
|
||||
});
|
||||
|
||||
it('should correctly set url', function () {
|
||||
var response = new Response(res);
|
||||
response.redirect('hello');
|
||||
assert.equal(response.redirectUrl, 'hello');
|
||||
});
|
||||
|
||||
it('should correctly set redirect status', function () {
|
||||
var response = new Response(res);
|
||||
response.setRedirectStatus('301');
|
||||
assert.equal(response.redirectStatus, '301');
|
||||
});
|
||||
|
||||
it('should set and retrieve data', function () {
|
||||
var response = new Response(res);
|
||||
response.setViewData({ name: 'value' });
|
||||
assert.equal(response.getViewData().name, 'value');
|
||||
});
|
||||
|
||||
it('should log item', function () {
|
||||
var response = new Response(res);
|
||||
response.log('one', 'two', 'three');
|
||||
assert.equal(response.messageLog.length, 1);
|
||||
assert.equal(response.messageLog[0], 'one two three');
|
||||
});
|
||||
|
||||
it('should convert log item to json', function () {
|
||||
var response = new Response(res);
|
||||
response.log({ name: 'value' });
|
||||
assert.equal(response.messageLog.length, 1);
|
||||
assert.equal(response.messageLog[0], '{"name":"value"}');
|
||||
});
|
||||
|
||||
it('should try to print out a message', function () {
|
||||
var response = new Response(res);
|
||||
response.print('hello');
|
||||
|
||||
assert.equal(response.renderings.length, 1);
|
||||
assert.equal(response.renderings[0].type, 'print');
|
||||
assert.equal(response.renderings[0].message, 'hello');
|
||||
});
|
||||
|
||||
it('should set http header', function () {
|
||||
var response = new Response(res);
|
||||
response.setHttpHeader('aName', 'aValue');
|
||||
assert.isTrue(res.setHttpHeader.calledWith('aName', 'aValue'));
|
||||
});
|
||||
|
||||
it('should set content type', function () {
|
||||
var response = new Response(res);
|
||||
response.setContentType('text/html');
|
||||
assert.isTrue(res.setContentType.calledWith('text/html'));
|
||||
});
|
||||
|
||||
it('should set status code', function () {
|
||||
var response = new Response(res);
|
||||
response.setStatusCode(500);
|
||||
assert.isTrue(res.setStatus.calledWith(500));
|
||||
});
|
||||
|
||||
it('should set cache expiration for the page', function (done) {
|
||||
var response = new Response(res);
|
||||
response.cacheExpiration(6);
|
||||
assert.equal(6, response.cachePeriod);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should loop through and append to renderings array', function () {
|
||||
var response = new Response(res);
|
||||
response.renderings.push({ type: 'render', subType: 'isml' });
|
||||
|
||||
response.json({ name: 'value' });
|
||||
|
||||
assert.isTrue(response.isJson);
|
||||
assert.equal(response.viewData.name, 'value');
|
||||
|
||||
assert.equal(response.renderings.length, 1);
|
||||
assert.equal(response.renderings[0].type, 'render');
|
||||
assert.equal(response.renderings[0].subType, 'json');
|
||||
});
|
||||
|
||||
it('should loop through and append to renderings array', function () {
|
||||
var response = new Response(res);
|
||||
response.renderings.push({ type: 'print' });
|
||||
|
||||
response.json({ name: 'value' });
|
||||
|
||||
assert.equal(response.renderings.length, 2);
|
||||
assert.equal(response.renderings[0].type, 'print');
|
||||
|
||||
assert.equal(response.renderings[1].type, 'render');
|
||||
assert.equal(response.renderings[1].subType, 'json');
|
||||
});
|
||||
});
|
@@ -0,0 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var Response = proxyquire('../../../../cartridges/modules/server/response', {
|
||||
'*/cartridge/config/httpHeadersConf': [{ 'id': 'testId', 'value': 'testValue' }]
|
||||
});
|
||||
var Route = require('../../../../cartridges/modules/server/route');
|
||||
|
||||
var sinon = require('sinon');
|
||||
var assert = require('chai').assert;
|
||||
var mockReq = {
|
||||
path: '',
|
||||
querystring: {},
|
||||
locale: ''
|
||||
};
|
||||
var mockRes = {
|
||||
setViewData: function () {}
|
||||
};
|
||||
|
||||
describe('route', function () {
|
||||
it('should create a new route with a given number of steps', function () {
|
||||
function tempFunc(req, res, next) { next(); }
|
||||
var route = new Route('test', [tempFunc, tempFunc], mockReq, mockRes);
|
||||
assert.equal(route.name, 'test');
|
||||
assert.equal(route.chain.length, 2);
|
||||
});
|
||||
it('should update response after last step', function (done) {
|
||||
function tempFunc(req, res, next) {
|
||||
res.test = 'Hello'; // eslint-disable-line no-param-reassign
|
||||
next();
|
||||
}
|
||||
var route = new Route('test', [tempFunc], mockReq, mockRes);
|
||||
route.on('route:Complete', function (req, res) {
|
||||
assert.equal(res.test, 'Hello');
|
||||
done();
|
||||
});
|
||||
route.getRoute()();
|
||||
});
|
||||
it('should execute two middleware steps', function (done) {
|
||||
var i = 0;
|
||||
|
||||
function tempFunc(req, res, next) {
|
||||
i += 1;
|
||||
next();
|
||||
}
|
||||
var route = new Route('test', [tempFunc, tempFunc], mockReq, mockRes);
|
||||
route.on('route:Complete', function () {
|
||||
assert.equal(i, 2);
|
||||
done();
|
||||
});
|
||||
route.getRoute()();
|
||||
});
|
||||
it('should verify that response keeps redirect variable', function (done) {
|
||||
function tempFunc(req, res, next) {
|
||||
res.redirect('test');
|
||||
next();
|
||||
}
|
||||
var response = new Response({ redirect: function () {}, setHttpHeader: function () {} });
|
||||
var route = new Route('test', [tempFunc], mockReq, response);
|
||||
route.on('route:Redirect', function (req, res) {
|
||||
assert.equal(res.redirectUrl, 'test');
|
||||
done();
|
||||
});
|
||||
route.getRoute()();
|
||||
});
|
||||
it('should verify that redirect with implicit (not set) redirect status works', function (done) {
|
||||
var baseResponseRedirectMock = sinon.spy();
|
||||
function tempFunc(req, res, next) {
|
||||
res.redirect('test');
|
||||
next();
|
||||
}
|
||||
var response = new Response({ redirect: baseResponseRedirectMock, setHttpHeader: function () {} });
|
||||
var route = new Route('test', [tempFunc], mockReq, response);
|
||||
route.getRoute()();
|
||||
assert.isTrue(baseResponseRedirectMock.calledOnce);
|
||||
assert.isTrue(baseResponseRedirectMock.firstCall.calledWithExactly('test'));
|
||||
done();
|
||||
});
|
||||
it('should verify that redirect with explicit redirect status works', function (done) {
|
||||
var baseResponseRedirectMock = sinon.spy();
|
||||
function tempFunc(req, res, next) {
|
||||
res.setRedirectStatus(301);
|
||||
res.redirect('test');
|
||||
next();
|
||||
}
|
||||
var response = new Response({ redirect: baseResponseRedirectMock, setHttpHeader: function () {} });
|
||||
var route = new Route('test', [tempFunc], mockReq, response);
|
||||
route.getRoute()();
|
||||
assert.isTrue(baseResponseRedirectMock.calledOnce);
|
||||
assert.isTrue(baseResponseRedirectMock.firstCall.calledWithExactly('test', 301));
|
||||
done();
|
||||
});
|
||||
it('should throw an error', function () {
|
||||
function tempFunc(req, res, next) {
|
||||
next(new Error());
|
||||
}
|
||||
var res = {
|
||||
log: function () {},
|
||||
setViewData: mockRes.setViewData };
|
||||
var route = new Route('test', [tempFunc], mockReq, res);
|
||||
assert.throws(function () { route.getRoute()(); });
|
||||
});
|
||||
it('should correct append a step to the route', function () {
|
||||
function tempFunc(req, res, next) {
|
||||
next();
|
||||
}
|
||||
var route = new Route('test', [tempFunc, tempFunc], mockReq, mockRes);
|
||||
assert.equal(route.chain.length, 2);
|
||||
route.append(tempFunc);
|
||||
assert.equal(route.chain.length, 3);
|
||||
});
|
||||
it('should set error object on the response', function () {
|
||||
var RouteStaging = proxyquire('../../../../cartridges/modules/server/route', {
|
||||
'dw/system/System': {
|
||||
getInstanceType: function () {
|
||||
return false;
|
||||
},
|
||||
'PRODUCTION_SYSTEM': true
|
||||
}
|
||||
});
|
||||
|
||||
function tempFunc(req, res, next) {
|
||||
next();
|
||||
}
|
||||
var req = {
|
||||
path: mockReq.path,
|
||||
querystring: mockReq.querystring,
|
||||
locale: mockReq.locale
|
||||
};
|
||||
var route = new RouteStaging('test', [tempFunc], req, mockRes);
|
||||
route.getRoute()({
|
||||
ErrorText: 'hello',
|
||||
ControllerName: 'Foo',
|
||||
CurrentStartNodeName: 'Bar'
|
||||
});
|
||||
assert.isNotNull(req.error);
|
||||
assert.equal(req.error.errorText, 'hello');
|
||||
assert.equal(req.error.controllerName, 'Foo');
|
||||
assert.equal(req.error.startNodeName, 'Bar');
|
||||
});
|
||||
it('should set error object on the response to empty string if on production', function () {
|
||||
var RouteProduction = proxyquire('../../../../cartridges/modules/server/route', {
|
||||
'dw/system/System': {
|
||||
getInstanceType: function () {
|
||||
return true;
|
||||
},
|
||||
'PRODUCTION_SYSTEM': true
|
||||
}
|
||||
});
|
||||
|
||||
function tempFunc(req, res, next) {
|
||||
next();
|
||||
}
|
||||
var req = {
|
||||
path: mockReq.path,
|
||||
querystring: mockReq.querystring,
|
||||
locale: mockReq.locale
|
||||
};
|
||||
var route = new RouteProduction('test', [tempFunc], req, mockRes);
|
||||
route.getRoute()({
|
||||
ErrorText: 'hello',
|
||||
ControllerName: 'Foo',
|
||||
CurrentStartNodeName: 'Bar'
|
||||
});
|
||||
assert.isNotNull(req.error);
|
||||
assert.equal(req.error.errorText, '');
|
||||
assert.equal(req.error.controllerName, '');
|
||||
assert.equal(req.error.startNodeName, '');
|
||||
});
|
||||
});
|
@@ -0,0 +1,353 @@
|
||||
/* eslint "no-underscore-dangle": ["error", { "allow": ["__routes"] }] */
|
||||
|
||||
'use strict';
|
||||
|
||||
var Route = require('../../../../cartridges/modules/server/route');
|
||||
var assert = require('chai').assert;
|
||||
var middleware = require('../../../../cartridges/modules/server/middleware');
|
||||
var proxyquire = require('proxyquire').noCallThru().noPreserveCache();
|
||||
var sinon = require('sinon');
|
||||
|
||||
var render = {
|
||||
template: sinon.spy(),
|
||||
json: sinon.spy(),
|
||||
xml: sinon.spy(),
|
||||
applyRenderings: sinon.spy()
|
||||
};
|
||||
var server = null;
|
||||
|
||||
function request() {
|
||||
return {
|
||||
httpMethod: 'GET',
|
||||
host: 'localhost',
|
||||
path: 'test',
|
||||
querystring: '',
|
||||
locale: {
|
||||
id: ''
|
||||
},
|
||||
https: false,
|
||||
currentCustomer: {
|
||||
raw: {},
|
||||
profile: {},
|
||||
addressBook: {},
|
||||
wallet: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('server', function () {
|
||||
// this function initializes fields in the response object
|
||||
// which is created in the server.use method
|
||||
var initResponse = function (response) {
|
||||
response.cachePeriod = 0; // eslint-disable-line no-param-reassign
|
||||
response.cachePeriodUnit = null; // eslint-disable-line no-param-reassign
|
||||
response.personalized = false; // eslint-disable-line no-param-reassign
|
||||
response.base = { // eslint-disable-line no-param-reassign
|
||||
setExpires: function () {},
|
||||
setVaryBy: function () {},
|
||||
writer: {
|
||||
print: function (message) { assert.equal(message, 'test'); }
|
||||
}
|
||||
};
|
||||
response.json = function () {}; // eslint-disable-line no-param-reassign
|
||||
response.isJson = true; // eslint-disable-line no-param-reassign
|
||||
response.setViewData = function () { // eslint-disable-line no-param-reassign
|
||||
return '';
|
||||
};
|
||||
response.renderings = [{ type: 'render', subType: 'json' }]; // eslint-disable-line no-param-reassign
|
||||
return response;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
server = proxyquire('../../../../cartridges/modules/server/server', {
|
||||
'./render': render,
|
||||
'./request': request,
|
||||
'./response': require('../../../mocks/modules/responseMock'),
|
||||
'dw/system/HookMgr': {
|
||||
hasHook: function (/* extension */) {
|
||||
return true;
|
||||
},
|
||||
callHook: function (/* extensionPoint, functionName , args */) {
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a server with one route', function () {
|
||||
server.use('test', function () {});
|
||||
var exports = server.exports();
|
||||
assert.equal(typeof exports.test, 'function');
|
||||
});
|
||||
|
||||
it('should apply default page cache period value', function () {
|
||||
var mockResp = null;
|
||||
server.use('test', function (req, res, next) {
|
||||
mockResp = initResponse(res);
|
||||
res.cachePeriod = 24; // eslint-disable-line no-param-reassign
|
||||
res.cachePeriodUnit = 'hours'; // eslint-disable-line no-param-reassign
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
var route = exports.__routes.test;
|
||||
var routeStartHit = false;
|
||||
var routeCompleteHit = false;
|
||||
|
||||
route.once('route:Start', function () {
|
||||
routeStartHit = true;
|
||||
});
|
||||
route.on('route:Complete', function () {
|
||||
routeCompleteHit = true;
|
||||
assert.equal(typeof mockResp.cachePeriod, 'number');
|
||||
assert.equal(24, mockResp.cachePeriod);
|
||||
assert.equal('hours', mockResp.cachePeriodUnit);
|
||||
assert.equal(false, mockResp.personalized);
|
||||
});
|
||||
exports.test();
|
||||
assert.isTrue(routeStartHit);
|
||||
assert.isTrue(routeCompleteHit);
|
||||
});
|
||||
|
||||
it('should apply default page cache period value', function () {
|
||||
var mockResp = null;
|
||||
server.use('test', function (req, res, next) {
|
||||
mockResp = initResponse(res);
|
||||
res.cachePeriod = 30; // eslint-disable-line no-param-reassign
|
||||
res.cachePeriodUnit = 'minutes'; // eslint-disable-line no-param-reassign
|
||||
res.personalized = true; // eslint-disable-line no-param-reassign
|
||||
res.renderings = [{ type: 'render', subType: 'xml' }]; // eslint-disable-line no-param-reassign
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
var route = exports.__routes.test;
|
||||
var routeStartHit = false;
|
||||
var routeCompleteHit = false;
|
||||
|
||||
route.once('route:Start', function () {
|
||||
routeStartHit = true;
|
||||
});
|
||||
route.on('route:Complete', function () {
|
||||
routeCompleteHit = true;
|
||||
assert.equal(typeof mockResp.cachePeriod, 'number');
|
||||
assert.equal(30, mockResp.cachePeriod);
|
||||
assert.equal('minutes', mockResp.cachePeriodUnit);
|
||||
assert.equal(true, mockResp.personalized);
|
||||
});
|
||||
exports.test();
|
||||
assert.isTrue(routeStartHit);
|
||||
assert.isTrue(routeCompleteHit);
|
||||
});
|
||||
|
||||
it('should print', function () {
|
||||
server.use('test', function (req, res, next) {
|
||||
initResponse(res);
|
||||
res.cachePeriod = 30; // eslint-disable-line no-param-reassign
|
||||
res.cachePeriodUnit = 'minutes'; // eslint-disable-line no-param-reassign
|
||||
res.personalized = true; // eslint-disable-line no-param-reassign
|
||||
res.renderings = [{ type: 'print', message: 'test' }]; // eslint-disable-line no-param-reassign
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
|
||||
exports.test();
|
||||
});
|
||||
|
||||
it('should create a server with a route of two steps', function () {
|
||||
server.get('test', function () {});
|
||||
var exports = server.exports();
|
||||
assert.equal(exports.__routes.test.chain.length, 2);
|
||||
});
|
||||
|
||||
it('should create a server with two routes', function () {
|
||||
server.get('test', function () {}, function () {});
|
||||
server.post('test2', function () {});
|
||||
var exports = server.exports();
|
||||
assert.equal(typeof exports.test, 'function');
|
||||
assert.equal(typeof exports.test2, 'function');
|
||||
assert.equal(exports.__routes.test.chain.length, 3);
|
||||
assert.equal(exports.__routes.test2.chain.length, 2);
|
||||
});
|
||||
|
||||
it('should extend existing chain with 2 more steps', function () {
|
||||
server.get('test', function () {});
|
||||
var exports = server.exports();
|
||||
assert.equal(exports.__routes.test.chain.length, 2);
|
||||
server.extend(exports);
|
||||
server.append('test', function () {}, function () {});
|
||||
assert.equal(exports.__routes.test.chain.length, 4);
|
||||
});
|
||||
|
||||
it('The extended chain with append should be executed last.', function () {
|
||||
server.get('test', function () {});
|
||||
var exports = server.exports();
|
||||
server.extend(exports);
|
||||
server.append('test', function () {}, function () { return 'EXECUTED'; });
|
||||
assert.equal(server.getRoute('test').chain[3](), 'EXECUTED');
|
||||
});
|
||||
|
||||
it('The extended chain with prepend should be executed first.', function () {
|
||||
server.get('test', function () {});
|
||||
var exports = server.exports();
|
||||
server.extend(exports);
|
||||
server.prepend('test', function () { return 'EXECUTED'; });
|
||||
assert.equal(server.getRoute('test').chain[0](), 'EXECUTED');
|
||||
});
|
||||
|
||||
it('should replace existing route with a new one', function () {
|
||||
var spy = sinon.spy();
|
||||
var spy2 = sinon.spy();
|
||||
server.get('test', spy);
|
||||
var exports = server.exports();
|
||||
|
||||
server.extend(exports);
|
||||
server.replace('test', spy2);
|
||||
var newExports = server.exports();
|
||||
newExports.test();
|
||||
assert.isTrue(spy.notCalled);
|
||||
assert.isTrue(spy2.called);
|
||||
});
|
||||
|
||||
it('should throw when replacing non-existing route', function () {
|
||||
var testFn = function () {
|
||||
server.replace('blah', function () {});
|
||||
};
|
||||
assert.throws(testFn, 'Route with this name does not exist');
|
||||
});
|
||||
|
||||
it('should throw when trying to create two routes with the same name', function () {
|
||||
server.get('test', function () {});
|
||||
assert.throws(function () { server.post('test', function () {}); });
|
||||
});
|
||||
|
||||
it('should throw when route name is not provided', function () {
|
||||
assert.throws(function () { server.get(function () {}); });
|
||||
});
|
||||
|
||||
it('should throw when route chain contains non-functions', function () {
|
||||
assert.throws(function () { server.get('test', {}); });
|
||||
});
|
||||
|
||||
it('should throw when trying to append to non-existing route', function () {
|
||||
server.get('test', function () {});
|
||||
server.extend(server.exports());
|
||||
assert.throws(function () { server.append('foo', function () {}); });
|
||||
});
|
||||
|
||||
it('should throw when extending server without routes', function () {
|
||||
assert.throws(function () { server.extend(server.exports()); });
|
||||
});
|
||||
|
||||
it('should throw when extending server with an object', function () {
|
||||
assert.throws(function () { server.extend({}); });
|
||||
});
|
||||
|
||||
it('should throw when middleware doesn\'t match route', function () {
|
||||
server.post('test', middleware.https, function (req, res, next) {
|
||||
req.render('test', { name: 'value' }); next();
|
||||
});
|
||||
assert.throws(function () { server.exports().test(); });
|
||||
});
|
||||
|
||||
it('should verify that whole route passes', function () {
|
||||
server.get('test', middleware.http, function (req, res, next) {
|
||||
res.render('test', { name: 'value' });
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
exports.test();
|
||||
var result = render.applyRenderings.called;
|
||||
assert.isTrue(result);
|
||||
});
|
||||
|
||||
it('should verify that all events are emitted', function (done) {
|
||||
server.get('test', middleware.http, function (req, res, next) {
|
||||
res.json({ name: 'value' });
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
var route = exports.__routes.test;
|
||||
var routeStartHit = false;
|
||||
var routeStepHits = 0;
|
||||
|
||||
route.once('route:Start', function () {
|
||||
routeStartHit = true;
|
||||
});
|
||||
route.on('route:Step', function () {
|
||||
routeStepHits += 1;
|
||||
});
|
||||
route.on('route:Complete', function () {
|
||||
assert.isTrue(routeStartHit);
|
||||
assert.equal(routeStepHits, 2);
|
||||
done();
|
||||
});
|
||||
exports.test();
|
||||
});
|
||||
|
||||
it('should maintain events for exported route', function () {
|
||||
var spy = sinon.spy();
|
||||
var spy2 = sinon.spy();
|
||||
server.get('test', spy);
|
||||
|
||||
var exports = server.exports();
|
||||
var route = exports.__routes.test;
|
||||
|
||||
route.on('route:Start', spy2);
|
||||
|
||||
var exported = server.exports();
|
||||
assert.equal(exported.__routes.test.listeners('route:Start').length, 1);
|
||||
});
|
||||
|
||||
it('should correctly remove event after export', function () {
|
||||
var spy = sinon.spy();
|
||||
var spy2 = sinon.spy();
|
||||
server.get('test', spy);
|
||||
|
||||
var exports = server.exports();
|
||||
var route = exports.__routes.test;
|
||||
|
||||
route.on('route:Start', spy2);
|
||||
|
||||
var exported = server.exports();
|
||||
exported.__routes.test.off('route:Start');
|
||||
exported.test();
|
||||
|
||||
assert.isTrue(spy.called);
|
||||
assert.isTrue(spy2.notCalled);
|
||||
});
|
||||
|
||||
it('should verify that request is frozen', function (done) {
|
||||
server.get('test', function (req) {
|
||||
assert.isFrozen(req);
|
||||
done();
|
||||
});
|
||||
server.exports().test();
|
||||
});
|
||||
|
||||
it('should retrieve a route by name', function () {
|
||||
server.get('test', function (req, res, next) {
|
||||
res.json({ name: 'value' });
|
||||
next();
|
||||
});
|
||||
var testRoute = server.getRoute('test');
|
||||
assert.isNotNull(testRoute);
|
||||
});
|
||||
|
||||
it('should return a route on get call', function () {
|
||||
var route = server.get('test', function () {});
|
||||
assert.isTrue(route instanceof Route);
|
||||
});
|
||||
|
||||
it('should redirect if requested in BeforeComplete', function (done) {
|
||||
server.get('test', function (req, res, next) {
|
||||
this.on('route:BeforeComplete', function (r, response) {
|
||||
response.base.redirect = function (text) { // eslint-disable-line no-param-reassign
|
||||
assert.equal(text, 'test');
|
||||
done();
|
||||
};
|
||||
response.redirect('test');
|
||||
});
|
||||
next();
|
||||
});
|
||||
var exports = server.exports();
|
||||
exports.test();
|
||||
});
|
||||
});
|
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('chai').assert;
|
||||
var SimpleCache = require('../../../../cartridges/modules/server/simpleCache');
|
||||
|
||||
describe('simpleCache', function () {
|
||||
beforeEach(function () {
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
});
|
||||
|
||||
it('should handle null argument for constructor', function () {
|
||||
var cache = new SimpleCache(null);
|
||||
|
||||
assert.isTrue(cache !== null);
|
||||
});
|
||||
|
||||
it('should accept a pre-filled KV store', function () {
|
||||
var cache = new SimpleCache({ 'foo': 'bar' });
|
||||
var value = cache.get('foo');
|
||||
|
||||
assert.isTrue(value === 'bar');
|
||||
});
|
||||
|
||||
it('should get a value previously set', function () {
|
||||
var cache = new SimpleCache({});
|
||||
cache.set('foo', 'bar');
|
||||
var value = cache.get('foo');
|
||||
|
||||
assert.isTrue(value === 'bar');
|
||||
});
|
||||
|
||||
it('should correctly clear() values previously set', function () {
|
||||
var cache = new SimpleCache({});
|
||||
cache.set('foo', 'bar');
|
||||
cache.clear();
|
||||
var value = cache.get('foo');
|
||||
|
||||
assert.isTrue(value === null);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user