<commit_before>import reducers from '../../app/reducers';
import actions from '../../app/actions/';
import chai from 'chai';
import { createStore } from 'redux';
import { applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import update from 'react/lib/update'
import fs from 'fs';
import path from 'path';

const assert = chai.assert,
      expect = chai.expect;

let store;

module.exports = function() {
  describe('Reducers', () => {

    beforeEach(() => {
      store = createStore(reducers, applyMiddleware(thunk));
    });

    describe('Store', () => {
      it("should return the default state for scripts", () => {
        let state = store.getState().scripts;

        let expected = {
          scripts: {},
          activeScript: {}
        }

        expect(state).to.deep.equal(expected);
      });
    });

    describe('LOAD_SCRIPT_PENDING', () => {
      it("should return the correct state with a status of pending", () => {

        let scriptPath = __dirname + '/scripts/ValidSyntax.js';

        store.dispatch(actions.scripts.loadScriptPending(scriptPath, 'name', 'Pending'));
        let state = store.getState().scripts;

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                status: 'Pending',
                name: 'name'
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        assert(Boolean(state.scripts[scriptPath]), true);
        expect(state).to.deep.equal(expected);
      });
    });
    describe('REFRESH_SCRIPT_PENDING', (done) => {
      it("should return the correct state with a status of pending", (done) => {

        let scriptPath = __dirname + '/scripts/ValidSyntax.js';

        store.dispatch(actions.scripts.refreshScriptPending(scriptPath, 'Test', 'Pending'));

        let state = store.getState().scripts;

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                status: 'Pending',
                name: 'Test'
              }
            },
          },
          activeScript: {
            $set: {
              status: 'Pending',
              name: 'Test'
            }
          }
        });

        assert(Boolean(state.scripts[scriptPath]), true);
        expect(state).to.deep.equal(expected);
        done();

      });
    });
    describe('REFRESH_SCRIPT', (done) => {
      it("should return a state with a script with Syntax error and then refresh it to a status of OK", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/InvalidTemp.js');

        fs.writeFileSync(scriptPath, 'vra fest = \'fest\'');

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Temp'))
        .then(() => {

          fs.writeFileSync(scriptPath, 'var fest = \'fest\'');

          store.dispatch(actions.scripts.refreshScript(scriptPath, 'Temp'))
          .then(() => {

            let state = store.getState().scripts;

            let expected = update({}, {
              scripts: {
                $set: {
                  [scriptPath]: {
                    code: '\'use strict\';\n\nvar fest = \'fest\';',
                    status: 'OK',
                    errors: [],
                    logs: [],
                    validated: true,
                    active: false,
                    name: 'Temp',
                    content: 'var fest = \'fest\''
                  }
                },
              },
              activeScript: {
                $set: {
                  code: '\'use strict\';\n\nvar fest = \'fest\';',
                  status: 'OK',
                  errors: [],
                  logs: [],
                  validated: true,
                  active: false,
                  name: 'Temp',
                  content: 'var fest = \'fest\''
                }
              }
            });

            assert(Boolean(state.scripts[scriptPath]), true);
            expect(state.scripts).to.deep.equal(expected.scripts);
            done();
          });

        })
      });
    });

    describe('LOAD_SCRIPT_SUCCESS', () => {
      it("should return the correct state with an script of OK status", (done) => {
        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: [],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state).to.deep.equal(expected);
          done();
        })
      });
     it("should return the correct state with not OK status", (done) => {
        let scriptPath = path.join(__dirname , '../scripts/InvalidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '//Below should be invalid\n\nvra foo = \'foo\';',
                status: 'Syntax Error',
                errors: [],
                logs: [],
                validated: true,
                active: false,
                name: 'Test',
                content: '//Below should be invalid\n\nvra foo = \'foo\';',
                error: new Error()
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(state.scripts[scriptPath].error instanceof Error, true);

          //Comparing Error objects is hard, which is why I remove them.
          state.scripts[scriptPath].error = '';
          expected.scripts[scriptPath].error = '';
          expect(state).to.be.deep.equal(expected);

          done();

        })
      });
    });
    describe('LOAD_SCRIPT_UNSUCCESS', () => {
      it("should return the correct state with the status ENOENT and error being an instance of Error", (done) => {

        let scriptPath = __dirname + '/does/not/exist.js';

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(state.scripts[scriptPath].error instanceof Error, true);
          assert(Boolean(state.scripts[scriptPath].status.match(/(ENOENT)/)), true);
          done();
        })
      });
    });
    describe('ADD_SCRIPT_LOG', (done) => {
      it("should return the correct state with an added message", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: ['Message'],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {
              code: '"use strict";\n\nconsole.log("Hey guys");',
              status: 'OK',
              errors: [],
              logs: ['Message'],
              validated: true,
              active: false,
              name: 'Test',
              content: 'console.log("Hey guys");'
            }
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          //toggleScript has to get dispatched for the user to dispatch addLog
          store.dispatch(actions.scripts.toggleScript(scriptPath));
          store.dispatch(actions.scripts.addLog(scriptPath, 'Message'));
          let state = store.getState().scripts;
          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state.scripts).to.deep.equal(expected.scripts);
          done();
        });
      });
      it("should return the correct state with an added error object to log", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: [new Error()],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {
              code: '"use strict";\n\nconsole.log("Hey guys");',
              status: 'OK',
              errors: [],
              logs: [new  Error()],
              validated: true,
              active: false,
              name: 'Test',
              content: 'console.log("Hey guys");'
            }
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {

          //toggleScript has to get dispatched for the user to dispatch addLog
          store.dispatch(actions.scripts.toggleScript(scriptPath));
          store.dispatch(actions.scripts.addLog(scriptPath, new Error()));
          let state = store.getState().scripts;
          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state.scripts).to.deep.equal(expected.scripts);
          done();
        });
      });
    });
  });
}<commit_msg>Add test for remove script reducer<commit_after>import reducers from '../../app/reducers';
import actions from '../../app/actions/';
import chai from 'chai';
import { createStore } from 'redux';
import { applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import update from 'react/lib/update'
import fs from 'fs';
import path from 'path';

const assert = chai.assert,
      expect = chai.expect;

let store;

module.exports = function() {
  describe('Reducers', () => {

    beforeEach(() => {
      store = createStore(reducers, applyMiddleware(thunk));
    });

    describe('Store', () => {
      it("should return the default state for scripts", () => {
        let state = store.getState().scripts;

        let expected = {
          scripts: {},
          activeScript: {}
        }

        expect(state).to.deep.equal(expected);
      });
    });

    describe('LOAD_SCRIPT_PENDING', () => {
      it("should return the correct state with a status of pending", () => {

        let scriptPath = __dirname + '/scripts/ValidSyntax.js';

        store.dispatch(actions.scripts.loadScriptPending(scriptPath, 'name', 'Pending'));
        let state = store.getState().scripts;

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                status: 'Pending',
                name: 'name'
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        assert(Boolean(state.scripts[scriptPath]), true);
        expect(state).to.deep.equal(expected);
      });
    });
    describe('REFRESH_SCRIPT_PENDING', (done) => {
      it("should return the correct state with a status of pending", (done) => {

        let scriptPath = __dirname + '/scripts/ValidSyntax.js';

        store.dispatch(actions.scripts.refreshScriptPending(scriptPath, 'Test', 'Pending'));

        let state = store.getState().scripts;

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                status: 'Pending',
                name: 'Test'
              }
            },
          },
          activeScript: {
            $set: {
              status: 'Pending',
              name: 'Test'
            }
          }
        });

        assert(Boolean(state.scripts[scriptPath]), true);
        expect(state).to.deep.equal(expected);
        done();

      });
    });
    describe('REFRESH_SCRIPT', (done) => {
      it("should return a state with a script with Syntax error and then refresh it to a status of OK", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/InvalidTemp.js');

        fs.writeFileSync(scriptPath, 'vra fest = \'fest\'');

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Temp'))
        .then(() => {

          fs.writeFileSync(scriptPath, 'var fest = \'fest\'');

          store.dispatch(actions.scripts.refreshScript(scriptPath, 'Temp'))
          .then(() => {

            let state = store.getState().scripts;

            let expected = update({}, {
              scripts: {
                $set: {
                  [scriptPath]: {
                    code: '\'use strict\';\n\nvar fest = \'fest\';',
                    status: 'OK',
                    errors: [],
                    logs: [],
                    validated: true,
                    active: false,
                    name: 'Temp',
                    content: 'var fest = \'fest\''
                  }
                },
              },
              activeScript: {
                $set: {
                  code: '\'use strict\';\n\nvar fest = \'fest\';',
                  status: 'OK',
                  errors: [],
                  logs: [],
                  validated: true,
                  active: false,
                  name: 'Temp',
                  content: 'var fest = \'fest\''
                }
              }
            });

            assert(Boolean(state.scripts[scriptPath]), true);
            expect(state.scripts).to.deep.equal(expected.scripts);
            done();
          });

        })
      });
    });

    describe('LOAD_SCRIPT_SUCCESS', () => {
      it("should return the correct state with an script of OK status", (done) => {
        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: [],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state).to.deep.equal(expected);
          done();
        })
      });
     it("should return the correct state with not OK status", (done) => {
        let scriptPath = path.join(__dirname , '../scripts/InvalidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '//Below should be invalid\n\nvra foo = \'foo\';',
                status: 'Syntax Error',
                errors: [],
                logs: [],
                validated: true,
                active: false,
                name: 'Test',
                content: '//Below should be invalid\n\nvra foo = \'foo\';',
                error: new Error()
              }
            },
          },
          activeScript: {
            $set: {}
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(state.scripts[scriptPath].error instanceof Error, true);

          //Comparing Error objects is hard, which is why I remove them.
          state.scripts[scriptPath].error = '';
          expected.scripts[scriptPath].error = '';
          expect(state).to.be.deep.equal(expected);

          done();

        })
      });
    });
    describe('LOAD_SCRIPT_UNSUCCESS', () => {
      it("should return the correct state with the status ENOENT and error being an instance of Error", (done) => {

        let scriptPath = __dirname + '/does/not/exist.js';

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          let state = store.getState().scripts;

          assert(state.scripts[scriptPath].error instanceof Error, true);
          assert(Boolean(state.scripts[scriptPath].status.match(/(ENOENT)/)), true);
          done();
        })
      });
    });
    describe('ADD_SCRIPT_LOG', (done) => {
      it("should return the correct state with an added message", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: ['Message'],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {
              code: '"use strict";\n\nconsole.log("Hey guys");',
              status: 'OK',
              errors: [],
              logs: ['Message'],
              validated: true,
              active: false,
              name: 'Test',
              content: 'console.log("Hey guys");'
            }
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {
          //toggleScript has to get dispatched for the user to dispatch addLog
          store.dispatch(actions.scripts.toggleScript(scriptPath));
          store.dispatch(actions.scripts.addLog(scriptPath, 'Message'));
          let state = store.getState().scripts;
          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state.scripts).to.deep.equal(expected.scripts);
          done();
        });
      });
      it("should return the correct state with an added error object to log", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        let expected = update({}, {
          scripts: {
            $set: {
              [scriptPath]: {
                code: '"use strict";\n\nconsole.log("Hey guys");',
                status: 'OK',
                errors: [],
                logs: [new Error()],
                validated: true,
                active: false,
                name: 'Test',
                content: 'console.log("Hey guys");'
              }
            },
          },
          activeScript: {
            $set: {
              code: '"use strict";\n\nconsole.log("Hey guys");',
              status: 'OK',
              errors: [],
              logs: [new  Error()],
              validated: true,
              active: false,
              name: 'Test',
              content: 'console.log("Hey guys");'
            }
          }
        });

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Test'))
        .then(e => {

          //toggleScript has to get dispatched for the user to dispatch addLog
          store.dispatch(actions.scripts.toggleScript(scriptPath));
          store.dispatch(actions.scripts.addLog(scriptPath, new Error()));
          let state = store.getState().scripts;
          assert(Boolean(state.scripts[scriptPath]), true);
          expect(state.scripts).to.deep.equal(expected.scripts);
          done();
        });
      });
    });
    describe('REMOVE_SCRIPT', (done) => {
      it("should remove the specified script", (done) => {

        let scriptPath = path.join(__dirname , '../scripts/ValidSyntax.js');

        store.dispatch(actions.scripts.loadScript(scriptPath, 'Temp'))
        .then(() => {

          let state = store.getState().scripts;

          expect(state.scripts[scriptPath]).is.ok;

          store.dispatch(actions.scripts.removeScript(scriptPath));

          state = store.getState().scripts;

          expect(state.scripts[scriptPath]).is.not.ok

          done();
        })
      });
    });
  });
}<|endoftext|>


