" ).appendTo( "#interactions" );
12 | }
13 |
14 | // loadScript based on Answer by e-satis
15 | // from http://stackoverflow.com/a/950146/40444
16 | function loadScript(url, callback)
17 | {
18 | // Adding the script tag to the head as suggested before
19 | var head = document.getElementsByTagName('head')[0];
20 | var script = document.createElement('script');
21 | script.type = 'text/javascript';
22 | script.src = url;
23 |
24 | // Then bind the event to the callback function.
25 | // There are several events for cross browser compatibility.
26 | script.onreadystatechange = callback;
27 | script.onload = callback;
28 |
29 | // Fire the loading
30 | head.appendChild(script);
31 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Indiegogo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/example/payment.js:
--------------------------------------------------------------------------------
1 | $( document ).ready(function () {
2 | configureApplePay();
3 | });
4 |
5 | function configureApplePay() {
6 | if (window.ApplePaySession) {
7 | ApplePaySession.canMakePaymentsWithActiveCard("com.example.e-commerce").
8 | then(function (canMakePayments) {
9 | if (canMakePayments) {
10 | $(".apple-pay").show();
11 | $(".no-apple-pay").hide();
12 | } else {
13 | $(".apple-pay").hide();
14 | $(".no-apple-pay").show();
15 | }
16 | });
17 | }
18 | }
19 |
20 | $( ".apple-pay" ).click(function() {
21 | var request = {};
22 | var session = new ApplePaySession(1, request);
23 | session.onvalidatemerchant = function (event) {
24 | logSessionInteraction("Validate Merchant Requested");
25 | var fakeMerchantSession = {};
26 | session.completeMerchantValidation(fakeMerchantSession);
27 | }
28 |
29 | session.oncancel = function(event) {
30 | logSessionInteraction("Payment Cancelled");
31 | }
32 |
33 | session.onshippingcontactselected = function(event) {
34 | logSessionInteraction("Shipping Contact Selected");
35 | session.completeShippingContactSelection(123, [], {}, {});
36 | };
37 |
38 | session.onpaymentauthorized = function(event) {
39 | logSessionInteraction("Payment Authorized by User");
40 | session.completePayment();
41 | };
42 |
43 | session.begin();
44 | });
--------------------------------------------------------------------------------
/example/stub-configuration.js:
--------------------------------------------------------------------------------
1 | // Stub Configuration
2 |
3 | $( document ).ready(function () {
4 | $( ".stub-config").prop("disabled",true);
5 | });
6 |
7 | function loadStubs() {
8 | loadScript("../src/apple-pay-js-stubs.js", function() {
9 | enableStubPaymentsForBrowser();
10 | configureApplePay();
11 | });
12 | $ ( "#enable-stubbing").text("Stubs Loaded");
13 | $ ( "#enable-stubbing").prop("disabled",true);
14 | $ ( ".stub-config").prop("disabled",false);
15 |
16 | $ ( "#stub-config-cancel").click(configureStubBehaviourCancel);
17 | $ ( "#stub-config-shipping-authorize").click(configureStubBehaviourShippingAuthorize);
18 | }
19 |
20 | function resetExample() {
21 | enableStubPaymentsForBrowser();
22 | }
23 |
24 | function enableStubPaymentsForBrowser() {
25 | ApplePaySession.stubCanMakePaymentsWithActiveCard = true;
26 | ApplePaySession.stubExecuteAfterMerchantValidation = function (session) {
27 | logSessionError("Error: No stub behaviour selected - please choose a configuration above first!");
28 | }
29 | }
30 |
31 | function configureStubBehaviourCancel() {
32 | ApplePaySession.stubExecuteAfterMerchantValidation = function (session) {
33 | // 1. Stub acts as if the user cancels the paysheet
34 | var event = {};
35 | session.oncancel(event);
36 |
37 | resetExample();
38 | };
39 | }
40 |
41 | function configureStubBehaviourShippingAuthorize() {
42 | ApplePaySession.stubExecuteAfterMerchantValidation = function (session) {
43 | // 1. Stub acts as if the user selects a on a shipping address
44 | var event = {};
45 | session.onshippingcontactselected(event);
46 | // 2. Stub acts as if the user authorizes the payment
47 | session.onpaymentauthorized(event);
48 |
49 | resetExample();
50 | };
51 | }
52 |
53 | $("#enable-stubbing").click(function () {
54 | loadStubs();
55 | configureApplePay();
56 | });
--------------------------------------------------------------------------------
/test/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Mon Aug 01 2016 09:35:18 GMT-0700 (PDT)
3 |
4 | module.exports = function(config) {
5 | var cfg = {
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '../',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['mocha', 'chai-as-promised', 'chai'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'src/*.js',
19 | 'test/*.js'
20 | ],
21 |
22 |
23 | // list of files to exclude
24 | exclude: [
25 | ],
26 |
27 |
28 | // preprocess matching files before serving them to the browser
29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
30 | preprocessors: {
31 | },
32 |
33 |
34 | // test results reporter to use
35 | // possible values: 'dots', 'progress'
36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
37 | reporters: ['dots'],
38 |
39 |
40 | // web server port
41 | port: 9876,
42 |
43 |
44 | // enable / disable colors in the output (reporters and logs)
45 | colors: true,
46 |
47 |
48 | // level of logging
49 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
50 | logLevel: config.LOG_INFO,
51 |
52 |
53 | // enable / disable watching file and executing tests whenever any file changes
54 | autoWatch: true,
55 |
56 |
57 | // start these browsers
58 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
59 | browsers: ['Firefox'],
60 |
61 |
62 | // Continuous Integration mode
63 | // if true, Karma captures browsers, runs the tests and exits
64 | singleRun: false,
65 |
66 | // Concurrency level
67 | // how many browser should be started simultaneous
68 | concurrency: Infinity,
69 | };
70 |
71 | config.set(cfg);
72 | }
73 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | apple-pay-js-stubs Example
4 |
26 |
27 |
28 |
29 |
Amazing Product
30 |
This is a product you'd definitely pay $10 for.
31 |
Price: $10
32 |
33 |
34 |
35 |
apple-pay-js-stubs Example Console
36 |
37 |
Configure apple-pay-js-stubs
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
Log of Stubbed Behaviour
47 |
48 |
49 |
50 |
Instructions
51 |
52 | Initially this page is loaded without apple-pay-js-stubs loaded.
53 | To try out apple-pay-js-stubs you can control the stub behaviour using the Example Console above.
54 |
55 | You can enable stubbing for a given configuration by:
56 |
57 |
Clicking 'Load apple-pay-js-stubs'
58 |
Clicking your preferred configuration option
59 |
then click the '🍎 Pay'
60 |
61 | The 'Log of Stubbed Behaviour' outputs the stubbed user behaviour as a result of your clck on the '🍎 Pay' button.
62 | Note: after every '🍎 Pay' press the stub behaviour will be cleared. So please reselect another option between presses.
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at open-source@indiegogo.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [http://contributor-covenant.org/version/1/4][version]
72 |
73 | [homepage]: http://contributor-covenant.org
74 | [version]: http://contributor-covenant.org/version/1/4/
75 |
--------------------------------------------------------------------------------
/src/apple-pay-js-stubs.js:
--------------------------------------------------------------------------------
1 | // Based on solution by naomik here http://stackoverflow.com/a/24216547
2 | class Emitter {
3 | constructor() {
4 | var delegate = document.createDocumentFragment();
5 | [
6 | 'addEventListener',
7 | 'dispatchEvent',
8 | 'removeEventListener'
9 | ].forEach(f =>
10 | this[f] = (...xs) => delegate[f](...xs)
11 | )
12 | }
13 | }
14 |
15 | class ApplePaySessionStub extends Emitter {
16 | constructor(version, paymentRequest) {
17 | super();
18 | this.version = version;
19 | this._request = paymentRequest;
20 | }
21 |
22 | // Static Stub configuration
23 |
24 | static get stubCanMakePayments() {
25 | return this._stubCanMakePayments;
26 | }
27 |
28 | static set stubCanMakePayments(value) {
29 | this._stubCanMakePayments = value;
30 | }
31 |
32 | static get stubCanMakePaymentsWithActiveCard() {
33 | return this._stubCanMakePaymentsWithActiveCard;
34 | }
35 |
36 | static set stubCanMakePaymentsWithActiveCard(value) {
37 | this._stubCanMakePaymentsWithActiveCard = value;
38 | }
39 |
40 | static set stubExecuteAfterMerchantValidation(callback) {
41 | this._stubExecuteAfterMerchantValidation = callback;
42 | }
43 |
44 | static get stubExecuteAfterMerchantValidation() {
45 | return this._stubExecuteAfterMerchantValidation;
46 | }
47 |
48 | // Static Apple Pay JS interface
49 |
50 | static canMakePayments() {
51 | return this._stubCanMakePayments;
52 | }
53 |
54 | static canMakePaymentsWithActiveCard(merchantIdentifier) {
55 | return Promise.resolve(this.stubCanMakePaymentsWithActiveCard);
56 | }
57 |
58 | static supportsVersion(version) {
59 | return true;
60 | }
61 |
62 | // Instance Apple Pay JS interface
63 |
64 | abort() {}
65 |
66 | begin() {
67 | let url = 'https://apple-pay-gateway-cert.apple.com/paymentservices/startSession';
68 | if (this._onvalidatemerchant) {
69 | this._onvalidatemerchant(
70 | {validationURL: url}
71 | );
72 | }
73 | var event = new ApplePayValidateMerchantEvent(url);
74 | this.dispatchEvent(event);
75 | }
76 |
77 | completeMerchantValidation(merchantSession) {
78 | if (!ApplePaySession.stubExecuteAfterMerchantValidation) {
79 | throw "Error: No stubExecuteAfterMerchantValidation() callback set";
80 | }
81 | ApplePaySession.stubExecuteAfterMerchantValidation(this);
82 | }
83 |
84 | completePayment(status) { }
85 |
86 | completePaymentMethodSelection(newTotal, newLineItems) { }
87 |
88 | completeShippingContactSelection(status, newShippingMethods, newTotal, newLineItems) { }
89 |
90 | completeShippingMethodSelection(status, newTotal, newLineItems) { }
91 |
92 | set onvalidatemerchant(value) {
93 | this._onvalidatemerchant = value;
94 | }
95 |
96 | // Stub helper methods
97 |
98 | get request() {
99 | return this._request;
100 | }
101 |
102 | }
103 |
104 | window.ApplePaySession = ApplePaySessionStub;
105 |
106 | class ApplePayPaymentAuthorizedEvent extends Event {
107 | constructor(payment) {
108 | super("paymentauthorized");
109 | this._payment = payment;
110 | }
111 |
112 | get payment() {
113 | return this._payment;
114 | }
115 | }
116 | window.ApplePayPaymentAuthorizedEvent = ApplePayPaymentAuthorizedEvent;
117 |
118 | class ApplePayValidateMerchantEvent extends Event {
119 | constructor(validationURL) {
120 | super("validatemerchant");
121 | this._validationURL = validationURL;
122 | }
123 |
124 | get validationURL() {
125 | return this._validationURL;
126 | }
127 | }
128 | window.ApplePayValidateMerchantEvent = ApplePayValidateMerchantEvent;
129 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # apple-pay-js-stubs
2 | The Apple Pay JS Stubs provide a stubbed implementation of the ApplePay JS framework allowing you to acceptance test your Apple Pay for the Web code without requiring Safari, or an iPhone with iOS 10
3 |
4 | [](https://travis-ci.org/indiegogo/apple-pay-js-stubs)
5 |
6 | This stubbed implementation substitutes the ApplePay JS API normally provided by the Safari browser on iOS 10, and macOS Sierra with a stubbed javascript implementation.
7 |
8 | Unlike the offical API, apple-pay-js-stubs presents no paysheet or other visual feedback when called, instead it can be configured to executes the ApplePay JS callbacks based the test scenario pre-configured by *you* the developer.
9 |
10 | This approach allows you to simulate both the ApplePay paysheet and user behaviour quickly and easily without requiring a physical ApplePay capable device.
11 |
12 | # Requirements
13 | - ECMAScript 6 complient browser
14 | - Tested in:
15 | - Chrome 51.0.2704.103 (64-bit)
16 | - Firefox 48.0
17 | - Safari Version 9.1 (11601.5.17.1)
18 |
19 | # Installation and Usage
20 |
21 | ## Step 1: Install apple-pay-js-stubs
22 | ### Option a: Install using node
23 | ```bash
24 | npm install apple-pay-js-stubs
25 | ```
26 |
27 | ### Option b: Manually by downloading
28 |
29 | Alternatively you can download the [apple-pay-js-stubs.js file here](https://github.com/indiegogo/apple-pay-js-stubs/blob/master/src/apple-pay-js-stubs.js)
30 |
31 | ## Step 2: Load Javascript file in your acceptance tests
32 |
33 | In order for apple-pay-js-stubs.js to be available when your acceptance tests run, you'll need to load the javascript file on the page in your website which normally interacts with the window.ApplePaySession object.
34 |
35 | **Note: You should only do this when you're running your automated acceptance tests to avoid conflicting with Safari in your production environment**
36 |
37 | How you go about this will depend on what language you are writing your acceptance tests in.
38 |
39 | For acceptance tests written in Ruby's RSpec you can load `apple-pay-js-stubs.js` after you visit your ApplePay supporting webpage as follows:
40 | ```ruby
41 | javascript = <<-JAVASCRIPT
42 | var js = document.createElement("script");
43 | js.type = "text/javascript";
44 | js.src = "/assets/test_support/apple-pay-js-stubs.js";
45 | document.body.appendChild(js);
46 | JAVASCRIPT
47 | page.execute_script(javascript)
48 | ```
49 | (where `/assets/test_support/` is the path on your website to the apple-pay-js-stubs.js file)
50 |
51 | Note: This approach will result in a delay in `window.ApplePaySession` being available which may not be the same as on the real ApplePay supporting browser.
52 |
53 | ## Step 3: Configure the Stubs for your current test
54 |
55 | Each test using ApplePay/apple-pay-js-stubs, will need to configure the ApplePaySessionStubs class (stored in window.ApplePaySession) before executing the test. This is how you configure the call backs to simulate the users, and ApplePay JS's normal behaviour for a specific scenario.
56 |
57 | You can configure this by running the following javascript code on you page before each test:
58 |
59 | ```javascript
60 | // Configure what a call to ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier) should result to
61 | ApplePaySession.stubCanMakePaymentsWithActiveCard = true; // ApplePaySession.canMakePaymentsWithActiveCard() returns promise resulting to true
62 |
63 | ApplePaySession.stubExecuteAfterMerchantValidation = function(session) {
64 | // Call callbacks on session to simulate ApplePay JS / user behaviour
65 | };
66 | ```
67 |
68 | # Example Configurations
69 | Some example apple-pay-js-stubs javascript configurations:
70 |
71 | ### User without ApplePay configured
72 | ```javascript
73 | ApplePaySession.stubCanMakePaymentsWithActiveCard = false;
74 | ```
75 |
76 | ### User cancels payment after opening paysheet
77 | ```javascript
78 | ApplePaySession.stubCanMakePaymentsWithActiveCard = true;
79 | ApplePaySession.stubExecuteAfterMerchantValidation = function(session) {
80 | session.oncancel({})
81 | };
82 | ```
83 |
84 | ### User selects a shipping address, then authorizes the payment
85 | ```javascript
86 | ApplePaySession.stubCanMakePaymentsWithActiveCard = true;
87 | ApplePaySession.stubExecuteAfterMerchantValidation = function (session) {
88 | var event = {};
89 | // 1. Stub acts as if the user selects a on a shipping address
90 | session.onshippingcontactselected(event);
91 | // 2. Stub acts as if the user authorizes the payment
92 | session.onpaymentauthorized(event);
93 | };
94 | ```
95 |
96 |
97 | # apple-pay-js-stubs Demo / Example
98 |
99 | You can see an example web page which demonstrates some of the capabilities of the stubs in [/example/index.html](/example/index.html).
100 |
101 | A few things to note:
102 | * To get the demo to load, you'll need to clone the repository locally then open example/index.html in the Chrome browser.
103 | * This demonstrates the stubs through an interactive 'Console'. Typically usage will be driven from your acceptance tests instead of interactively.
104 |
105 |
106 | ## Code of Conduct
107 | Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
108 |
--------------------------------------------------------------------------------
/test/apple-pay-js-stubs-test.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | describe('apple-pay-js-stubs', function() {
4 | describe("ApplePaySession", function () {
5 | var ApplePaySession = window.ApplePaySession;
6 | it("has window.ApplePaySession set", function () {
7 | expect(ApplePaySession).to.not.be.undefined;
8 | });
9 |
10 | describe('constructor', function () {
11 | it('should construct a session object', function() {
12 | var session = new ApplePaySession(1, {});
13 | expect(session).to.not.be.undefined;
14 | });
15 | });
16 |
17 | describe('static canMakePaymentsWithActiveCard()', function () {
18 | it('returns fulfilled promise with the configured mockCanMakePaymentsWithActiveCard value', function () {
19 | ApplePaySession.stubCanMakePaymentsWithActiveCard = false;
20 | ApplePaySession.canMakePaymentsWithActiveCard("com.fake.merchant.identifier").should.eventually.equal(false);
21 |
22 | ApplePaySession.stubCanMakePaymentsWithActiveCard = true;
23 | ApplePaySession.canMakePaymentsWithActiveCard("com.fake.merchant.identifier").should.eventually.equal(true);
24 | });
25 | });
26 |
27 | describe("supportsVersion(version)", function () {
28 | it("returns true", function () {
29 | expect(ApplePaySession.supportsVersion(123)).to.be.true;
30 | });
31 | });
32 |
33 | describe("abort()", function () {
34 | it("has implementation", function () {
35 | var session = new ApplePaySession(1, {});
36 | expect(function() {
37 | session.abort();
38 | }).to.not.throw();
39 | });
40 | });
41 |
42 | describe('begin()', function () {
43 | it('calls session.onvalidatemerchant() with expected validationURL', function () {
44 | var session = new ApplePaySession(1, {});
45 | var theEvent;
46 | session.onvalidatemerchant = function(event) {
47 | theEvent = event;
48 | };
49 | session.begin();
50 | expect(theEvent.validationURL).to.equal('https://apple-pay-gateway-cert.apple.com/paymentservices/startSession');
51 | });
52 |
53 | it('triggers ApplePayValidateMerchantEvent (validatemerchant) with expected validationURL', function () {
54 | var session = new ApplePaySession(1, {});
55 | var theEvent;
56 | session.addEventListener("validatemerchant", function(event){
57 | theEvent = event;
58 | });
59 | session.begin();
60 | expect(theEvent.validationURL).to.equal('https://apple-pay-gateway-cert.apple.com/paymentservices/startSession');
61 | });
62 | });
63 |
64 | describe("canMakePayments()", function () {
65 | it("has implementation that returns true", function () {
66 | ApplePaySession.stubCanMakePayments = true;
67 | expect(ApplePaySession.canMakePayments()).to.be.true;
68 | });
69 |
70 | it("has implementation that returns false", function () {
71 | ApplePaySession.stubCanMakePayments = false;
72 | expect(ApplePaySession.canMakePayments()).to.be.false;
73 | });
74 | });
75 |
76 | describe("completeMerchantValidation()", function() {
77 | var session;
78 | beforeEach(function () {
79 | session = new ApplePaySession(1, {});
80 | });
81 |
82 | it('throws exception when no ApplePaySession.stubExecuteAfterMerchantValidation() callback is set when completeMerchantValidation is called', function () {
83 | expect(function() {
84 | session.completeMerchantValidation({});
85 | }).to.throw("Error: No stubExecuteAfterMerchantValidation() callback set");
86 | });
87 |
88 | it('does not throw an exception when ApplePaySession.stubExecuteAfterMerchantValidation() callback is set when completeMerchantValidation is called', function () {
89 | ApplePaySession.stubExecuteAfterMerchantValidation = function() {};
90 | expect(function() {
91 | session.completeMerchantValidation({});
92 | }).to.not.throw();
93 | });
94 |
95 | it('calls ApplePaySession.stubExecuteAfterMerchantValidation() with session when completeMerchantValidation is called', function() {
96 | var calledWithSession;
97 | ApplePaySession.stubExecuteAfterMerchantValidation = function(session) {
98 | calledWithSession = session;
99 | };
100 | session.completeMerchantValidation({});
101 | expect(calledWithSession).to.eq(session);
102 | });
103 |
104 | it('retains ApplePaySession.stubExecuteAfterMerchantValidation() after completeMerchantValidation is called', function() {
105 | var calledWithSession;
106 | var executeAfterMerchantValidation = function(session) {
107 | calledWithSession = session;
108 | };
109 |
110 | ApplePaySession.stubExecuteAfterMerchantValidation = executeAfterMerchantValidation;
111 | session.completeMerchantValidation({});
112 | expect(ApplePaySession.stubExecuteAfterMerchantValidation).to.eq(executeAfterMerchantValidation);
113 | });
114 | });
115 |
116 | describe("completePayment(status)", function () {
117 | it("has implementation", function () {
118 | var session = new ApplePaySession(1, {});
119 | expect(function() {
120 | session.completePayment(123);
121 | }).to.not.throw();
122 | });
123 | });
124 |
125 | describe("completePaymentMethodSelection(newTotal, newLineItems)", function() {
126 | it("has implementation", function () {
127 | var session = new ApplePaySession(1, {});
128 | var newTotal = {};
129 | var newLineItems = [];
130 | expect(function() {
131 | session.completePaymentMethodSelection(newTotal, newLineItems);
132 | }).to.not.throw();
133 | });
134 | });
135 |
136 | describe("completeShippingContactSelection(status, newShippingMethods, newTotal, newLineItems)", function() {
137 | it("has implementation", function () {
138 | var session = new ApplePaySession(1, {});
139 | var newShippingMethods = [];
140 | var status = 123;
141 | var newTotal = {};
142 | var newLineItems = [];
143 | expect(function() {
144 | session.completeShippingContactSelection(status, newShippingMethods, newTotal, newLineItems);
145 | }).to.not.throw();
146 | });
147 | });
148 |
149 | describe("completeShippingMethodSelection(status, newTotal, newLineItems)", function() {
150 | it("has implementation", function () {
151 | var session = new ApplePaySession(1, {});
152 | var status = 123;
153 | var newTotal = {};
154 | var newLineItems = [];
155 | expect(function() {
156 | session.completeShippingMethodSelection(status, newTotal, newLineItems);
157 | }).to.not.throw();
158 | });
159 | });
160 |
161 | describe("request()", function () {
162 | it ("returns payment request", function () {
163 | var theRequest = {with: "expected value"};
164 | var session = new ApplePaySession(1, theRequest);
165 | expect(session.request).to.eq(theRequest);
166 | });
167 | });
168 | });
169 |
170 | describe("ApplePayPaymentAuthorizedEvent", function () {
171 | var ApplePayPaymentAuthorizedEvent = window.ApplePayPaymentAuthorizedEvent;
172 | it("has window.ApplePayPaymentAuthorizedEvent set", function () {
173 | expect(ApplePayPaymentAuthorizedEvent).to.not.be.undefined;
174 | });
175 |
176 | it("has 'paymentauthorized' event.type", function() {
177 | var event = new ApplePayPaymentAuthorizedEvent({});
178 | expect(event.type).to.eq('paymentauthorized');
179 | });
180 |
181 | it("has payment property which returns constructor passed payment object", function() {
182 | var paymentObject = {aKey: "aValue"};
183 | var event = new ApplePayPaymentAuthorizedEvent(paymentObject);
184 | expect(event.payment).to.eq(paymentObject);
185 | });
186 | });
187 |
188 | describe("ApplePayValidateMerchantEvent", function () {
189 | var ApplePayValidateMerchantEvent = window.ApplePayValidateMerchantEvent;
190 | it("has window.ApplePayValidateMerchantEvent set", function () {
191 | expect(ApplePayValidateMerchantEvent).to.not.be.undefined;
192 | });
193 |
194 | it("has 'validatemerchant' event.type", function() {
195 | var event = new ApplePayValidateMerchantEvent({});
196 | expect(event.type).to.eq('validatemerchant');
197 | });
198 |
199 | it("has payment property which returns constructor passed payment object", function() {
200 | var validationURL = "url";
201 | var event = new ApplePayValidateMerchantEvent(validationURL);
202 | expect(event.validationURL).to.eq(validationURL);
203 | });
204 | });
205 | });
206 |
--------------------------------------------------------------------------------