<commit_before>/*
    Multi line alert message.
    args is an array.
 */
function multiLineAlert(args){

    if(args.length){
        alert(args.join('\n'));
    }

}<commit_msg>Get current time Javascript<commit_after>/*
    Multi line alert message.
    args is an array.
 */
function multiLineAlert(args){

    if(args.length){
        alert(args.join('\n'));
    }

}

/*
 * Get current time Javascript
 */
function getCurrentTime() {
    var d = new Date();
    var x = document.getElementById("demo");
    var h = addZero(d.getHours());
    var m = addZero(d.getMinutes());
    var s = addZero(d.getSeconds());
    return h + ":" + m + ":" + s;
}<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;
var supertest = require('supertest');
var superagent = require('superagent');
var agent = superagent.agent();

var PORT = process.env.PORT || '3000';
var api = supertest('http://localhost:' + PORT);
var gateway = require('../lib/gateway');

describe('Checkout index page', function () {
  it('redirects to the checkouts new page', function (done) {
    api.get('/').expect(302, function (err, response) {
      expect(response.header.location).to.equal('/checkouts/new');
      done();
    });
  });

  it('responds with 200', function (done) {
    api.get('/checkouts/new').expect(200, done);
  });

  it('generates a client token', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/var token = \"[\w=]+\";/);
      done();
    });
  });

  it('includes the checkout form', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<form id="payment-form"/);
      done();
    });
  });

  it('includes the dropin div', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<div id="bt-dropin"/);
      done();
    });
  });

  it('includes the amount field', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<label for="amount/);
      expect(res.text).to.match(/<input id="amount" name="amount" type="tel"/);
      done();
    });
  });
});

describe('Checkouts show page', function () {
  it('respond with 200', function (done) {
    gateway.transaction.sale({
      amount: '10.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).expect(200, done);
    });
  });

  it('displays the transaction\'s fields', function (done) {
    gateway.transaction.sale({
      amount: '10.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain(transaction.id);
        expect(res.text).to.contain(transaction.type);
        expect(res.text).to.contain(transaction.amount);
        expect(res.text).to.contain(transaction.status);
        expect(res.text).to.contain(transaction.stati);
        expect(res.text).to.contain(transaction.creditCard.bin);
        expect(res.text).to.contain(transaction.creditCard.last4);
        expect(res.text).to.contain(transaction.creditCard.cardType);
        expect(res.text).to.contain(transaction.creditCard.expirationDate);
        expect(res.text).to.contain(transaction.creditCard.customerLocation);
        done();
      });
    });
  });

  it('displays a success page when transaction succeeded', function (done) {
    gateway.transaction.sale({
      amount: '11.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain('Sweet Success!');
        done();
      });
    });
  });

  it('displays a failure page when transaction failed', function (done) {
    gateway.transaction.sale({
      amount: '2000.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain('Transaction Failed');
        expect(res.text).to.contain('Your test transaction has a status of processor_declined');
        done();
      });
    });
  });
});

describe('Checkouts create', function () {
  it('creates a transaction and redirects to checkout show', function (done) {
    api.post('/checkouts')
      .send({amount: '10.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
      .expect(302, done);
  });

  context('when the transaction is not successful', function () {
    context('when braintree returns an error', function () {
      it('redirects to the new checkout page if transaction is not created', function (done) {
        api.post('/checkouts')
        .send({amount: 'not_a_valid_amount', payment_method_nonce: 'not_a_valid_nonce'}) // eslint-disable-line camelcase
        .expect(302)
        .expect('Location', 'checkouts/new')
        .end(done);
      });

      it('displays errors', function (done) {
        api.post('/checkouts')
          .send({amount: 'not_a_valid_amount', payment_method_nonce: 'not_a_valid_nonce'}) // eslint-disable-line camelcase
          .end(function (err, res) {
            agent.saveCookies(res);
            var req = api.get('/checkouts/new');

            agent.attachCookies(req);
            req.end(function (err, res) {
              expect(res.text).to.contain('Error: 81503: Amount is an invalid format.');
              done();
            });
          });
      });
    });

    context('when there are processor errors', function () {
      it('redirects to the checkouts show page', function (done) {
        api.post('/checkouts')
        .send({amount: '2000.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
        .expect(302)
        .expect('Location', /checkouts\/[^new$][\w+]/)
        .end(done);
      });

      it('displays the transaction status', function (done) {
        api.post('/checkouts')
          .send({amount: '2000.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
          .end(function (err, res) {
            agent.saveCookies(res);
            var redirectUrl = '/' + res.req.res.headers.location;
            var req = api.get(redirectUrl);

            agent.attachCookies(req);
            req.end(function (err, res) {
              expect(res.text).to.contain('Your test transaction has a status of processor_declined');
              done();
            });
          });
      });
    });
  });
});
<commit_msg>Update checkout_test.js<commit_after>'use strict';

var expect = require('chai').expect;
var supertest = require('supertest');
var superagent = require('superagent');
var agent = superagent.agent();

var PORT = process.env.PORT || '3000';
var api = supertest('http://localhost:' + PORT);
var gateway = require('../lib/gateway');

describe('Checkout index page', function () {
  it('redirects to the checkouts new page', function (done) {
    api.get('/').expect(302, function (err, response) {
      expect(response.header.location).to.equal('/checkouts/new');
      done();
    });
  });

  it('responds with 200', function (done) {
    api.get('/checkouts/new').expect(200, done);
  });

  it('generates a client token', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/var token = \"[\w=]+\";/);
      done();
    });
  });

  it('includes the checkout form', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<form id="payment-form"/);
      done();
    });
  });

  it('includes the dropin div', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<div id="bt-dropin"/);
      done();
    });
  });

  it('includes the amount field', function (done) {
    api.get('/checkouts/new').end(function (err, res) {
      expect(res.text).to.match(/<label for="amount/);
      expect(res.text).to.match(/<input id="amount" name="amount" type="tel"/);
      done();
    });
  });
});

describe('Checkouts show page', function () {
  it('respond with 200', function (done) {
    gateway.transaction.sale({
      amount: '10.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).expect(200, done);
    });
  });

  it('displays the transaction\'s fields', function (done) {
    gateway.transaction.sale({
      amount: '10.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain(transaction.id);
        expect(res.text).to.contain(transaction.type);
        expect(res.text).to.contain(transaction.amount);
        expect(res.text).to.contain(transaction.status);
        expect(res.text).to.contain(transaction.creditCard.bin);
        expect(res.text).to.contain(transaction.creditCard.last4);
        expect(res.text).to.contain(transaction.creditCard.cardType);
        expect(res.text).to.contain(transaction.creditCard.expirationDate);
        expect(res.text).to.contain(transaction.creditCard.customerLocation);
        done();
      });
    });
  });

  it('displays a success page when transaction succeeded', function (done) {
    gateway.transaction.sale({
      amount: '11.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain('Sweet Success!');
        done();
      });
    });
  });

  it('displays a failure page when transaction failed', function (done) {
    gateway.transaction.sale({
      amount: '2000.00',
      paymentMethodNonce: 'fake-valid-nonce'
    }, function (err, result) {
      var transaction = result.transaction;

      api.get('/checkouts/' + transaction.id).end(function (err, res) {
        expect(res.text).to.contain('Transaction Failed');
        expect(res.text).to.contain('Your test transaction has a status of processor_declined');
        done();
      });
    });
  });
});

describe('Checkouts create', function () {
  it('creates a transaction and redirects to checkout show', function (done) {
    api.post('/checkouts')
      .send({amount: '10.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
      .expect(302, done);
  });

  context('when the transaction is not successful', function () {
    context('when braintree returns an error', function () {
      it('redirects to the new checkout page if transaction is not created', function (done) {
        api.post('/checkouts')
        .send({amount: 'not_a_valid_amount', payment_method_nonce: 'not_a_valid_nonce'}) // eslint-disable-line camelcase
        .expect(302)
        .expect('Location', 'checkouts/new')
        .end(done);
      });

      it('displays errors', function (done) {
        api.post('/checkouts')
          .send({amount: 'not_a_valid_amount', payment_method_nonce: 'not_a_valid_nonce'}) // eslint-disable-line camelcase
          .end(function (err, res) {
            agent.saveCookies(res);
            var req = api.get('/checkouts/new');

            agent.attachCookies(req);
            req.end(function (err, res) {
              expect(res.text).to.contain('Error: 81503: Amount is an invalid format.');
              done();
            });
          });
      });
    });

    context('when there are processor errors', function () {
      it('redirects to the checkouts show page', function (done) {
        api.post('/checkouts')
        .send({amount: '2000.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
        .expect(302)
        .expect('Location', /checkouts\/[^new$][\w+]/)
        .end(done);
      });

      it('displays the transaction status', function (done) {
        api.post('/checkouts')
          .send({amount: '2000.00', payment_method_nonce: 'fake-valid-nonce'}) // eslint-disable-line camelcase
          .end(function (err, res) {
            agent.saveCookies(res);
            var redirectUrl = '/' + res.req.res.headers.location;
            var req = api.get(redirectUrl);

            agent.attachCookies(req);
            req.end(function (err, res) {
              expect(res.text).to.contain('Your test transaction has a status of processor_declined');
              done();
            });
          });
      });
    });
  });
});
<|endoftext|>


<commit_before>
document.getElementById("id_logic_level_version").innerHTML = "Business level version: 2017.11.01.7";
window.addEventListener('deviceorientation', ondeviceorientation);
window.addEventListener('devicemotion', ondevicemotion);

//----------------------------------------
function deseneaza_cerc_svg(gamma, beta)
{
	var svg = document.getElementById("id_svg");
	var w = svg.getAttribute("width");
	var h = svg.getAttribute("height");

	var cerc = document.getElementById("id_circle");

	var centru = {x : w / 2, y : h / 2};
	var raza = cerc.getAttribute("r");
	var max_deplasare_x = w / 2 - raza;
	var max_deplasare_y = h / 2 - raza;

	cerc.setAttribute("cx", centru.x + gamma / 90 * max_deplasare_x);
	cerc.setAttribute("cy", centru.y + beta / 90 * max_deplasare_y);
}
//----------------------------------------
function deseneaza_cerc_canvas(gamma, beta)
{
	var canvas = document.getElementById("id_canvas");
	var context = canvas.getContext("2d");

	context.beginPath();
	var w = canvas.getAttribute("width");
	var h = canvas.getAttribute("height");

	context.clearRect(0, 0, w, h);

	var centru = {x : w / 2, y : h / 2};
	var raza = 10;
	var max_deplasare_x = w / 2 - raza;
	var max_deplasare_y = h / 2 - raza;
 // gamma == 0 -> centru.x
 // gamma == -90 -> 0 + raza
 // gamma == 90 -> w - raza
	context.arc(centru.x + gamma / 90 * max_deplasare_x, centru.y + beta / 90 * max_deplasare_y, raza, 0, 2 * Math.PI);

	context.stroke();
}
//----------------------------------------
function deseneaza_patrat_canvas(alpha, gamma, beta)
{
	var canvas = document.getElementById("id_canvas");
	var context = canvas.getContext("2d");

	context.resetTransform();
	context.clearRect(0, 0, w, h);

	var w = canvas.getAttribute("width");
	var h = canvas.getAttribute("height");

	var centru = {x : w / 2, y : h / 2};
	var latura = 10;
	var max_deplasare_x = w / 2 - latura / 2;
	var max_deplasare_y = h / 2 - latura / 2;

	var centru_patrat = {x: centru.x + gamma / 90 * max_deplasare_x, y : centru.y + beta / 90 * max_deplasare_y};

	context.translate(centru_patrat.x, centru_patrat.y);
	context.rotate(alpha / 180 * Math.PI);
 // gamma == 0 -> centru.x
 // gamma == -90 -> 0 + raza
 // gamma == 90 -> w - raza

	context.beginPath();
	//context.arc(centru.x + gamma / 90 * max_deplasare_x, centru.y + beta / 90 * max_deplasare_y, raza, 0, 2 * Math.PI);
	context.strokeRect(- latura / 2, -latura / 2, latura, latura);
	context.stroke();
}
//----------------------------------------
function ondeviceorientation(event)
{
	var alpha = event.alpha;
	var beta = event.beta;
	var gamma = event.gamma;

	document.getElementById("id_alpha").innerHTML = "alpha = " + Math.round(alpha * 10) / 10;
	document.getElementById("id_beta").innerHTML = "beta = " + Math.round(beta * 10) / 10;
	document.getElementById("id_gamma").innerHTML = "gamma = " + Math.round(gamma * 10) / 10;

	//deseneaza_cerc_canvas(gamma, beta);
	// deseneaza_cerc_svg(gamma, beta);
	//deseneaza_patrat_canvas(alpha, gamma, beta);
}
//----------------------------------------
function ondevicemotion(event)
{
	document.getElementById("id_acc").innerHTML = "Acc = " + Math.round(event.acceleration.x * 10) / 10 + " " + Math.round(event.acceleration.y * 10) / 10 + " " + Math.round(event.acceleration.z * 10) / 10;

	var ag = event.accelerationIncludingGravity;
	var gamma = -Math.atan(ag.x / ag.z) * 180 / Math.PI;
	var beta = Math.atan(ag.y / ag.z) * 180 / Math.PI;

	document.getElementById("id_acc_g").innerHTML = "AccG = " + Math.round(ag.x * 10) / 10 + " " + Math.round(ag.y * 10) / 10 + " " + Math.round(ag.z * 10) / 10 + " gamma = " + Math.round(gamma * 10) / 10 + " beta = " + Math.round(beta * 10) / 10;
	deseneaza_cerc_canvas(gamma, beta);
}
//----------------------------------------<commit_msg>dreptunghi canvas<commit_after>
document.getElementById("id_logic_level_version").innerHTML = "Business level version: 2017.11.29.0";
//window.addEventListener('deviceorientation', ondeviceorientation);
window.addEventListener('devicemotion', ondevicemotion);

//----------------------------------------
function deseneaza_cerc_svg(gamma, beta)
{
	var svg = document.getElementById("id_svg");
	var w = svg.getAttribute("width");
	var h = svg.getAttribute("height");

	var cerc = document.getElementById("id_circle");

	var centru = {x : w / 2, y : h / 2};
	var raza = cerc.getAttribute("r");
	var max_deplasare_x = w / 2 - raza;
	var max_deplasare_y = h / 2 - raza;

	cerc.setAttribute("cx", centru.x + gamma / 90 * max_deplasare_x);
	cerc.setAttribute("cy", centru.y + beta / 90 * max_deplasare_y);
}
//----------------------------------------
function deseneaza_cerc_canvas(gamma, beta)
{
	var canvas = document.getElementById("id_canvas");
	var context = canvas.getContext("2d");

	context.clearRect(0, 0, w, h);

	var w = canvas.getAttribute("width");
	var h = canvas.getAttribute("height");

	context.rect(0, 0, w, h);
	context.stroke();

	context.beginPath();

	var centru = {x : w / 2, y : h / 2};
	var raza = 10;
	var max_deplasare_x = w / 2 - raza;
	var max_deplasare_y = h / 2 - raza;
 // gamma == 0 -> centru.x
 // gamma == -90 -> 0 + raza
 // gamma == 90 -> w - raza
	context.arc(centru.x + gamma / 90 * max_deplasare_x, centru.y + beta / 90 * max_deplasare_y, raza, 0, 2 * Math.PI);

	context.stroke();
}
//----------------------------------------
function deseneaza_patrat_canvas(alpha, gamma, beta)
{
	var canvas = document.getElementById("id_canvas");
	var context = canvas.getContext("2d");

	context.resetTransform();
	context.clearRect(0, 0, w, h);

	var w = canvas.getAttribute("width");
	var h = canvas.getAttribute("height");

	var centru = {x : w / 2, y : h / 2};
	var latura = 10;
	var max_deplasare_x = w / 2 - latura / 2;
	var max_deplasare_y = h / 2 - latura / 2;

	var centru_patrat = {x: centru.x + gamma / 90 * max_deplasare_x, y : centru.y + beta / 90 * max_deplasare_y};

	context.translate(centru_patrat.x, centru_patrat.y);
	context.rotate(alpha / 180 * Math.PI);
 // gamma == 0 -> centru.x
 // gamma == -90 -> 0 + raza
 // gamma == 90 -> w - raza

	context.beginPath();
	//context.arc(centru.x + gamma / 90 * max_deplasare_x, centru.y + beta / 90 * max_deplasare_y, raza, 0, 2 * Math.PI);
	context.strokeRect(- latura / 2, -latura / 2, latura, latura);
	context.stroke();
}
//----------------------------------------
function ondeviceorientation(event)
{
	var alpha = event.alpha;
	var beta = event.beta;
	var gamma = event.gamma;

	document.getElementById("id_alpha").innerHTML = "alpha = " + Math.round(alpha * 10) / 10;
	document.getElementById("id_beta").innerHTML = "beta = " + Math.round(beta * 10) / 10;
	document.getElementById("id_gamma").innerHTML = "gamma = " + Math.round(gamma * 10) / 10;

	//deseneaza_cerc_canvas(gamma, beta);
	// deseneaza_cerc_svg(gamma, beta);
	//deseneaza_patrat_canvas(alpha, gamma, beta);
}
//----------------------------------------
function ondevicemotion(event)
{
	document.getElementById("id_acc").innerHTML = "Acc = " + Math.round(event.acceleration.x * 10) / 10 + " " + Math.round(event.acceleration.y * 10) / 10 + " " + Math.round(event.acceleration.z * 10) / 10;

	var ag = event.accelerationIncludingGravity;
	var gamma = -Math.atan(ag.x / ag.z) * 180 / Math.PI;
	var beta = Math.atan(ag.y / ag.z) * 180 / Math.PI;

	//document.getElementById("id_acc_g").innerHTML = "AccG = " + Math.round(ag.x * 10) / 10 + " " + Math.round(ag.y * 10) / 10 + " " + Math.round(ag.z * 10) / 10 + " gamma = " + Math.round(gamma * 10) / 10 + " beta = " + Math.round(beta * 10) / 10;
	deseneaza_cerc_canvas(gamma, beta);
}
//----------------------------------------<|endoftext|>


<commit_before>const DNSMessageHeader = require('./DNSMessageHeader.js');
const DNSMessageQuestion = require('./DNSMessageQuestion.js');
const DNSMessageAnswer = require('./DNSMessageResource.js');

const DNSMessage = function(server, rinfo) {
	this._server = server;
	this._rinfo = rinfo;

	this.header = null;
	this.questions = [];
	this.answers = [];
	this.authorities = [];
	this.additionals = [];
};

DNSMessage.prototype.encode = function() {
	var buffers = [];

	this.header.qdcount = 0; //this.questions.length;
	this.header.ancount = this.answers.length;
	this.header.nscount = this.authorities.length;
	this.header.arcount = this.additionals.length;

	buffers.push(this.header.encode());

	// TODO: Encode questions (even though these shouldn't be present in responses)

	for (var i=0; i<this.answers.length; i++) {
		buffers.push(this.answers[i].encode());
	}

	for (var i=0; i<this.authorities.length; i++) {
		buffers.push(this.authorities[i].encode());
	}

	for (var i=0; i<this.additionals.length; i++) {
		buffers.push(this.additionals[i].encode());
	}

	return Buffer.concat(buffers);
};

DNSMessage.prototype.send = function() {
	if (!this._server || !this._rinfo) {
		throw new Error('Can not send this message as a response');
	}

	var message = this.encode();
	this._server.socket.send(message, 0, message.length, this._rinfo.port, this._rinfo.address);
};

DNSMessage.parse = function(buffer, server) {
	buffer.pos = 0; // Store already read bytes in buffer so parse functions know where to start.

	var message = new DNSMessage(server);
	message.header = DNSMessageHeader.parse(buffer);
	message.questions = DNSMessageQuestion.parse(buffer, message.header.qdcount);

	// TODO: Parse answers, authorities, and additionals.
	// These shouldn't be included in question queries, but it would be nice if it was at least possible to parse them.

	return message;
};

DNSMessage.prototype.toString = function() {
	return '<DNSMessage>';
};

module.exports = DNSMessage;
<commit_msg>add question to message<commit_after>const DNSMessageHeader = require('./DNSMessageHeader.js');
const DNSMessageQuestion = require('./DNSMessageQuestion.js');
const DNSMessageAnswer = require('./DNSMessageResource.js');

const DNSMessage = function(server, rinfo) {
	this._server = server;
	this._rinfo = rinfo;

	this.header = null;
	this.questions = [];
	this.answers = [];
	this.authorities = [];
	this.additionals = [];
};

DNSMessage.prototype.encode = function() {
	var buffers = [];

	this.header.qdcount = this.questions.length;
	this.header.ancount = this.answers.length;
	this.header.nscount = this.authorities.length;
	this.header.arcount = this.additionals.length;

	buffers.push(this.header.encode());

	for (var i=0; i<this.questions.length; i++) {
                buffers.push(this.questions[i].encode());
        }

	for (var i=0; i<this.answers.length; i++) {
		buffers.push(this.answers[i].encode());
	}

	for (var i=0; i<this.authorities.length; i++) {
		buffers.push(this.authorities[i].encode());
	}

	for (var i=0; i<this.additionals.length; i++) {
		buffers.push(this.additionals[i].encode());
	}

	return Buffer.concat(buffers);
};

DNSMessage.prototype.send = function() {
	if (!this._server || !this._rinfo) {
		throw new Error('Can not send this message as a response');
	}

	var message = this.encode();
	this._server.socket.send(message, 0, message.length, this._rinfo.port, this._rinfo.address);
};

DNSMessage.parse = function(buffer, server) {
	buffer.pos = 0; // Store already read bytes in buffer so parse functions know where to start.

	var message = new DNSMessage(server);
	message.header = DNSMessageHeader.parse(buffer);
	message.questions = DNSMessageQuestion.parse(buffer, message.header.qdcount);

	// TODO: Parse answers, authorities, and additionals.
	// These shouldn't be included in question queries, but it would be nice if it was at least possible to parse them.

	return message;
};

DNSMessage.prototype.toString = function() {
	return '<DNSMessage>';
};

module.exports = DNSMessage;
<|endoftext|>


<commit_before>(function(){
    var querystring = require('querystring'),
        https = require('https'),
        sha1 = require('./sha1'),
        URL = require('url'),
        util = require('util'),
        _ = require('underscore')._;

    var OAuth;
    OAuth = function(options){
	this.token = !options.token? {}: {
	    'key' : options.token.oauth_token,
	    'secret' : options.token.oauth_token_secret
	};

	this.consumer = {
	    'key': options.appKey,
	    'secret': options.appSecret
	};

	this.headers = options.headers || {};
    };

    _(OAuth.prototype).extend({
	'addHeaders' : function(headers) {
	    _(this.headers).extend(headers);

	    return this;
	},
	'request' : function(method, url /* [data], [callback]*/){
	    var args = Array.prototype.slice.call(arguments, 2);

	    var callback = args.pop() || function() {},
	        data = args.shift();

	    new(Request)(
		method, url, data, this.headers, this.consumer, this.token
	    ).send(callback);

	    return this;
	},
	'requestToken' : function(url, callback){
	    var that = this;

	    this.addHeaders({ 'Content-Length': 0 })
		.request('post', url, function(res){
		    res.setEncoding('utf8');
		    res.on('data', function(data){
			if ( res.statusCode !== 200 ){
			    callback(data, null);
			    return;
			}

			token = querystring.parse(data);
			that.token = {
			    'key' : token.oauth_token,
			    'secret' : token.oauth_token_secret
			};

			callback(null, token);
			return;
		    });
		});
	},
	'accessToken' : function(url /* [verifier], [callback]*/){
	    var args = Array.prototype.slice.call(arguments, 1),
                that = this;

	    console.log(args);
	    var callback = args.pop() || function(){},
	        verifier = args.shift();

	    console.log(verifier);
	    url +='?oauth_verifier='+verifier;

	    this.addHeaders({ 'Content-Length' : 0 })
		.request('post', url, function(res){
		    res.setEncoding('utf8');

		    res.on('data', function(data){
			if ( res.statusCode !== 200 ){
			    callback(data, null);
			    return;
			}

			token = querystring.parse(data);
			that.token = {
			    'key': token.oauth_token,
			    'secret': token.oauth_token_secret
			};
			callback(null, token);
			return;
		    });

		});
	}
    });

    var Request;
    Request = function(method, url, data, headers, consumer, token){
	this.method = method.toLowerCase();
	this.url    = url;
	this.data   = data || {};
	this.consumer = consumer;
	this.token = token || {};

	this.headers = {

	};
	if ( headers ){
	    _.extend(
		this.headers, headers
	    );
	}
    };

    Request.prototype.getNonce = function(length, base64){
	var nonce = [], timestamp, char;

	base64 = ( base64 !== undefined )?base64 : true;
	length = ( length )?length : 32;

	timestamp = (+new(Date)).toString();
	nonce.push(timestamp);

	if ( timestamp.length < length ){
	    for (var i = 0; i <= (length-timestamp.length); i++){
		char = String.fromCharCode(Math.floor(Math.random() * 26)+97);

		if ( Math.floor(Math.random()*2) )
		    char = char.toUpperCase();

		nonce.push(char);
	    }
	}

	nonce = nonce.join('');
	return ( base64 )?Buffer(nonce).toString('base64') : nonce;
    };

    Request.prototype.createSignature = function(oauth_query){
	var query, sorted_query, base_string, that;

	this.method = this.method.toUpperCase();
	/*
	  Parameter string
	 */
	var keys = [];
	for ( var key in this.url.query ){
	    if ( this.url.query.hasOwnProperty(key) ){
		keys.push(key);
	    }
	}
	keys.sort();

	sorted_query = [];
	that = this;

	keys.forEach(function(key){
	    sorted_query.push([
		key, that.url.query[key]
	    ]);
	});

	query = [];
	sorted_query.forEach(function(field){
	    query.push([
		querystring.escape(field[0]),
		querystring.escape(field[1])
	    ].join('='));
	});
	query = query.join('&');
	query = query.replace(/\!/g, '%21');
	query = querystring.escape(query);

	/*
	  Creating the signature base string
	*/
	var base_url = querystring.escape(this.url.protocol+'//'+this.url.host+this.url.pathname);
	base_string = [
	    this.method, base_url, query
	].join('&');

	/*
	  Getting a signing key.
	 */
	var signing_key = [
	    this.consumer.secret, ( this.token.secret )?this.token.secret: ''
	].join('&');

	console.log('Base string = ');
	console.log(base_string);

	console.log('Signing key = ');
	console.log(signing_key);

	return sha1.HMACSHA1(signing_key, base_string);
    };

    Request.prototype.authHeader = function(oauth_query){
	var auth_header = 'OAuth ', params = [];

	for ( var key in oauth_query ){
	    params.push(
		util.format('%s="%s"', key, querystring.escape(oauth_query[key]))
	    );
	}

	auth_header += params.join(', ');
	return auth_header;
    };

    Request.prototype.send = function(callback){
	var options, request, oauth_query, oauth_header, oauth_token;

	this.url = URL.parse(this.url);
	/*
	  querystring.parse(undefined) -> {};
	 */
	this.url.query = querystring.parse(this.url.query);
	oauth_query = {
	    'oauth_consumer_key' : this.consumer.key,
	    'oauth_signature_method' : 'HMAC-SHA1',
	    'oauth_nonce' : this.getNonce(),
	    'oauth_timestamp' : Math.round(+new(Date)/1000).toString(),
	    'oauth_version' : '1.0'
	};

	/*
	  This handles the 'oauth_callback' for the 'request token' step
	 */
	oauth_header = _.clone(
	    !_.has(this.url.query, 'oauth_callback')?oauth_query : _.extend(
		oauth_query, {
		    'oauth_callback' : querystring.escape(this.url.query.oauth_callback)
		}
	    )
	);

	/*
	  And this handles the 'oauth_verifier' for the 'access token' step
	*/
	oauth_header = _.clone(
	    !_.has(this.url.query, 'oauth_verifier')?oauth_query : _.extend(
		oauth_query, {
		    'oauth_verifier' : this.url.query.oauth_verifier
		}
	    )
	);

	/*

	*/

	if ( this.token.key ){
	    oauth_token = {
		'oauth_token' : this.token.key
	    };

	    _.extend(oauth_header, oauth_token);
	    _.extend(this.url.query, oauth_token);
	}

	/*
	  Adding oauth parameters to the query
	 */
	oauth_query = _.clone(
	    _.extend(
		this.url.query, oauth_query
	    )
	);

	/*
	  Extending the query with the data, if exists
	 */
	if ( this.method === 'get' ){
	    _.extend(
		this.url.query, this.data
	    );
	    this.data = {};
	}

	/*
	  Adding the oauth_signature to the query
	*/
	var signature = {
	    'oauth_signature' : this.createSignature()
	};

	_.extend(this.url.query, signature);
	_.extend(oauth_header, signature);

	var path = [
	    this.url.path,
	    querystring.stringify(this.url.query)
	].join('?');

	/*
	  Adding oauth headers
	*/
	_.extend(this.headers, {
	    'Authorization' : this.authHeader(oauth_header)
	});

	console.log(this.headers);

	options = {
	    'method' : this.method,
	    'host' : this.url.hostname,
	    'path' : this.url.path,
	    'headers' : this.headers
	};

	request = https.request(options, callback);
	request.end();
    };

    exports.Request = Request;
    exports.OAuth = OAuth;
})();<commit_msg>New verifier handler in the accessToken method<commit_after>(function(){
    var querystring = require('querystring'),
        https = require('https'),
        http = require('http'),
        sha1 = require('./sha1'),
        URL = require('url'),
        util = require('util'),
        _ = require('underscore')._;

    var OAuth;
    OAuth = function(options){
	this.token = !options.token? {}: {
	    'key' : options.token.oauth_token,
	    'secret' : options.token.oauth_token_secret
	};

	this.consumer = {
	    'key': options.appKey,
	    'secret': options.appSecret
	};

	this.headers = options.headers || {};
    };

    _(OAuth.prototype).extend({
	'addHeaders' : function(headers) {
	    _(this.headers).extend(headers);

	    return this;
	},
	'request' : function(method, url /* [data], [callback]*/){
	    var args = Array.prototype.slice.call(arguments, 2);

	    var callback = args.pop() || function() {},
	        data = args.shift();

	    new(Request)(
		method, url, data, this.headers, this.consumer, this.token
	    ).send(callback);

	    return this;
	},
	'requestToken' : function(url, callback){
	    var that = this;

	    this.addHeaders({ 'Content-Length': 0 })
		.request('post', url, function(res){
		    res.setEncoding('utf8');
		    res.on('data', function(data){
			if ( res.statusCode !== 200 ){
			    callback(data, null);
			    return;
			}

			token = querystring.parse(data);
			that.token = {
			    'key' : token.oauth_token,
			    'secret' : token.oauth_token_secret
			};

			callback(null, token);
			return;
		    });
		});
	},
	'accessToken' : function(url /* [verifier], [callback]*/){
	    var args = Array.prototype.slice.call(arguments, 1),
                that = this;

	    console.log(args);
	    var callback = args.pop() || function(){},
	        verifier = args.shift();

	    url = URL.parse(url);
	    var query = url.query || null;

	    url = url.protocol+'//'+url.hostname+url.pathname;

	    if ( query ){
		query = querystring.parse(query);
		_(query).extend({
		    'oauth_verifier' : verifier
		});
	    }else{
		query = {
		    'oauth_verifier' : verifier
		};
	    }

	    url = [
		url, querystring.stringify(query)
	    ].join('?');

	    this.addHeaders({ 'Content-Length' : 0 })
		.request('post', url, function(res){
		    res.setEncoding('utf8');

		    res.on('data', function(data){
			if ( res.statusCode !== 200 ){
			    callback(data, null);
			    return;
			}

			token = querystring.parse(data);
			that.token = {
			    'key': token.oauth_token,
			    'secret': token.oauth_token_secret
			};
			callback(null, token);
			return;
		    });

		});
	}
    });

    var Request;
    Request = function(method, url, data, headers, consumer, token){
	this.method = method.toLowerCase();
	this.url    = url;
	this.data   = data || {};
	this.consumer = consumer;
	this.token = token || {};

	this.headers = {

	};
	if ( headers ){
	    _.extend(
		this.headers, headers
	    );
	}
    };

    Request.prototype.getNonce = function(length, base64){
	var nonce = [], timestamp, char;

	base64 = ( base64 !== undefined )?base64 : true;
	length = ( length )?length : 32;

	timestamp = (+new(Date)).toString();
	nonce.push(timestamp);

	if ( timestamp.length < length ){
	    for (var i = 0; i <= (length-timestamp.length); i++){
		char = String.fromCharCode(Math.floor(Math.random() * 26)+97);

		if ( Math.floor(Math.random()*2) )
		    char = char.toUpperCase();

		nonce.push(char);
	    }
	}

	nonce = nonce.join('');
	return ( base64 )?Buffer(nonce).toString('base64') : nonce;
    };

    Request.prototype.createSignature = function(oauth_query){
	var query, sorted_query, base_string, that;

	this.method = this.method.toUpperCase();
	/*
	  Parameter string
	 */
	var keys = [];
	for ( var key in this.url.query ){
	    if ( this.url.query.hasOwnProperty(key) ){
		keys.push(key);
	    }
	}
	keys.sort();

	sorted_query = [];
	that = this;

	keys.forEach(function(key){
	    sorted_query.push([
		key, that.url.query[key]
	    ]);
	});

	query = [];
	sorted_query.forEach(function(field){
	    query.push([
		querystring.escape(field[0]),
		querystring.escape(field[1])
	    ].join('='));
	});
	query = query.join('&');
	query = query.replace(/\!/g, '%21');
	query = querystring.escape(query);

	/*
	  Creating the signature base string
	*/
	var base_url = querystring.escape(this.url.protocol+'//'+this.url.host+this.url.pathname);
	base_string = [
	    this.method, base_url, query
	].join('&');

	/*
	  Getting a signing key.
	 */
	var signing_key = [
	    this.consumer.secret, ( this.token.secret )?this.token.secret: ''
	].join('&');

	console.log('Base string = ');
	console.log(base_string);

	console.log('Signing key = ');
	console.log(signing_key);

	return sha1.HMACSHA1(signing_key, base_string);
    };

    Request.prototype.authHeader = function(oauth_query){
	var auth_header = 'OAuth ', params = [];

	for ( var key in oauth_query ){
	    params.push(
		util.format('%s="%s"', key, querystring.escape(oauth_query[key]))
	    );
	}

	auth_header += params.join(', ');
	return auth_header;
    };

    Request.prototype.send = function(callback){
	var options, request, oauth_query, oauth_header, oauth_token;

	this.url = URL.parse(this.url);
	/*
	  querystring.parse(undefined) -> {};
	 */
	this.url.query = querystring.parse(this.url.query);
	oauth_query = {
	    'oauth_consumer_key' : this.consumer.key,
	    'oauth_signature_method' : 'HMAC-SHA1',
	    'oauth_nonce' : this.getNonce(),
	    'oauth_timestamp' : Math.round(+new(Date)/1000).toString(),
	    'oauth_version' : '1.0'
	};

	/*
	  This handles the 'oauth_callback' for the 'request token' step
	 */
	oauth_header = _.clone(
	    !_.has(this.url.query, 'oauth_callback')?oauth_query : _.extend(
		oauth_query, {
		    'oauth_callback' : querystring.escape(this.url.query.oauth_callback)
		}
	    )
	);

	/*
	  And this handles the 'oauth_verifier' for the 'access token' step
	*/
	oauth_header = _.clone(
	    !_.has(this.url.query, 'oauth_verifier')?oauth_query : _.extend(
		oauth_query, {
		    'oauth_verifier' : this.url.query.oauth_verifier
		}
	    )
	);

	/*

	*/

	if ( this.token.key ){
	    oauth_token = {
		'oauth_token' : this.token.key
	    };

	    _.extend(oauth_header, oauth_token);
	    _.extend(this.url.query, oauth_token);
	}

	/*
	  Adding oauth parameters to the query
	 */
	oauth_query = _.clone(
	    _.extend(
		this.url.query, oauth_query
	    )
	);

	/*
	  Extending the query with the data, if exists
	 */
	if ( this.method === 'get' ){
	    _.extend(
		this.url.query, this.data
	    );
	    this.data = {};
	}

	/*
	  Adding the oauth_signature to the query
	*/
	var signature = {
	    'oauth_signature' : this.createSignature()
	};

	_.extend(this.url.query, signature);
	_.extend(oauth_header, signature);

	var path = [
	    this.url.path,
	    querystring.stringify(this.url.query)
	].join('?');

	/*
	  Adding oauth headers
	*/
	_.extend(this.headers, {
	    'Authorization' : this.authHeader(oauth_header)
	});

	console.log(this.headers);

	options = {
	    'method' : this.method,
	    'host' : this.url.hostname,
	    'path' : this.url.path,
	    'headers' : this.headers
	};

	request = ((this.url.protocol === 'https:')?https:http).request(options, callback);
	request.end();
    };

    exports.Request = Request;
    exports.OAuth = OAuth;
})();<|endoftext|>


<commit_before>// Update UI (adapted from ProseMirror's src/menu/update.js)

const MIN_FLUSH_DELAY = 200
const UPDATE_TIMEOUT = 200

const BLOCK_LABELS = {
  'paragraph': gettext('Normal Text'),
  'ordered_list': gettext('Numbered List'),
  'bullet_list': gettext('Bulleted List'),
  'blockquote': gettext('Block Quote'),
  'heading_1': gettext('1st Heading'),
  'heading_2': gettext('2nd Heading'),
  'heading_3': gettext('3rd Heading'),
  'code_block': gettext('Code')
}

export class UpdateUI {
  constructor(pm, events) {
    this.pm = pm

    this.mustUpdate = false
    this.updateInfo = null
    this.timeout = null
    this.lastFlush = 0
    this.placeHolderCss = ''

    this.events = events.split(" ")
    this.onEvent = this.onEvent.bind(this)
    this.force = this.force.bind(this)
    this.events.forEach(event => pm.on(event, this.onEvent))
    pm.on("flushed", this.onFlushed = this.onFlushed.bind(this))
    this.updateUI()
  }

  detach() {
    clearTimeout(this.timeout)
    this.events.forEach(event => this.pm.off(event, this.onEvent))
    this.pm.off("flush", this.onFlush)
    this.pm.off("flushed", this.onFlushed)
  }

  onFlushed() {
    let now = Date.now()
    if (this.mustUpdate && (now - this.lastFlush) >= MIN_FLUSH_DELAY) {
      this.lastFlush = now
      clearTimeout(this.timeout)
      this.mustUpdate = false
      this.updateUI()
    }
  }

  onEvent() {
    this.mustUpdate = true
    clearTimeout(this.timeout)
    this.timeout = setTimeout(this.force, UPDATE_TIMEOUT)
  }

  force() {
    if (this.pm.operation) {
      this.onEvent()
    } else {
      this.mustUpdate = false
      this.updateInfo = null
      this.lastFlush = Date.now()
      clearTimeout(this.timeout)
      this.updateUI()
    }
  }

  updateUI() {
    /* Fidus Writer code */

    // We count on the this precise order in all documents.
    let nodes = {
        'title': this.pm.doc.firstChild,
        'subtitle': this.pm.doc.child(1),
        'authors': this.pm.doc.child(2),
        'abstract': this.pm.doc.child(3),
        'keywords': this.pm.doc.child(4),
        'contents': this.pm.doc.child(5)
    }

    let documentTitle = nodes.title.textContent

        if (documentTitle.length === 0) {
            documentTitle = gettext('Untitled Document')
        }
        jQuery('title').html('Fidus Writer - ' + documentTitle)
        jQuery('#header h1').html(documentTitle)

    let marks = this.pm.activeMarks()
    let strong = marks.some(function(mark){return (mark.type.name==='strong')})

    if (strong) {
        jQuery('#button-bold').addClass('ui-state-active')
    } else {
        jQuery('#button-bold').removeClass('ui-state-active')
    }

    let em = marks.some(function(mark){return (mark.type.name==='em')})

    if (em) {
        jQuery('#button-italic').addClass('ui-state-active')
    } else {
        jQuery('#button-italic').removeClass('ui-state-active')
    }

    let link = marks.some(function(mark){return (mark.type.name==='link')})

    if (link) {
        jQuery('#button-link').addClass('ui-state-active')
    } else {
        jQuery('#button-link').removeClass('ui-state-active')
    }

    /* Block level selector */
    if (this.pm.selection.head) {
        var headPath = this.pm.selection.head.path,
        anchorPath = this.pm.selection.anchor.path
    } else {
        var headPath = this.pm.selection.from.path,
        anchorPath = this.pm.selection.to.path
    }

    var headElement = this.pm.doc.path([headPath[0]]),
    anchorElement = this.pm.doc.path([anchorPath[0]])
  /*  // For metadata, one has to look one level deeper.
    if (headElement.type.name==='metadata') {
        headElement = this.pm.doc.path(headPath.slice(0,2))
    }

    if (anchorElement.type.name==='metadata') {
        anchorElement = this.pm.doc.path(anchorPath.slice(0,2))
    }*/

    this.calculatePlaceHolderCss(headElement, nodes);

    if (headElement !== anchorElement) {
        /* Selection goes across document parts */
        jQuery('.editortoolbar button').addClass('disabled')
        jQuery('#block-style-label').html('')

    } else {

        switch (headElement) {
            case nodes.title:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Title'))
                break
            case nodes.subtitle:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Subtitle'))
                break
            case nodes.authors:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Authors'))
                break
            case nodes.keywords:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Keywords'))
                break
            case nodes.abstract:
                jQuery('.edit-button').removeClass('disabled')
                jQuery('#button-figure').addClass('disabled')
                jQuery('#current-position').html(gettext('Body'))

                var blockNodeType = true, blockNode, nextBlockNodeType

                if (_(headPath).isEqual(anchorPath)) {
                  // Selection within a single block.
                  blockNode = this.pm.doc.path(anchorPath)
                  blockNodeType = blockNode.type.name === 'heading' ? blockNode.type.name + '_' + blockNode.attrs.level : blockNode.type.name
                  jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                } else {
                    this.pm.doc.nodesBetween({path:headPath,offset:0},{path:anchorPath,offset:0}, function(node, path, parent) {
                      if (node.isBlock) {
                        nextBlockNodeType = node.type.name === 'heading' ? node.type.name + '_' + node.attrs.level : node.type.name
                        if (blockNodeType===true) {
                          blockNodeType = nextBlockNodeType
                        }
                        if (blockNodeType!==nextBlockNodeType){
                          blockNodeType = false
                        }

                      }
                    })

                    if (blockNodeType) {
                        jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                    } else {
                        jQuery('#block-style-label').html('')
                    }
                }

                break
            case nodes.contents:
            jQuery('.edit-button').removeClass('disabled')
            jQuery('#button-figure').addClass('disabled')
            jQuery('#current-position').html(gettext('Abstract'))

            var blockNodeType = true, blockNode, nextBlockNodeType

            if (_(headPath).isEqual(anchorPath)) {
              // Selection within a single block.
              blockNode = this.pm.doc.path(anchorPath)
              blockNodeType = blockNode.type.name === 'heading' ? blockNode.type.name + '_' + blockNode.attrs.level : blockNode.type.name
              jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
            } else {
                this.pm.doc.nodesBetween({path:headPath,offset:0},{path:anchorPath,offset:0}, function(node, path, parent) {
                  if (node.isBlock) {
                    nextBlockNodeType = node.type.name === 'heading' ? node.type.name + '_' + node.attrs.level : node.type.name
                    if (blockNodeType===true) {
                      blockNodeType = nextBlockNodeType
                    }
                    if (blockNodeType!==nextBlockNodeType){
                      blockNodeType = false
                    }

                  }
                })

                if (blockNodeType) {
                    jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                } else {
                    jQuery('#block-style-label').html('')
                }
            }

            break
        }
    }

    return true;
  }

  /** Show or hide placeholders ('Contents...', 'Title...', etc.) depending on
  whether these elements are empty or not.*/
  calculatePlaceHolderCss (headElement, nodes) {
    var newPlaceHolderCss = ''
    for (var elementType of [
      {'type': 'title', 'selector': '#document-title', 'placeholder': gettext('Title...')},
      {'type': 'subtitle', 'selector': '#metadata-subtitle', 'placeholder': gettext('Subtitle...')},
      {'type': 'authors', 'selector': '#metadata-authors', 'placeholder': gettext('Authors...')},
      {'type': 'abstract', 'selector': '#metadata-abstract', 'placeholder': gettext('Abstract...')},
      {'type': 'keywords', 'selector': '#metadata-keywords', 'placeholder': gettext('Keywords...')},
      {'type': 'contents', 'selector': '#document-contents', 'placeholder': gettext('Body...')}
    ]) {
      if (nodes[elementType.type].textContent.length === 0 &&
          (headElement != nodes[elementType.type] || !this.pm.hasFocus())) {
          newPlaceHolderCss += elementType.selector + ':before {content: "' +
              elementType.placeholder + '"}\n';
      }
    }
    if (this.placeHolderCss !== newPlaceHolderCss) {
      this.placeHolderCss = newPlaceHolderCss
      jQuery('#placeholderStyles')[0].innerHTML = newPlaceHolderCss;
    }
  }
}
<commit_msg>abstract and body reversed<commit_after>// Update UI (adapted from ProseMirror's src/menu/update.js)

const MIN_FLUSH_DELAY = 200
const UPDATE_TIMEOUT = 200

const BLOCK_LABELS = {
  'paragraph': gettext('Normal Text'),
  'heading_1': gettext('1st Heading'),
  'heading_2': gettext('2nd Heading'),
  'heading_3': gettext('3rd Heading'),
  'heading_4': gettext('4th Heading'),
  'heading_5': gettext('5th Heading'),
  'heading_6': gettext('6th Heading'),
  'code_block': gettext('Code')
}

export class UpdateUI {
  constructor(pm, events) {
    this.pm = pm

    this.mustUpdate = false
    this.updateInfo = null
    this.timeout = null
    this.lastFlush = 0
    this.placeHolderCss = ''

    this.events = events.split(" ")
    this.onEvent = this.onEvent.bind(this)
    this.force = this.force.bind(this)
    this.events.forEach(event => pm.on(event, this.onEvent))
    pm.on("flushed", this.onFlushed = this.onFlushed.bind(this))
    this.updateUI()
  }

  detach() {
    clearTimeout(this.timeout)
    this.events.forEach(event => this.pm.off(event, this.onEvent))
    this.pm.off("flush", this.onFlush)
    this.pm.off("flushed", this.onFlushed)
  }

  onFlushed() {
    let now = Date.now()
    if (this.mustUpdate && (now - this.lastFlush) >= MIN_FLUSH_DELAY) {
      this.lastFlush = now
      clearTimeout(this.timeout)
      this.mustUpdate = false
      this.updateUI()
    }
  }

  onEvent() {
    this.mustUpdate = true
    clearTimeout(this.timeout)
    this.timeout = setTimeout(this.force, UPDATE_TIMEOUT)
  }

  force() {
    if (this.pm.operation) {
      this.onEvent()
    } else {
      this.mustUpdate = false
      this.updateInfo = null
      this.lastFlush = Date.now()
      clearTimeout(this.timeout)
      this.updateUI()
    }
  }

  updateUI() {
    /* Fidus Writer code */

    // We count on the this precise order in all documents.
    let nodes = {
        'title': this.pm.doc.firstChild,
        'subtitle': this.pm.doc.child(1),
        'authors': this.pm.doc.child(2),
        'abstract': this.pm.doc.child(3),
        'keywords': this.pm.doc.child(4),
        'contents': this.pm.doc.child(5)
    }

    let documentTitle = nodes.title.textContent

        if (documentTitle.length === 0) {
            documentTitle = gettext('Untitled Document')
        }
        jQuery('title').html('Fidus Writer - ' + documentTitle)
        jQuery('#header h1').html(documentTitle)

    let marks = this.pm.activeMarks()
    let strong = marks.some(function(mark){return (mark.type.name==='strong')})

    if (strong) {
        jQuery('#button-bold').addClass('ui-state-active')
    } else {
        jQuery('#button-bold').removeClass('ui-state-active')
    }

    let em = marks.some(function(mark){return (mark.type.name==='em')})

    if (em) {
        jQuery('#button-italic').addClass('ui-state-active')
    } else {
        jQuery('#button-italic').removeClass('ui-state-active')
    }

    let link = marks.some(function(mark){return (mark.type.name==='link')})

    if (link) {
        jQuery('#button-link').addClass('ui-state-active')
    } else {
        jQuery('#button-link').removeClass('ui-state-active')
    }

    /* Block level selector */
    if (this.pm.selection.head) {
        var headPath = this.pm.selection.head.path,
        anchorPath = this.pm.selection.anchor.path
    } else {
        var headPath = this.pm.selection.from.path,
        anchorPath = this.pm.selection.to.path
    }

    var headElement = this.pm.doc.path([headPath[0]]),
    anchorElement = this.pm.doc.path([anchorPath[0]])

    this.calculatePlaceHolderCss(headElement, nodes);

    if (headElement !== anchorElement) {
        /* Selection goes across document parts */
        jQuery('.editortoolbar button').addClass('disabled')
        jQuery('#block-style-label').html('')

    } else {

        switch (headElement) {
            case nodes.title:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Title'))
                break
            case nodes.subtitle:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Subtitle'))
                break
            case nodes.authors:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Authors'))
                break
            case nodes.keywords:
                jQuery('.edit-button').addClass('disabled')
                jQuery('#block-style-label').html('')
                jQuery('#current-position').html(gettext('Keywords'))
                break
            case nodes.abstract:
                jQuery('.edit-button').removeClass('disabled')
                jQuery('#button-figure').addClass('disabled')
                jQuery('#current-position').html(gettext('Abstract'))

                var blockNodeType = true, blockNode, nextBlockNodeType

                if (_(headPath).isEqual(anchorPath)) {
                  // Selection within a single block.
                  blockNode = this.pm.doc.path(anchorPath)
                  blockNodeType = blockNode.type.name === 'heading' ? blockNode.type.name + '_' + blockNode.attrs.level : blockNode.type.name
                  jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                } else {
                    this.pm.doc.nodesBetween({path:headPath,offset:0},{path:anchorPath,offset:0}, function(node, path, parent) {
                      if (node.isBlock) {
                        nextBlockNodeType = node.type.name === 'heading' ? node.type.name + '_' + node.attrs.level : node.type.name
                        if (blockNodeType===true) {
                          blockNodeType = nextBlockNodeType
                        }
                        if (blockNodeType!==nextBlockNodeType){
                          blockNodeType = false
                        }

                      }
                    })

                    if (blockNodeType) {
                        jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                    } else {
                        jQuery('#block-style-label').html('')
                    }
                }

                break
            case nodes.contents:
            jQuery('.edit-button').removeClass('disabled')
            jQuery('#button-figure').addClass('disabled')
            jQuery('#current-position').html(gettext('Body'))

            var blockNodeType = true, blockNode, nextBlockNodeType

            if (_(headPath).isEqual(anchorPath)) {
              // Selection within a single block.
              blockNode = this.pm.doc.path(anchorPath)
              blockNodeType = blockNode.type.name === 'heading' ? blockNode.type.name + '_' + blockNode.attrs.level : blockNode.type.name
              jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
            } else {
                this.pm.doc.nodesBetween({path:headPath,offset:0},{path:anchorPath,offset:0}, function(node, path, parent) {
                  if (node.isBlock) {
                    nextBlockNodeType = node.type.name === 'heading' ? node.type.name + '_' + node.attrs.level : node.type.name
                    if (blockNodeType===true) {
                      blockNodeType = nextBlockNodeType
                    }
                    if (blockNodeType!==nextBlockNodeType){
                      blockNodeType = false
                    }

                  }
                })

                if (blockNodeType) {
                    jQuery('#block-style-label').html(BLOCK_LABELS[blockNodeType])
                } else {
                    jQuery('#block-style-label').html('')
                }
            }

            break
        }
    }

    return true;
  }

  /** Show or hide placeholders ('Contents...', 'Title...', etc.) depending on
  whether these elements are empty or not.*/
  calculatePlaceHolderCss (headElement, nodes) {
    var newPlaceHolderCss = ''
    for (var elementType of [
      {'type': 'title', 'selector': '#document-title', 'placeholder': gettext('Title...')},
      {'type': 'subtitle', 'selector': '#metadata-subtitle', 'placeholder': gettext('Subtitle...')},
      {'type': 'authors', 'selector': '#metadata-authors', 'placeholder': gettext('Authors...')},
      {'type': 'abstract', 'selector': '#metadata-abstract', 'placeholder': gettext('Abstract...')},
      {'type': 'keywords', 'selector': '#metadata-keywords', 'placeholder': gettext('Keywords...')},
      {'type': 'contents', 'selector': '#document-contents', 'placeholder': gettext('Body...')}
    ]) {
      if (nodes[elementType.type].textContent.length === 0 &&
          (headElement != nodes[elementType.type] || !this.pm.hasFocus())) {
          newPlaceHolderCss += elementType.selector + ':before {content: "' +
              elementType.placeholder + '"}\n';
      }
    }
    if (this.placeHolderCss !== newPlaceHolderCss) {
      this.placeHolderCss = newPlaceHolderCss
      jQuery('#placeholderStyles')[0].innerHTML = newPlaceHolderCss;
    }
  }
}
<|endoftext|>


<commit_before>// eslint-disable-next-line no-unused-vars
const viz = {
  init(nodes, links) {
    const svg = d3.select('svg');

    const nodesGroup = svg.append('g');
    nodesGroup.attr('class', 'nodes');

    const linksGroup = svg.append('g');
    linksGroup.attr('class', 'links');

    this.allCircles = nodesGroup.selectAll('.node');
    this.allLabels = nodesGroup.selectAll('.textLabel');
    this.allLines = linksGroup.selectAll('.link');

    this.update(nodes, links);
  },

  simulateForce(nodes, links) {
    const { width, height } = this.getDimensions();
    const linkForce = d3.forceLink(links);
    let simulation;

    if (!this.simulation) {
      simulation = d3.forceSimulation(nodes);
    } else {
      simulation = this.simulation;
      simulation.nodes(nodes);
    }

    linkForce.id((d) => d.hostname);
    simulation.force('link', linkForce);
    simulation.force('charge', d3.forceManyBody());
    simulation.force('center', d3.forceCenter(width/2, height/2));
    simulation.alphaTarget(1);

    return simulation;
  },

  getDimensions() {
    const visualization = document.getElementById('visualization');
    const { width, height } = visualization.getBoundingClientRect();

    return {
      width,
      height
    };
  },

  tick() {
    this.simulation.stop();

    this.allCircles
      .attr('cx', function(d) {
        return d.x;
      })
      .attr('cy', function(d) {
        return d.y;
      });

    this.allLabels
      .attr('x', function(d) {
        return d.x;
      })
      .attr('y', function(d) {
        return d.y;
      });

    this.allLines
      .attr('x1', function(d) {
        return d.source.x;
      })
      .attr('y1', function(d) {
        return d.source.y;
      })
      .attr('x2', function(d) {
        return d.target.x;
      })
      .attr('y2', function(d) {
        return d.target.y;
      });

    this.simulation.tick();
  },

  update(nodes, links) {
    this.simulation = this.simulateForce(nodes, links);
    this.tick();

    // determine which nodes to keep, remove and add: the update selection
    this.allCircles = this.allCircles.data(nodes, function(d) {
      return d.hostname;
    });

    // remove old nodes: the exit selection
    const oldNodes = this.allCircles.exit();
    oldNodes.remove();

    // add new nodes: the enter selection
    let newNodes = this.allCircles.enter();
    newNodes = newNodes.append('circle');
    newNodes.attr('class', 'node');
    newNodes.attr('fill', 'red');
    newNodes.attr('r', 5);

    this.allCircles = newNodes.merge(this.allCircles);

    this.allLabels = this.allLabels.data(nodes, function(d) {
      return d.hostname;
    });

    const oldText = this.allLabels.exit();
    oldText.remove();

    let newText = this.allLabels.enter();
    newText = newText.append('text');
    newText.attr('class', 'textLabel')
    .text( function (d) {
      return d.hostname;
    })
    .attr('fill', 'white');

    this.allLabels = newText.merge(this.allLabels);

    // determine which links to keep, remove and add, the update selection
    this.allLines = this.allLines
      .data(links, function(d) {
        return `${d.source.hostname}-${d.target.hostname}`;
      });

    // remove old links
    const oldLinks = this.allLines.exit();
    oldLinks.remove();

    // add new links
    let newLinks = this.allLines.enter();
    newLinks = newLinks.append('line');
    this.allLines = newLinks.merge(this.allLines);

    // Update and restart the simulation.
    this.simulation = this.simulateForce(nodes, links);
    this.tick();
  }
};
<commit_msg>arrow functions added. fixes #76<commit_after>// eslint-disable-next-line no-unused-vars
const viz = {
  init(nodes, links) {
    const svg = d3.select('svg');

    const nodesGroup = svg.append('g');
    nodesGroup.attr('class', 'nodes');

    const linksGroup = svg.append('g');
    linksGroup.attr('class', 'links');

    this.allCircles = nodesGroup.selectAll('.node');
    this.allLabels = nodesGroup.selectAll('.textLabel');
    this.allLines = linksGroup.selectAll('.link');

    this.update(nodes, links);
  },

  simulateForce(nodes, links) {
    const { width, height } = this.getDimensions();
    const linkForce = d3.forceLink(links);
    let simulation;

    if (!this.simulation) {
      simulation = d3.forceSimulation(nodes);
    } else {
      simulation = this.simulation;
      simulation.nodes(nodes);
    }

    linkForce.id((d) => d.hostname);
    simulation.force('link', linkForce);
    simulation.force('charge', d3.forceManyBody());
    simulation.force('center', d3.forceCenter(width/2, height/2));
    simulation.alphaTarget(1);

    return simulation;
  },

  getDimensions() {
    const visualization = document.getElementById('visualization');
    const { width, height } = visualization.getBoundingClientRect();

    return {
      width,
      height
    };
  },

  tick() {
    this.simulation.stop();
    this.allCircles
      .attr('cx', (d) => d.x)
      .attr('cy', (d) => d.y);
    this.allLabels
      .attr('x', (d) => d.x)
      .attr('y', (d) => d.y);
    this.allLines
      .attr('x1', (d) => d.source.x)
      .attr('y1', (d) => d.source.y)
      .attr('x2', (d) => d.target.x)
      .attr('y2', (d) => d.target.y);
    this.simulation.tick();
  },

  update(nodes, links) {
    this.simulation = this.simulateForce(nodes, links);
    this.tick();

    // determine which nodes to keep, remove and add: the update selection
    this.allCircles = this.allCircles.data(nodes, (d) => d.hostname);

    // remove old nodes: the exit selection
    const oldNodes = this.allCircles.exit();
    oldNodes.remove();

    // add new nodes: the enter selection
    let newNodes = this.allCircles.enter();
    newNodes = newNodes.append('circle');
    newNodes.attr('class', 'node');
    newNodes.attr('fill', 'red');
    newNodes.attr('r', 5);

    this.allCircles = newNodes.merge(this.allCircles);

    this.allLabels = this.allLabels.data(nodes, (d) => d.hostname);

    const oldText = this.allLabels.exit();
    oldText.remove();

    let newText = this.allLabels.enter();
    newText = newText.append('text');
    newText.attr('class', 'textLabel')
    .text((d) => d.hostname)
    .attr('fill', 'white');

    this.allLabels = newText.merge(this.allLabels);

    // determine which links to keep, remove and add, the update selection
    this.allLines = this.allLines
      .data(links, (d) => `${d.source.hostname}-${d.target.hostname}`);

    // remove old links
    const oldLinks = this.allLines.exit();
    oldLinks.remove();

    // add new links
    let newLinks = this.allLines.enter();
    newLinks = newLinks.append('line');
    this.allLines = newLinks.merge(this.allLines);

    // Update and restart the simulation.
    this.simulation = this.simulateForce(nodes, links);
    this.tick();
  }
};
<|endoftext|>