<commit_before>import moment from "moment"
import "twix"
import Promise from "bluebird"
import { listByKey as listProjects } from "./projects"
import { listByKey as listTasks } from "./tasks"
import { listByKey as listClients } from "./clients"
import { get as getAccount } from "./account"

require("dotenv-extended").load()

const deductibles = process.env.DEDUCTIBLE_TASKS
const hoursPerDay = process.env.HOURS_PER_DAY || 7.5
const isWeekend = dayNumber => [0, 6].includes(dayNumber)

// for each day, get
// * due hours for that day (normally 7.5)
// * logged hours per task
// * sum of all logged hours
// * balance for that day (due hours - logged hours)
// * cumulative balance from start of year

export const get = (harvestClient, { startDate }) => {
  const Reports = harvestClient.Reports
  const timeEntriesByUserAsync = Promise.promisify(Reports.timeEntriesByUser, { context: Reports })

  const fromDate = moment.utc(startDate)
  const today = moment().endOf("day")
  const toDate = moment().utc().endOf("isoweek") // Sunday as last day of week

  return getAccount(harvestClient, {}).then((account) => {
    const userId = account.user.id

    return Promise.all([
      listClients(harvestClient, {}),
      listProjects(harvestClient, {}),
      listTasks(harvestClient, {}),
      timeEntriesByUserAsync({
        from: fromDate.format("YYYYMMDD"),
        // NOTE: to is not included, so we need to add
        // an extra day to the harvest query
        to: moment.utc(toDate).add(1, "day").format("YYYYMMDD"),
        user_id: userId,
      }),
    ])
  }).then(([clients, projects, tasks, entries]) => {
    let cumulativeBalance = 0.0
    const dayTotals = {}

    // * iterate all days between start date and end date
    // * set start balance for that day (weekday vs holiday or future)
    // * for each day, find all entries spent on that day
    // * for each entry, get the tasks and their individual logged hours
    // * if no entry for given day, leave balance at start balance

    // const populatedEntries = entries.map(({ day_entry: dayEntry }) => {
    moment(startDate).twix(toDate).toArray("days").forEach((day) => {
      const dayDate = day.format("YYYY-MM-DD")

      // we're starting a new day, init the day balance (negative due hours)
      const weekday = day.day()
      const future = day > today
      const dueHours = (isWeekend(weekday) || future) ? 0 : hoursPerDay

      dayTotals[dayDate] = {
        future,
        weekday,
        due_hours: dueHours,
        logged_hours: 0,
        // init balance as -hoursPerDay for weekdays, not for Sat & Sun
        balance: -dueHours,
        day_entries: [],
      }

      // Grab entries from harvest for this date (there might or might not be any)
      // and populate them with calculated values
      dayTotals[dayDate].day_entries = entries
      .filter(({ day_entry }) => day_entry.spent_at === dayDate)
      .map(({ day_entry: dayEntry }) => {
        const project = projects[dayEntry.project_id]
        const client = clients[project.project.client_id]
        const task = tasks[dayEntry.task_id]

        // deductible tasks reduce the logged time from the
        // total balance instead of adding to it
        //
        // ex:
        // startbalance -7.5
        // overtime holiday 7.5
        // balance: -7.5
        //
        // ex 2:
        // startbalance -7.5
        // overtime holiday 7.5
        // some task 2.5
        // balance: -5
        if (deductibles.includes(task.task.name)) {
          // reduce the logged hours from cumulative hours
          dayTotals[dayDate].logged_hours -= dayEntry.hours
          // deductible days leave the day balance at -hoursPerDay,
          // regardless of logged hours, is that correct...?
        } else {
          dayTotals[dayDate].logged_hours += dayEntry.hours
          dayTotals[dayDate].balance += dayEntry.hours
        }

        return {
          ...dayEntry,
          ...task,
          project: {
            ...project.project,
            ...client,
          },
        }
      })

      cumulativeBalance += dayTotals[dayDate].balance
      dayTotals[dayDate].cumulative_balance = cumulativeBalance
    })

    const balance = Math.round(cumulativeBalance * 100) / 100
    const balanceDuration = moment.duration(balance, "hours")

    return {
      fromDate,
      toDate,
      balance: {
        value: balance,
        hours: Math.floor(balance),
        minutes: balanceDuration.minutes(),
      },
      dayTotals,
    }
  })
}

export default {
  get,
}
<commit_msg>Remove clients from report response<commit_after>import moment from "moment"
import "twix"
import Promise from "bluebird"
import { listByKey as listProjects } from "./projects"
import { listByKey as listTasks } from "./tasks"
import { listByKey as listClients } from "./clients"
import { get as getAccount } from "./account"

require("dotenv-extended").load()

const deductibles = process.env.DEDUCTIBLE_TASKS
const hoursPerDay = process.env.HOURS_PER_DAY || 7.5
const isWeekend = dayNumber => [0, 6].includes(dayNumber)

// for each day, get
// * due hours for that day (normally 7.5)
// * logged hours per task
// * sum of all logged hours
// * balance for that day (due hours - logged hours)
// * cumulative balance from start of year

export const get = (harvestClient, { startDate }) => {
  const Reports = harvestClient.Reports
  const timeEntriesByUserAsync = Promise.promisify(Reports.timeEntriesByUser, { context: Reports })

  const fromDate = moment.utc(startDate)
  const today = moment().endOf("day")
  const toDate = moment().utc().endOf("isoweek") // Sunday as last day of week

  return getAccount(harvestClient, {}).then((account) => {
    const userId = account.user.id

    return Promise.all([
      listClients(harvestClient, {}),
      listProjects(harvestClient, {}),
      listTasks(harvestClient, {}),
      timeEntriesByUserAsync({
        from: fromDate.format("YYYYMMDD"),
        // NOTE: to is not included, so we need to add
        // an extra day to the harvest query
        to: moment.utc(toDate).add(1, "day").format("YYYYMMDD"),
        user_id: userId,
      }),
    ])
  }).then(([clients, projects, tasks, entries]) => {
    console.log(clients)
    let cumulativeBalance = 0.0
    const dayTotals = {}

    // * iterate all days between start date and end date
    // * set start balance for that day (weekday vs holiday or future)
    // * for each day, find all entries spent on that day
    // * for each entry, get the tasks and their individual logged hours
    // * if no entry for given day, leave balance at start balance

    // const populatedEntries = entries.map(({ day_entry: dayEntry }) => {
    moment(startDate).twix(toDate).toArray("days").forEach((day) => {
      const dayDate = day.format("YYYY-MM-DD")

      // we're starting a new day, init the day balance (negative due hours)
      const weekday = day.day()
      const future = day > today
      const dueHours = (isWeekend(weekday) || future) ? 0 : hoursPerDay

      dayTotals[dayDate] = {
        future,
        weekday,
        due_hours: dueHours,
        logged_hours: 0,
        // init balance as -hoursPerDay for weekdays, not for Sat & Sun
        balance: -dueHours,
        day_entries: [],
      }

      // Grab entries from harvest for this date (there might or might not be any)
      // and populate them with calculated values
      dayTotals[dayDate].day_entries = entries
      .filter(({ day_entry }) => day_entry.spent_at === dayDate)
      .map(({ day_entry: dayEntry }) => {
        const project = projects[dayEntry.project_id]
        const client = {} // clients[project.project.client_id]
        const task = tasks[dayEntry.task_id]

        // deductible tasks reduce the logged time from the
        // total balance instead of adding to it
        //
        // ex:
        // startbalance -7.5
        // overtime holiday 7.5
        // balance: -7.5
        //
        // ex 2:
        // startbalance -7.5
        // overtime holiday 7.5
        // some task 2.5
        // balance: -5
        if (deductibles.includes(task.task.name)) {
          // reduce the logged hours from cumulative hours
          dayTotals[dayDate].logged_hours -= dayEntry.hours
          // deductible days leave the day balance at -hoursPerDay,
          // regardless of logged hours, is that correct...?
        } else {
          dayTotals[dayDate].logged_hours += dayEntry.hours
          dayTotals[dayDate].balance += dayEntry.hours
        }

        return {
          ...dayEntry,
          ...task,
          project: {
            ...project.project,
            ...client,
          },
        }
      })

      cumulativeBalance += dayTotals[dayDate].balance
      dayTotals[dayDate].cumulative_balance = cumulativeBalance
    })

    const balance = Math.round(cumulativeBalance * 100) / 100
    const balanceDuration = moment.duration(balance, "hours")

    return {
      fromDate,
      toDate,
      balance: {
        value: balance,
        hours: Math.floor(balance),
        minutes: balanceDuration.minutes(),
      },
      dayTotals,
    }
  })
}

export default {
  get,
}
<|endoftext|>


<commit_before>// Node
var util = require('util');
// 1st party
var db = require('./db');
var pre = require('./presenters');
// 3rd party
var debug = require('debug')('app:middleware');

// Assoc ctx.currUser if the sessionId cookie (UUIDv4 String)
// is an active session.
exports.currUser = function() {
  return function *(next) {
    var sessionId = this.cookies.get('sessionId');
    debug('[wrapCurrUser] sessionId: ', sessionId);
    if (! sessionId) return yield next;
    var user = yield db.findUserBySessionId(sessionId);
    if (user)
      this.currUser = pre.presentUser(user);
    if (user) {
      debug('[wrapCurrUser] User found');
    } else {
      debug('[wrapCurrUser] No user found');
    }
    yield next;
  };
};

// Expose req.flash (getter) and res.flash = _ (setter)
// Flash data persists in user's sessions until the next ~successful response
exports.flash = function(cookieName) {
  return function *(next) {
    var data;
    if (this.cookies.get(cookieName)) {
      data = JSON.parse(this.cookies.get(cookieName));
    } else {
      data = {};
    }

    Object.defineProperty(this, 'flash', {
      enumerable: true,
      get: function() {
        return data;
      },
      set: function(val) {
        this.cookies.set(cookieName, JSON.stringify(val));
      }
    });

    yield next;

    if (this.response.status < 300) {
      this.cookies.set(cookieName, null);
    }
  };
};
<commit_msg>Ensure sessionId is UUID before querying DB<commit_after>// Node
var util = require('util');
// 1st party
var db = require('./db');
var pre = require('./presenters');
var belt = require('./belt');
// 3rd party
var debug = require('debug')('app:middleware');

// Assoc ctx.currUser if the sessionId cookie (UUIDv4 String)
// is an active session.
exports.currUser = function() {
  return function *(next) {
    var sessionId = this.cookies.get('sessionId');
    // Skip if no session id
    if (!sessionId) return yield next;
    // Skip if it's not a uuid
    if (!belt.isValidUuid(sessionId)) yield next;

    var user = yield db.findUserBySessionId(sessionId);
    this.currUser = user && pre.presentUser(user);  // or null
    yield next;
  };
};

// Expose req.flash (getter) and res.flash = _ (setter)
// Flash data persists in user's sessions until the next ~successful response
exports.flash = function(cookieName) {
  return function *(next) {
    var data;
    if (this.cookies.get(cookieName)) {
      data = JSON.parse(this.cookies.get(cookieName));
    } else {
      data = {};
    }

    Object.defineProperty(this, 'flash', {
      enumerable: true,
      get: function() {
        return data;
      },
      set: function(val) {
        this.cookies.set(cookieName, JSON.stringify(val));
      }
    });

    yield next;

    if (this.response.status < 300) {
      this.cookies.set(cookieName, null);
    }
  };
};
<|endoftext|>


<commit_before>module.exports = (app) => {
  app.use('/register',
    require('./policies/AuthenticationControllerPolicy').register,
    require('./controllers/AuthenticationController').register)

  app.use('/login',
    require('./controllers/AuthenticationController').login)

  app.use('/songs',
    require('./controllers/SongsController').index)

  app.use('/song/edit',
    require('./controllers/SongsController').put)

  app.use('/song/:songId',
    require('./controllers/SongsController').show)

  app.use('/song',
    require('./controllers/SongsController').post)
}
<commit_msg>add bookmarks routes to server<commit_after>module.exports = (app) => {
  app.use('/register',
    require('./policies/AuthenticationControllerPolicy').register,
    require('./controllers/AuthenticationController').register)

  app.use('/login',
    require('./controllers/AuthenticationController').login)

  app.use('/songs',
    require('./controllers/SongsController').index)

  app.use('/song/edit',
    require('./controllers/SongsController').put)

  app.use('/song/:songId',
    require('./controllers/SongsController').show)

  app.use('/song',
    require('./controllers/SongsController').post)

  app.use('/bookmarks',
    require('./controllers/BookmarksController').index)

  app.use('/bookmark/:bookmarkId',
    require('./controllers/BookmarksController').delete)

  app.use('/bookmark',
    require('./controllers/BookmarksController').post)
}
<|endoftext|>


<commit_before>const fs = require('fs')
const tape = require('tape')
const Kernel = require('ewasm-kernel')
const KernelInterface = require('ewasm-kernel/interface.js')
const KernelEnvironment = require('ewasm-kernel/environment.js')
const ethUtil = require('ethereumjs-util')
const compiler = require('../index.js')
const dir = `${__dirname}/opcode`

// Transcompiled contracts have their EVM1 memory start at this WASM memory location
const EVM_MEMORY_OFFSET = 32768

let testFiles = fs.readdirSync(dir).filter((name) => name.endsWith('.json'))

tape('testing EVM1 Ops', (t) => {
  testFiles.forEach((path) => {
    let opTest = require(`${dir}/${path}`)
    opTest.forEach((test) => {
      const testEnvironment = new KernelEnvironment()
      const testInterface = new KernelInterface(testEnvironment)
      const testInstance = buildTest(test.op, testInterface)

      // FIXME: have separate `t.test()` for better grouping
      t.comment(`testing ${test.op} ${test.description}`)

      // populate the stack with predefined values
      test.stack.in.forEach((item, index) => {
        item = hexToUint8Array(item)
        setMemory(testInstance, item, index * 32)
      })

      // populate the memory
      if (test.memory) {
        Object.keys(test.memory.in).forEach((offset) => {
          test.memory.in[offset].forEach((item, index) => {
            offset |= 0
            offset += EVM_MEMORY_OFFSET
            item = hexToUint8Array(item)
            setMemory(testInstance, item, offset + index * 32)
          })
        })
      }

      // Runs the opcode. An empty stack must start with the stack pointer at -8.
      // also we have to add 8 to the resulting sp to accommodate for the fact
      // that the sp is pointing to memory segment holding the last stack item
      let sp = (test.stack.in.length - 1) * 32
      sp = testInstance.exports[test.op](...(test.params || []), sp) + 32
      t.equal(sp / 32, test.stack.out.length, 'should have corrent number of items on the stack')
      sp = 0

      // compare the output stack against the predefined values
      test.stack.out.forEach((item, index) => {
        const expectedItem = hexToUint8Array(item)
        const result = getMemory(testInstance, sp, sp = sp + 32)
        t.equals(result.toString(), expectedItem.toString(), 'should have correct item on stack')
      })

      // check the memory
      if (test.memory) {
        Object.keys(test.memory.out).forEach((offset) => {
          test.memory.out[offset].forEach((item, index) => {
            offset |= 0
            offset += EVM_MEMORY_OFFSET
            const expectedItem = hexToUint8Array(item)
            const result = getMemory(testInstance, offset + index * 32, offset + index * 32 + expectedItem.length)
            t.equals(result.toString(), expectedItem.toString(), `should have the correct memory slot at ${offset}:${index}`)
          })
        })
      }

      // check for EVM return value
      if (test.return) {
        const expectedItem = hexToUint8Array(test.return)
        const result = testEnvironment.returnValue
        t.equals(result.toString(), expectedItem.toString(), 'should have correct return value')
      }
    })
  })
  t.end()
})

function buildTest (op, interface) {
  const funcs = compiler.resolveFunctions(new Set([op]))
  const linked = compiler.buildModule(funcs, [], [op])
  const wasm = compiler.compileWAST(linked)
  return Kernel.codeHandler(wasm, interface)
}

function hexToUint8Array(item, length) {
  return new Uint8Array(ethUtil.setLength(new Buffer(item.slice(2), 'hex'), 32)).reverse()
}

function setMemory(instance, value, start) {
  new Uint8Array(instance.exports.memory).set(value, start)
}

function getMemory(instance, start, end) {
  return new Uint8Array(instance.exports.memory).slice(start, end)
}
<commit_msg>Fix length typo in hexToUint8Array<commit_after>const fs = require('fs')
const tape = require('tape')
const Kernel = require('ewasm-kernel')
const KernelInterface = require('ewasm-kernel/interface.js')
const KernelEnvironment = require('ewasm-kernel/environment.js')
const ethUtil = require('ethereumjs-util')
const compiler = require('../index.js')
const dir = `${__dirname}/opcode`

// Transcompiled contracts have their EVM1 memory start at this WASM memory location
const EVM_MEMORY_OFFSET = 32768

let testFiles = fs.readdirSync(dir).filter((name) => name.endsWith('.json'))

tape('testing EVM1 Ops', (t) => {
  testFiles.forEach((path) => {
    let opTest = require(`${dir}/${path}`)
    opTest.forEach((test) => {
      const testEnvironment = new KernelEnvironment()
      const testInterface = new KernelInterface(testEnvironment)
      const testInstance = buildTest(test.op, testInterface)

      // FIXME: have separate `t.test()` for better grouping
      t.comment(`testing ${test.op} ${test.description}`)

      // populate the stack with predefined values
      test.stack.in.forEach((item, index) => {
        item = hexToUint8Array(item)
        setMemory(testInstance, item, index * 32)
      })

      // populate the memory
      if (test.memory) {
        Object.keys(test.memory.in).forEach((offset) => {
          test.memory.in[offset].forEach((item, index) => {
            offset |= 0
            offset += EVM_MEMORY_OFFSET
            item = hexToUint8Array(item)
            setMemory(testInstance, item, offset + index * 32)
          })
        })
      }

      // Runs the opcode. An empty stack must start with the stack pointer at -8.
      // also we have to add 8 to the resulting sp to accommodate for the fact
      // that the sp is pointing to memory segment holding the last stack item
      let sp = (test.stack.in.length - 1) * 32
      sp = testInstance.exports[test.op](...(test.params || []), sp) + 32
      t.equal(sp / 32, test.stack.out.length, 'should have corrent number of items on the stack')
      sp = 0

      // compare the output stack against the predefined values
      test.stack.out.forEach((item, index) => {
        const expectedItem = hexToUint8Array(item)
        const result = getMemory(testInstance, sp, sp = sp + 32)
        t.equals(result.toString(), expectedItem.toString(), 'should have correct item on stack')
      })

      // check the memory
      if (test.memory) {
        Object.keys(test.memory.out).forEach((offset) => {
          test.memory.out[offset].forEach((item, index) => {
            offset |= 0
            offset += EVM_MEMORY_OFFSET
            const expectedItem = hexToUint8Array(item)
            const result = getMemory(testInstance, offset + index * 32, offset + index * 32 + expectedItem.length)
            t.equals(result.toString(), expectedItem.toString(), `should have the correct memory slot at ${offset}:${index}`)
          })
        })
      }

      // check for EVM return value
      if (test.return) {
        const expectedItem = hexToUint8Array(test.return)
        const result = testEnvironment.returnValue
        t.equals(result.toString(), expectedItem.toString(), 'should have correct return value')
      }
    })
  })
  t.end()
})

function buildTest (op, interface) {
  const funcs = compiler.resolveFunctions(new Set([op]))
  const linked = compiler.buildModule(funcs, [], [op])
  const wasm = compiler.compileWAST(linked)
  return Kernel.codeHandler(wasm, interface)
}

function hexToUint8Array(item, length) {
  return new Uint8Array(ethUtil.setLength(new Buffer(item.slice(2), 'hex'), length || 32)).reverse()
}

function setMemory(instance, value, start) {
  new Uint8Array(instance.exports.memory).set(value, start)
}

function getMemory(instance, start, end) {
  return new Uint8Array(instance.exports.memory).slice(start, end)
}
<|endoftext|>


<commit_before>var fs = require('fs');

var Logger = {
    className: 'Logger',

    /**
     * Syntax:
     * [Time]: [Message]
     */
    log: function(){
        fs.appendFileSync(this.logFile, this.createText(arguments) + "\r\n");
        //console.log.apply(console, arr);
    },

    logArray: function(className, arr){
        fs.appendFileSync(this.logFile, this.createText([className, ':'], arr) + "\r\n");
    },

    createText: function(params, params2){
        params2 = params2 || [];

        var result = ['[', this.getTime(), '] :'];
        for(var i=0; i<params.length; i++){
            result.push(params[i]);
        }
        for(i=0; i<params2.length; i++){
            result.push(params2[i]);
        }
        return result.join(' ');
    },

    sysLog: function(){
        var arr = ['[', this.getTime(), '] :'];
        for(var i =0; i < arguments.length; i++){
            arr.push(arguments[i]);
        }
        console.log.apply(console, arr);
    },

    init: function(){
        var file = this.getFile();
        this.sysLog('Init log file :', file);

        this.logFile = file;

        if(!fs.existsSync(file)){
            console.log(process.cwd());
            console.log(__filename);
            console.log(__dirname);
            var fd = fs.openSync("/app/server/" + file, "a+");
            fs.closeSync(fd);
        }
    },

    getFile: function(index){
        var logName = this.getLogName();
        index = index || 0;
        var fileName = this.getFormattedLogName(logName, index);

        if(!fs.existsSync(fileName)){
            return fileName;
        }

        var stat = fs.statSync(fileName);
        if(stat.size < 1024 * 1024 * 10){
            return fileName;
        }

        return this.getFile(index + 1);
    },

    /**
     * Syntax: dd/mm/YYYY hh:mm:ss
     * @returns {string}
     */
    getTime: function(){
        var d = new Date();
        return d.getDate() + '/' + d.getMonth() + '/' + d.getFullYear() + ' '
            + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
    },

    getFormattedLogName: function(logName, index){
        if(index < 1){
            return 'log/' + logName + '.log';
        }
        return 'log/' + logName + '-' + index + '.log';
    },

    getLogName: function(){
        var d = new Date();

        return d.getDate() + '-' + d.getMonth() + '-' + d.getFullYear();
    }
};

var compile = require('./compile.js');
module.exports = compile.singleton(Logger, null, true);
<commit_msg>fix crashing<commit_after>var fs = require('fs');

var Logger = {
    className: 'Logger',

    /**
     * Syntax:
     * [Time]: [Message]
     */
    log: function(){
        fs.appendFileSync(this.logFile, this.createText(arguments) + "\r\n");
        //console.log.apply(console, arr);
    },

    logArray: function(className, arr){
        fs.appendFileSync(this.logFile, this.createText([className, ':'], arr) + "\r\n");
    },

    createText: function(params, params2){
        params2 = params2 || [];

        var result = ['[', this.getTime(), '] :'];
        for(var i=0; i<params.length; i++){
            result.push(params[i]);
        }
        for(i=0; i<params2.length; i++){
            result.push(params2[i]);
        }
        return result.join(' ');
    },

    sysLog: function(){
        var arr = ['[', this.getTime(), '] :'];
        for(var i =0; i < arguments.length; i++){
            arr.push(arguments[i]);
        }
        console.log.apply(console, arr);
    },

    init: function(){
        var file = this.getFile();
        this.sysLog('Init log file :', file);

        this.logFile = file;

        if(!fs.existsSync(file)){
            console.log(process.cwd());
            console.log(__filename);
            console.log(__dirname);
            var fd = fs.openSync("/app/server/." + file, "a+");
            fs.closeSync(fd);
        }
    },

    getFile: function(index){
        var logName = this.getLogName();
        index = index || 0;
        var fileName = this.getFormattedLogName(logName, index);

        if(!fs.existsSync(fileName)){
            return fileName;
        }

        var stat = fs.statSync(fileName);
        if(stat.size < 1024 * 1024 * 10){
            return fileName;
        }

        return this.getFile(index + 1);
    },

    /**
     * Syntax: dd/mm/YYYY hh:mm:ss
     * @returns {string}
     */
    getTime: function(){
        var d = new Date();
        return d.getDate() + '/' + d.getMonth() + '/' + d.getFullYear() + ' '
            + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
    },

    getFormattedLogName: function(logName, index){
        if(index < 1){
            return 'log/' + logName + '.log';
        }
        return 'log/' + logName + '-' + index + '.log';
    },

    getLogName: function(){
        var d = new Date();

        return d.getDate() + '-' + d.getMonth() + '-' + d.getFullYear();
    }
};

var compile = require('./compile.js');
module.exports = compile.singleton(Logger, null, true);
<|endoftext|>


<commit_before>/**
 * @author: Leandro Leite Pinto de Oliveira <lleitep3 at gmail dot com>
 */

(function($){

    $.fn.maxLengthBox = function( options ){

        // Confs
        var conf = {
            'fontColor'      : '#ccc',
            'fontColorFinal' : '#DD0000',
            'definedColor'   : '#ccc',
            'fontSize'       : '0.8em',

            style : function () {
                return 'font-size:' + this.fontSize     + ';'
                + 'color:'      + this.definedColor + ';'
                + 'position:'   + 'absolute'        + ';'
            ;
            }
        }

        // methods of plugin
        var methods = {

            // initialize plugin
            init : function(el){
                el.live('focus',function(){
                    methods.exec($(this));
                });

                el.live('keyup',function(){
                    methods.exec($(this));
                });

                if( options )
                    $.extend( conf, options );
            },
            // execute function of plugin
            exec : function (el){
                $('#maxLengthBox').remove();
                var val = el.attr('maxlength') - el.val().length;
                this.showBox(el,val);
            },

            setFontColor : function (val){
                conf.definedColor =
                (val == 0)? conf.fontColorFinal : conf.fontColor;
            },

            // create MaxLengthBox
            showBox : function (el, val){
                var offset = el.offset();

                this.setFontColor(val);

                $('body').append('
'+val+'
');

                offset.left += el.width()  - $('#maxLengthBox').width();
                offset.top  += el.height() - $('#maxLengthBox').height() + 5;

                $('#maxLengthBox').css('left',(offset.left+'px'));
                $('#maxLengthBox').css('top',(offset.top+'px'));
            }
        }

        // start plugin
        methods.init($(this));

    }

})(jQuery);
<commit_msg>Mudança de live para delegate, para melhor performance.<commit_after>/**
 * @author: Leandro Leite Pinto de Oliveira <lleitep3 at gmail dot com>
 */

(function($){

    $.fn.maxLengthBox = function( options ){

        // Confs
        var conf = {
            'fontColor'      : '#ccc',
            'fontColorFinal' : '#DD0000',
            'definedColor'   : '#ccc',
            'fontSize'       : '0.8em',

            style : function () {
                return 'font-size:' + this.fontSize     + ';'
                + 'color:'      + this.definedColor + ';'
                + 'position:'   + 'absolute'        + ';'
            ;
            }
        }

        // methods of plugin
        var methods = {

            // initialize plugin
            init : function(el){
                el.delegate('focus',function(){
                    methods.exec($(this));
                });

                el.delegate('keyup',function(){
                    methods.exec($(this));
                });

                if( options )
                    $.extend( conf, options );
            },
            // execute function of plugin
            exec : function (el){
                $('#maxLengthBox').remove();
                var val = el.attr('maxlength') - el.val().length;
                this.showBox(el,val);
            },

            setFontColor : function (val){
                conf.definedColor =
                (val == 0)? conf.fontColorFinal : conf.fontColor;
            },

            // create MaxLengthBox
            showBox : function (el, val){
                var offset = el.offset();

                this.setFontColor(val);

                $('body').append('
'+val+'
');

                offset.left += el.width()  - $('#maxLengthBox').width();
                offset.top  += el.height() - $('#maxLengthBox').height() + 5;

                $('#maxLengthBox').css('left',(offset.left+'px'));
                $('#maxLengthBox').css('top',(offset.top+'px'));
            }
        }

        // start plugin
        methods.init($(this));

    }

})(jQuery);
<|endoftext|>


<commit_before>// see: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries

// external imports
import MediaQuery from 'mediaquery'
// local imports
import calculateResponsiveState from '../actions/creators/calculateResponsiveState'

// this function adds event handlers to the window that only tirgger
// when the responsive state changes
export default ({store, window, calculateStateInitially}) => {
    // the function to call when calculating the new responsive state
    function refreshResponsiveState() {
        store.dispatch(calculateResponsiveState(window))
    }

    // grab the current state of the store
    const storeState = store.getState()

    // go through every reducer at the root of the project
    const responsiveReducer = Object.keys(storeState).reduce((prev, current) => (
        // if the reducer contains the responsive state marker then keep it
        storeState[current]._responsiveState ? current : prev
    // otherwise the value should be at least falsey
    ), false)

    // if we couldn't find a responsive reducer at the root of the project
    if (!responsiveReducer) {
        throw new Error(
            'Could not find responsive state reducer - Performance mode can only '
            + 'be used if the responsive reducer is at the root of your reducer tree.'
        )
    }

    // get the object of breakpoints
    const breakpoints = storeState[responsiveReducer].breakpoints
    // get the object of media queries
    const mediaQueries = MediaQuery.asObject(breakpoints)

    // for every breakpoint range
    Object.keys(mediaQueries).forEach(breakpoint => {
        // create a media query list for the breakpoint
        const mediaQueryList = window.matchMedia(mediaQueries[breakpoint])

        /* eslint-disable no-loop-func */

        // whenever any of the media query lists status changes
        mediaQueryList.addListener((query) => {
            // if a new query was matched
            if (query.matches) {
                // recaulate the state
                refreshResponsiveState()
            }
        })

    })

    // if we are supposed to calculate the initial state
    if (calculateStateInitially) {
        // then do so
        refreshResponsiveState()
    }
}
<commit_msg>safety check for null props<commit_after>// see: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries

// external imports
import MediaQuery from 'mediaquery'
// local imports
import calculateResponsiveState from '../actions/creators/calculateResponsiveState'

// this function adds event handlers to the window that only tirgger
// when the responsive state changes
export default ({store, window, calculateStateInitially}) => {
    // the function to call when calculating the new responsive state
    function refreshResponsiveState() {
        store.dispatch(calculateResponsiveState(window))
    }

    // grab the current state of the store
    const storeState = store.getState()

    // go through every reducer at the root of the project
    const responsiveReducer = Object.keys(storeState).reduce((prev, current) => (
        // if the reducer contains the responsive state marker then keep it
        storeState[current] && storeState[current]._responsiveState ? current : prev
    // otherwise the value should be at least falsey
    ), false)

    // if we couldn't find a responsive reducer at the root of the project
    if (!responsiveReducer) {
        throw new Error(
            'Could not find responsive state reducer - Performance mode can only '
            + 'be used if the responsive reducer is at the root of your reducer tree.'
        )
    }

    // get the object of breakpoints
    const breakpoints = storeState[responsiveReducer].breakpoints
    // get the object of media queries
    const mediaQueries = MediaQuery.asObject(breakpoints)

    // for every breakpoint range
    Object.keys(mediaQueries).forEach(breakpoint => {
        // create a media query list for the breakpoint
        const mediaQueryList = window.matchMedia(mediaQueries[breakpoint])

        /* eslint-disable no-loop-func */

        // whenever any of the media query lists status changes
        mediaQueryList.addListener((query) => {
            // if a new query was matched
            if (query.matches) {
                // recaulate the state
                refreshResponsiveState()
            }
        })

    })

    // if we are supposed to calculate the initial state
    if (calculateStateInitially) {
        // then do so
        refreshResponsiveState()
    }
}
<|endoftext|>


<commit_before>window.FormValidator = function(jqSelector, defaultReturnValue, onPassFn)
{
		var form = this;
		form._selector = jqSelector;
		form._watches = new Array();

		form._onAllIsGood = function()
		{

		};
		if(typeof(onPassFn) == "function")
		{
			form._onAllIsGood = onPassFn;
		}
		form._defaultReturnValue = true;
		if(typeof(defaultReturnValue) == "boolean")
		{
			form._defaultReturnValue = defaultReturnValue;
		}
}
window.FormValidator.prototype.ensure = function(jqChildElement, fn, errorMsg, onError)
{
		var form = this;
		if(!jqChildElement)
		{
			throw "argument one is expecting a jquery Element to be passed";
		}
		if(!fn)
		{
			throw "argument two should be a function that returns true or false";
		}
		//if(!errorMsg && !onError)
		//{
		//	throw "argument three needs to be an error message, or...argument three may be an empty string if a fourth argument is passed as a callback function when argument two returns false";
		//}
		form._watches.push(
		{
			selector: jqChildElement,
			validationFn: fn,
			errorMsg: errorMsg,
			errorFn: onError,
			async: false
		});
}
window.FormValidator.prototype.ensureAsync = function(jqChildElement, dataFn, responseValidationFn, url, method, errorMsg, onError)
{
		var form = this;
		var els = $(form._selector).find(jqChildElement);
		var resultss = [];
		els.each(function(idx, Elm)
		{
			resultss.push("pending");
		});
		form._watches.push(
		{
			selector: jqChildElement,
			dataFn: dataFn,
			responseFn: responseValidationFn,
			url: url,
			method: method,
			errorMsg: errorMsg,
			errorFn: onError,
			async: true,
			results: resultss
		});
}
window.FormValidator.prototype._checkResults = function()
{
	var form = this;
	$(".formvalidation_error").each(function(idx, Elm)
	{
		$(Elm).removeClass("form_validation_error");
		$(Elm).blur(function(idx2, Elm2)
		{
			$(Elm2).removeClass("form_validation_error");
		});
	});
	$(".formvalidation_message").each(function(i, e){$(e).detach();});
	for(var i = 0; i < form._watches.length; i++)
	{
		var results = new Array();
		for(var k = 0; k < $(form._selector).find(form._watches[i]["selector"]).size(); k++)
		{
			if(!form._watches[i]["async"])
			{
				results.push(form._watches[i].validationFn($(form._selector).find(form._watches[i]["selector"]).eq(k)));
			}
		    else
		    {
		    	//console.log(form._watches[i]);
		    	if(form._watches[i].results[k] == "pending")
		    	{
		    		var key_vals = form._watches[i].dataFn($(form._selector).find(form._watches[i]["selector"]).eq(k));
		    		if(form._watches[i]["method"] == "GET")
		    		{
		    			var url = form._watches[i]["url"];
						var do_qmark = true;
		    			for(var key in key_vals)
		    			{
		    				if(do_qmark)
		    				{
		    					url += "?";
		    				}
		    				else
		    				{
		    					url += "&";
		    				}
		    				do_qmark = false;
		    				url += key + "=" + encodeURIComponent(key_vals[key]);
		    			}
		    			$.get(url).done(function(d)
		    			{
		    				form._watches[i]["results"][k] = form._watches[i].responseFn(d, $(form._selector).find(form._watches[i]["selector"]).eq(k));
		    				$(form._selector).eq(0).submit();
		    			});
					return false;
		    		}
		    		else if(form._watches[i]["method"] == "POST")
		    		{
		    			$.post(url, key_vals).done(function(d)
		    			{
		    				form._watches[i]["results"][k] = form._watches[i].responseFn(d, $(form._selector).find(form._watches[i]["selector"]).eq(k));
		    				$(form._selector).eq(0).submit();
		    			});
					return false;
		    		}

		    	}
		    	else
		    	{
		    		results.push(form._watches[i]["results"][k]);
		    	}
		    }
		}
		var do_custom_callback = (((form._watches[i].errorMsg === "") || (!form._watches[i].errorMsg)) && (typeof(form._watches[i].errorFn) != "undefined"))
		for(var k = 0; k < results.length; k++)
		{
			if(!results[k])
			{
				$(form._selector).find(form._watches[i]["selector"]).eq(k).addClass("formvalidation_error");
				if(do_custom_callback)
				{
					form._watches[i].errorFn();
					return false;
				}
				else
				{
					var off = $(".formvalidation_error").eq(0).offset();
					var ll = off.left;
					var tt = off.top;

					var width = $(".formvalidation_error").eq(0).width();
					var h = $(".formvalidation_error").eq(0).height();

					ll += '';
					tt += '';
					width += '';
					h += '';

					ll = ll.replace("px", "");
					tt = tt.replace("px", "");
					width = width.replace("px", "");
					h = h.replace("px", "");

					ll *= 1.0;
					tt *= 1.0;
					width *= 1.0;
					h *= 1.0;

					ll = parseInt(ll);
					tt = parseInt(tt);
					width = parseInt(width);
					h = parseInt(h);

					var msg = $("

");
					msg.text(form._watches[i]["errorMsg"]);
					msg.addClass("formvalidation_message");
					msg.css("position", "absolute")
						.css("display", "block")
						.css("left", ((ll + '') + 'px'))
						.css("top", ((tt + '') + 'px'))
						.css("min-height", ((h + '') + 'px'))
						.css("width", ((width + '') + 'px')).appendTo("body");
					msg.click(function()
					{
						msg.detach();
					});
				}

				try
				{
					$(form._selector).find(form._watches[i]["selector"]).eq(k)[0].focus();
				}
				catch(e2)
				{
					var h = $(window).height();
					h = h + '';
					h = h.replace("px", "");
					h = h + 0;
					h = parseInt(h);

					var ot = $(form._selector).find(form._watches[i]["selector"]).eq(k).offset().top;
					ot = ot + '';
					ot = ot.replace("px", "");
					ot = ot + 0;
					ot = parseInt(ot);
					if(ot > h)
					{
						$(window).scrollTop(ot - h);

					}
				}
				return false;
			}
		}
	}
	form._onAllIsGood();
	return form._defaultReturnValue;
}
window.FormValidator.prototype.watch = function()
{
		var form = this;
		$(form._selector).submit(function()
		{
			return form._checkResults();
		});
}
<commit_msg>Fixed bug where async validation would only validate as true the first-time around and would hang if a second attempt to submit the form with valid data was made.<commit_after>window.FormValidator = function(jqSelector, defaultReturnValue, onPassFn)
{
		var form = this;
		form._selector = jqSelector;
		form._watches = new Array();

		form._onAllIsGood = function()
		{

		};
		if(typeof(onPassFn) == "function")
		{
			form._onAllIsGood = onPassFn;
		}
		form._defaultReturnValue = true;
		if(typeof(defaultReturnValue) == "boolean")
		{
			form._defaultReturnValue = defaultReturnValue;
		}
}
window.FormValidator.prototype.ensure = function(jqChildElement, fn, errorMsg, onError)
{
		var form = this;
		if(!jqChildElement)
		{
			throw "argument one is expecting a jquery Element to be passed";
		}
		if(!fn)
		{
			throw "argument two should be a function that returns true or false";
		}
		//if(!errorMsg && !onError)
		//{
		//	throw "argument three needs to be an error message, or...argument three may be an empty string if a fourth argument is passed as a callback function when argument two returns false";
		//}
		form._watches.push(
		{
			selector: jqChildElement,
			validationFn: fn,
			errorMsg: errorMsg,
			errorFn: onError,
			async: false
		});
}
window.FormValidator.prototype.ensureAsync = function(jqChildElement, dataFn, responseValidationFn, url, method, errorMsg, onError)
{
		var form = this;
		var els = $(form._selector).find(jqChildElement);
		var resultss = [];
		els.each(function(idx, Elm)
		{
			resultss.push("pending");
		});
		form._watches.push(
		{
			selector: jqChildElement,
			dataFn: dataFn,
			responseFn: responseValidationFn,
			url: url,
			method: method,
			errorMsg: errorMsg,
			errorFn: onError,
			async: true,
			results: resultss
		});
}
window.FormValidator.prototype._checkResults = function()
{
	var form = this;
	$(".formvalidation_error").each(function(idx, Elm)
	{
		$(Elm).removeClass("form_validation_error");
		$(Elm).blur(function(idx2, Elm2)
		{
			$(Elm2).removeClass("form_validation_error");
		});
	});
	$(".formvalidation_message").each(function(i, e){$(e).detach();});
	for(var i = 0; i < form._watches.length; i++)
	{
		var results = new Array();
		for(var k = 0; k < $(form._selector).find(form._watches[i]["selector"]).size(); k++)
		{
			if(!form._watches[i]["async"])
			{
				results.push(form._watches[i].validationFn($(form._selector).find(form._watches[i]["selector"]).eq(k)));
			}
		    else
		    {
		    	//console.log(form._watches[i]);
		    	if(form._watches[i].results[k] == "pending")
		    	{
		    		var key_vals = form._watches[i].dataFn($(form._selector).find(form._watches[i]["selector"]).eq(k));
		    		if(form._watches[i]["method"] == "GET")
		    		{
		    			var url = form._watches[i]["url"];
						var do_qmark = true;
		    			for(var key in key_vals)
		    			{
		    				if(do_qmark)
		    				{
		    					url += "?";
		    				}
		    				else
		    				{
		    					url += "&";
		    				}
		    				do_qmark = false;
		    				url += key + "=" + encodeURIComponent(key_vals[key]);
		    			}
		    			$.get(url).done(function(d)
		    			{
		    				form._watches[i]["results"][k] = form._watches[i].responseFn(d, $(form._selector).find(form._watches[i]["selector"]).eq(k));
		    				$(form._selector).eq(0).submit();
							setTimeout(function()
							{
								form._watches[i]["results"][k] = "pending";
							}, 100);
		    			});
					return false;
		    		}
		    		else if(form._watches[i]["method"] == "POST")
		    		{
		    			$.post(url, key_vals).done(function(d)
		    			{
		    				form._watches[i]["results"][k] = form._watches[i].responseFn(d, $(form._selector).find(form._watches[i]["selector"]).eq(k));
		    				$(form._selector).eq(0).submit();
							setTimeout(function()
							{
								form._watches[i]["results"][k] = "pending";
							}, 100);

		    			});
					return false;
		    		}

		    	}
		    	else
		    	{
		    		results.push(form._watches[i]["results"][k]);
		    	}
		    }
		}
		var do_custom_callback = (((form._watches[i].errorMsg === "") || (!form._watches[i].errorMsg)) && (typeof(form._watches[i].errorFn) != "undefined"))
		for(var k = 0; k < results.length; k++)
		{
			if(!results[k])
			{
				$(form._selector).find(form._watches[i]["selector"]).eq(k).addClass("formvalidation_error");
				if(do_custom_callback)
				{
					form._watches[i].errorFn();
					return false;
				}
				else
				{
					var off = $(".formvalidation_error").eq(0).offset();
					var ll = off.left;
					var tt = off.top;

					var width = $(".formvalidation_error").eq(0).width();
					var h = $(".formvalidation_error").eq(0).height();

					ll += '';
					tt += '';
					width += '';
					h += '';

					ll = ll.replace("px", "");
					tt = tt.replace("px", "");
					width = width.replace("px", "");
					h = h.replace("px", "");

					ll *= 1.0;
					tt *= 1.0;
					width *= 1.0;
					h *= 1.0;

					ll = parseInt(ll);
					tt = parseInt(tt);
					width = parseInt(width);
					h = parseInt(h);

					var msg = $("

");
					msg.text(form._watches[i]["errorMsg"]);
					msg.addClass("formvalidation_message");
					msg.css("position", "absolute")
						.css("display", "block")
						.css("left", ((ll + '') + 'px'))
						.css("top", ((tt + '') + 'px'))
						.css("min-height", ((h + '') + 'px'))
						.css("width", ((width + '') + 'px')).appendTo("body");
					msg.click(function()
					{
						msg.detach();
					});
				}

				try
				{
					$(form._selector).find(form._watches[i]["selector"]).eq(k)[0].focus();
				}
				catch(e2)
				{
					var h = $(window).height();
					h = h + '';
					h = h.replace("px", "");
					h = h + 0;
					h = parseInt(h);

					var ot = $(form._selector).find(form._watches[i]["selector"]).eq(k).offset().top;
					ot = ot + '';
					ot = ot.replace("px", "");
					ot = ot + 0;
					ot = parseInt(ot);
					if(ot > h)
					{
						$(window).scrollTop(ot - h);

					}
				}
				return false;
			}
		}
	}
	form._onAllIsGood();
	return form._defaultReturnValue;
}
window.FormValidator.prototype.watch = function()
{
		var form = this;
		$(form._selector).submit(function()
		{
			return form._checkResults();
		});
}
<|endoftext|>


<commit_before>let respondsTo = require('../respondsTo')

describe('Utils - respondsTo', function() {

  it ('returns true when a key is a function', function() {
    respondsTo({ test(){} }, 'test').should.equal(true)
  })

  it ('returns true when a key is not a function', function() {
    respondsTo({ test(){} }, 'nope').should.equal(false)
  })

  it ('returns false if the target is null', function() {
    respondsTo(null, 'test').should.equal(false)
  })

  it ('returns false if the target is undefined', function() {
    respondsTo(undefined, 'test').should.equal(false)
  })

})
<commit_msg>[fix] Description of test in respondsTo<commit_after>let respondsTo = require('../respondsTo')

describe('Utils - respondsTo', function() {

  it ('returns true when a key is a function', function() {
    respondsTo({ test(){} }, 'test').should.equal(true)
  })

  it ('returns false when a key is not a function', function() {
    respondsTo({ test(){} }, 'nope').should.equal(false)
  })

  it ('returns false if the target is null', function() {
    respondsTo(null, 'test').should.equal(false)
  })

  it ('returns false if the target is undefined', function() {
    respondsTo(undefined, 'test').should.equal(false)
  })

})
<|endoftext|>


<commit_before>/*globals exports */

'use strict';

exports.format = format;

function format (reports) {
    var formatted = '# Complexity report ~ ' + (new Date()).toLocaleDateString() + '\n\n', i;

    for (i = 0; i < reports.length; i += 1) {
        formatted += formatModule(reports[i]) + '\n\n';
    }

    return formatted;
}

function formatModule (report) {
    return [
        '##',
        report.module,
        '\n\n',
        '* Maintainability index: ', report.maintainability, '\n',
        '* Aggregate cyclomatic complexity: ', report.aggregate.complexity.cyclomatic,
        formatFunctions(report.functions)
    ].join('');
}

function formatFunctions (report) {
    var formatted = '', i;

    for (i = 0; i < report.length; i += 1) {
        formatted += '\n\n' + formatFunction(report[i]);
    }

    return formatted;
}

function formatFunction (report) {
    return [
        '    * Function: **', report.name, '**\n',
        '        * Line No.: ', report.line, '\n',
        '        * Physical SLOC: ', report.complexity.sloc.physical, '\n',
        '        * Logical SLOC: ', report.complexity.sloc.logical, '\n',
        '        * Cyclomatic complexity: ', report.complexity.cyclomatic, '\n',
        '        * Halstead difficulty: ', report.complexity.halstead.difficulty, '\n',
        '        * Halstead volume: ', report.complexity.halstead.volume, '\n',
        '        * Halstead effort: ', report.complexity.halstead.effort
    ].join('');
}

<commit_msg>Tweak markdown format.<commit_after>/*globals exports */

'use strict';

exports.format = format;

function format (reports) {
    var formatted = '# Complexity report ~ ' + (new Date()).toLocaleDateString() + '\n\n', i;

    for (i = 0; i < reports.length; i += 1) {
        formatted += formatModule(reports[i]) + '\n\n';
    }

    return formatted;
}

function formatModule (report) {
    return [
        '##',
        report.module,
        '\n\n',
        '* Maintainability index: ', report.maintainability, '\n\n',
        '* Aggregate cyclomatic complexity: ', report.aggregate.complexity.cyclomatic,
        formatFunctions(report.functions)
    ].join('');
}

function formatFunctions (report) {
    var formatted = '', i;

    for (i = 0; i < report.length; i += 1) {
        formatted += '\n\n' + formatFunction(report[i]);
    }

    return formatted;
}

function formatFunction (report) {
    return [
        '    * Function: **', report.name.replace('<', '<'), '**\n\n',
        '        * Line No.: ', report.line, '\n',
        '        * Physical SLOC: ', report.complexity.sloc.physical, '\n',
        '        * Logical SLOC: ', report.complexity.sloc.logical, '\n',
        '        * Cyclomatic complexity: ', report.complexity.cyclomatic, '\n',
        '        * Halstead difficulty: ', report.complexity.halstead.difficulty, '\n',
        '        * Halstead volume: ', report.complexity.halstead.volume, '\n',
        '        * Halstead effort: ', report.complexity.halstead.effort
    ].join('');
}

<|endoftext|>


<commit_before>/* NODE MODULES */
var eventerface = require('eventerface');

/** MODULE INTERFACE
 *@method {function} -
 */
module.exports = {
    createChannel: createChannel
};

/*----------------------------------------------------------------------------*/

/** Creates a channel between the zone and a neighboring zone
 * @param {object} localSide -
 * @param {object} remoteSide -
 * @returns
 */
function createChannel(zone, zoneNamespace, local, remote) {
    eventerface.create('channel://' + local.port, function (neighbor) {
        console.log('Channel created on port ' + local.port);
        neighbor.connect(remote.host + ':' + remote.port, function () {
            console.log('Connected to neighbor on ' + remote.port);
            neighbor.emit('ping', 'pong');
        });
        neighbor.on('ping', function (message) {
            console.log('Ping from ' + remote.port + ': ' + message);
        });
    });
}<commit_msg>Attached the #emit and #on channel methods to each neighbor<commit_after>/* NODE MODULES */
var eventerface = require('eventerface');

/** MODULE INTERFACE
 *@method {function} -
 */
module.exports = {
    createChannel: createChannel
};

/*----------------------------------------------------------------------------*/

/** Creates a channel between the zone and a neighboring zone
 * @param {object} zone - The zone requesting the servers to be created
 * @param {object} globalNamespace - The global namespace where the other zone components will emit events
 * @param {object} side - The side of the zone where the channel will be created
 * @param {object} channelOptions - Host and port of the local and remote sides of the channel
 * @returns
 */
function createChannel(zone, zoneNamespace, side, channelOptions) {
    eventerface.create('channel://' + channelOptions.local.port, function (neighbor) {
        console.log('Channel created on port ' + channelOptions.local.port);
        zone._neighbors[side].emit = neighbor.emit;
        zone._neighbors[side].on = neighbor.on;

        neighbor.connect(channelOptions.remote.host + ':' + channelOptions.remote.port, function () {
            console.log('Connected to neighbor on ' + channelOptions.remote.port);
            neighbor.emit('ping', 'pong');
        });
        neighbor.on('ping', function (message) {
            console.log('Ping from ' + channelOptions.remote.port + ': ' + message);
        });
    });
}<|endoftext|>


<commit_before>const config = require('./config/config.json')

describe('provider testing', () => {
  const { VerifierV3 } = require('@pact-foundation/pact/v3')
  const chai = require('chai')
  const chaiAsPromised = require('chai-as-promised')
  const path = require('path')
  const fetch = require('sync-fetch')

  const {
    validAdminAuthHeaders
  } = require('./pactHelper.js')

  const {
    createFolderRecrusive,
    createFile,
    deleteItem
  } = require('./webdavHelper.js')

  chai.use(chaiAsPromised)

  it('verifies the provider', () => {
    const opts = {
      provider: 'oc-server',
      logLevel: 'debug',
      providerBaseUrl: process.env.PROVIDER_BASE_URL || 'http://localhost/',
      disableSSLVerification: true
    }
    if (process.env.CI === 'true') {
      opts.pactBrokerUrl = 'https://jankaritech.pactflow.io'
      opts.publishVerificationResult = true
      opts.pactBrokerToken = process.env.PACTFLOW_TOKEN
      opts.enablePending = true
      opts.consumerVersionSelectors = [
        {
          tag: process.env.DRONE_SOURCE_BRANCH,
          latest: true
        }
      ]
      opts.providerVersion = process.env.PROVIDER_VERSION
    } else {
      opts.pactUrls = [path.resolve(process.cwd(), 'tests', 'pacts', 'owncloud-sdk-oc-server.json')]
    }

    opts.stateHandlers = {
      'group exists': (setup, parameters) => {
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups', {
            method: 'POST',
            body: 'groupid=' + parameters.groupName,
            headers: {
              ...validAdminAuthHeaders,
              ...{ 'Content-Type': 'application/x-www-form-urlencoded' }
            }
          })
          return Promise.resolve({ description: 'group added' })
        } else {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          return Promise.resolve({ description: 'group deleted' })
        }
      },
      'group does not exist': (setup, parameters) => {
        fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
          method: 'DELETE',
          headers: validAdminAuthHeaders
        })
        return Promise.resolve({ description: 'group deleted' })
      },
      'folder exists': (setup, parameters) => {
        if (setup) {
          const results = createFolderRecrusive(
            parameters.username, parameters.password, parameters.folderName
          )
          chai.assert.isBelow(
            results[0].status, 300, `creating folder '${parameters.folderName}' failed`
          )
        }
        return Promise.resolve({ description: 'folder created' })
      },
      'file exists': (setup, parameters) => {
        const dirname = path.dirname(parameters.fileName)
        if (setup) {
          if (dirname !== '' && dirname !== '/') {
            const results = createFolderRecrusive(
              parameters.username, parameters.password, dirname
            )
            for (let i = 0; i < results.length; i++) {
              chai.assert.isBelow(
                results[i].status, 300, `creating folder '${dirname}' failed'`
              )
            }
          }
          const result = createFile(
            parameters.username, parameters.password, parameters.fileName, config.testContent
          )
          chai.assert.isBelow(
            result.status, 300, `creating file '${parameters.fileName}' failed`
          )
        } else {
          let itemToDelete
          if (dirname !== '' && dirname !== '/') {
            const folders = dirname.split(path.sep)
            itemToDelete = folders[0]
          } else {
            itemToDelete = parameters.fileName
          }
          const result = deleteItem(
            parameters.username, parameters.password, itemToDelete
          )
          chai.assert.strictEqual(
            result.status, 204, `deleting '${itemToDelete}' failed`
          )
        }
        return Promise.resolve({ description: 'file created' })
      }
    }
    return new VerifierV3(opts).verifyProvider().then(output => {
      console.log('Pact Verification Complete!')
      console.log('Result:', output)
    }).catch(function (error) {
      chai.assert.fail(error.message)
    })
  }, 60000)
})
<commit_msg>recreate user provider state<commit_after>const config = require('./config/config.json')

describe('provider testing', () => {
  const { VerifierV3 } = require('@pact-foundation/pact/v3')
  const chai = require('chai')
  const chaiAsPromised = require('chai-as-promised')
  const path = require('path')
  const fetch = require('sync-fetch')

  const {
    validAdminAuthHeaders
  } = require('./pactHelper.js')

  const {
    createFolderRecrusive,
    createFile,
    deleteItem
  } = require('./webdavHelper.js')

  chai.use(chaiAsPromised)

  it('verifies the provider', () => {
    const opts = {
      provider: 'oc-server',
      logLevel: 'debug',
      providerBaseUrl: process.env.PROVIDER_BASE_URL || 'http://localhost/',
      disableSSLVerification: true
    }
    if (process.env.CI === 'true') {
      opts.pactBrokerUrl = 'https://jankaritech.pactflow.io'
      opts.publishVerificationResult = true
      opts.pactBrokerToken = process.env.PACTFLOW_TOKEN
      opts.enablePending = true
      opts.consumerVersionSelectors = [
        {
          tag: process.env.DRONE_SOURCE_BRANCH,
          latest: true
        }
      ]
      opts.providerVersion = process.env.PROVIDER_VERSION
    } else {
      opts.pactUrls = [path.resolve(process.cwd(), 'tests', 'pacts', 'owncloud-sdk-oc-server.json')]
    }

    opts.stateHandlers = {
      'group exists': (setup, parameters) => {
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups', {
            method: 'POST',
            body: 'groupid=' + parameters.groupName,
            headers: {
              ...validAdminAuthHeaders,
              ...{ 'Content-Type': 'application/x-www-form-urlencoded' }
            }
          })
          return Promise.resolve({ description: 'group added' })
        } else {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          return Promise.resolve({ description: 'group deleted' })
        }
      },
      'group does not exist': (setup, parameters) => {
        fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
          method: 'DELETE',
          headers: validAdminAuthHeaders
        })
        return Promise.resolve({ description: 'group deleted' })
      },
      'folder exists': (setup, parameters) => {
        if (setup) {
          const results = createFolderRecrusive(
            parameters.username, parameters.password, parameters.folderName
          )
          chai.assert.isBelow(
            results[0].status, 300, `creating folder '${parameters.folderName}' failed`
          )
        }
        return Promise.resolve({ description: 'folder created' })
      },
      'file exists': (setup, parameters) => {
        const dirname = path.dirname(parameters.fileName)
        if (setup) {
          if (dirname !== '' && dirname !== '/') {
            const results = createFolderRecrusive(
              parameters.username, parameters.password, dirname
            )
            for (let i = 0; i < results.length; i++) {
              chai.assert.isBelow(
                results[i].status, 300, `creating folder '${dirname}' failed'`
              )
            }
          }
          const result = createFile(
            parameters.username, parameters.password, parameters.fileName, config.testContent
          )
          chai.assert.isBelow(
            result.status, 300, `creating file '${parameters.fileName}' failed`
          )
        } else {
          let itemToDelete
          if (dirname !== '' && dirname !== '/') {
            const folders = dirname.split(path.sep)
            itemToDelete = folders[0]
          } else {
            itemToDelete = parameters.fileName
          }
          const result = deleteItem(
            parameters.username, parameters.password, itemToDelete
          )
          chai.assert.strictEqual(
            result.status, 204, `deleting '${itemToDelete}' failed`
          )
        }
        return Promise.resolve({ description: 'file created' })
      },
      'the user is recreated': (setup, parameters) => {
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users/' + parameters.username, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          const result = fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users',
            {
              method: 'POST',
              body: `userid=${parameters.username}&password=${parameters.username}`,
              headers: {
                ...validAdminAuthHeaders,
                ...{ 'Content-Type': 'application/x-www-form-urlencoded' }
              }
            })
          chai.assert.strictEqual(
            result.status, 200, `creating user '${parameters.username}' failed`
          )
          return Promise.resolve({ description: 'user created' })
        }
      }
    }
    return new VerifierV3(opts).verifyProvider().then(output => {
      console.log('Pact Verification Complete!')
      console.log('Result:', output)
    }).catch(function (error) {
      chai.assert.fail(error.message)
    })
  }, 60000)
})
<|endoftext|>


<commit_before>/**
 * @name index.js<lib/fsys>
 * @author Kei Funagayama <funagayama_kei@cyberagent.co.jp>
 * copyright (c) Cyberagent Inc.
 * @overview fsys library
 */

var fs = require('fs');
var path = require('path');
var util = require('util');

var _  =  require('lodash');
var mkdirp = require('mkdirp');
var jsonminify = require('jsonminify');
var jsonlint = require('jsonlint');

var store = require('./store');
var Checker = require('./checker');

/**
 * @name fsys
 * @namespace fsys
 */
module.exports = {

    /**
     * store library
     * @name store
     * @memberof fsys
     */
    store: store,

    /**
     * checker library
     * @name checker
     * @memberof fsys
     */
    Checker: Checker,

    /**
     * file type
     * @name TYPE
     * @memberof fsys
     */
    TYPE: {
        FILE: 'file',
        DIRECTORY: 'directory',
        BLOCK_DEVICE: 'block',
        CHARACTER_DEVICE: 'character',
        SYMLINK: 'symlink',
        FIFO: 'fifo',
        SOCKET: 'socket'
    },

    /**
     * @name isFileSync
     * @memberof fsys
     * @method
     * @param {String} p target file path
     * @return {boolean}
     */
    isFileSync: function (p) {
        if (!fs.existsSync(p)) {
            return false;
        }
        var stats = fs.statSync(p);
        return stats.isFile();
    },

    /**
     * @name isDirectorySync
     * @memberof fsys
     * @method
     * @param {String} p target directory path
     * @return {boolean}
     */
    isDirectorySync: function (p) {
        if (!fs.existsSync(p)) {
            return false;
        }
        var stats = fs.statSync(p);
        return stats.isDirectory();
    },

    /**
     * @name typeSync
     * @memberof fsys
     * @method
     * @param {String} p target path
     * @return {String} this.TYPES
     */
    typeSync: function (p) {
        if (!fs.existsSync(p)) {
            return undefined;
        }
        var TYPE = this.TYPE;
        var stats = fs.statSync(p);

        if (stats.isDirectory()) {
            return TYPE.DIRECTORY;
        } else if (stats.isFile()) {
            return TYPE.FILE;
        } else if (stats.isBlockDevice()) {
            return TYPE.BLOCK_DEVICE;
        } else if (stats.isCharacterDevice()) {
            return TYPE.CHARACTER_DEVICE;
        } else if (stats.isSymbolicLink()) {
            return TYPE.SYMLINK;
        } else if (stats.isFIFO()) {
            return TYPE.FIFO;
        } else if (stats.isSocket()) {
            return TYPE.SOCKET;
        } else {
            return undefined;
        }
    },

    /**
     * bash: $ rm -rf <path>
     *
     * @name typeSync
     * @param {String} p delete path
     * @param {String} f path.resolve#from
     * @memberof fsys
     * @method
     */
    rmrfSync: function (p, f) {
        var self = this;
        f = f || '';
        p = path.resolve(f, path.normalize(p));
        if (this.typeSync(p) === this.TYPE.DIRECTORY) {
            _.each(fs.readdirSync(p), function(f) {
                self.rmrfSync(path.join(p, f));
            });
            return fs.rmdirSync(p);
        }
        return fs.unlinkSync(p);
    },

    /**
     * bash: $ mkdir -p <path> (async)
     *
     * @name mkdirp
     * @memberof fsys
     * @method
     * @see https://npmjs.org/package/mkdirp
     */
    mkdirp: mkdirp,
    /**
     * bash: $ mkdir -p <path> (sync)
     *
     * @name mkdirpSync
     * @memberof fsys
     * @method
     * @see https://npmjs.org/package/mkdirp
     */
    mkdirpSync: mkdirp.sync,

    /**
     * file system walk function
     *
     * @name walk
     * @memberof fsys
     * @method
     * @param {String} basedir base path
     * @param {function} filefn Function to be executed when the file is found
     * @param {function} dirfnFunction to be executed when the directory is found
     *
     */
    walk: function (basedir, filefn, dirfn) {
        filefn = filefn || function() {};
        dirfn = dirfn || function() {};

        var readdirSync = function(dir) {
            var files = fs.readdirSync(dir);

            for (var i = 0; i < files.length; i++) {
                var file = dir+'/'+files[i];
                //debug('before fs.statsSync:', file);
                var stats = fs.statSync(file);

                if (stats.isFile()) {
                var prefix = dir.replace(basedir, '');
                    filefn(prefix, dir, files[i], stats);

                } else if (stats.isDirectory()) {
                    var prefix = file.replace(basedir, '');
                    dirfn(prefix, stats);
                    readdirSync(file);

                } else {
                    console.error('error:'.error, 'It is a file type that is not assumed. file:', file);
                    return;
                }
            }
        };
        readdirSync(basedir);
    },

    /**
     * Read file Sync(json format)
     *
     * @name readJsonSync
     * @memberof fsys
     * @method
     * @param {String} path read file path
     * @param {boolean} minify use jsonminify
     * @param {String} encode file read encode
     */
    readJsonSync: function (path, minify, encode) {
        minify = minify || false;
        encode = encode || 'utf-8';

        if (this.isFileSync(path)) {
            var raw = fs.readFileSync(path, encode);
            if (minify) {
                raw = jsonminify(raw);
            }

            try {
                return JSON.parse(raw);
            } catch (e1) {
                try {
                    jsonlint.parse(raw);
                } catch (e2) {
                    throw e2;
                }
            }
        }
        return {};
    },

    /**
     * JS設定ファイルからJSONデータを読み込む
     *
     * @name readFileFnJSONSync
     * @memberof fsys
     * @method
     * @param {String} path load file path
     * @param {String} encode file encode
     * @return {Object} load json data
     */
    readFileFnJSONSync: function (path, encode) {
        encode = encode || 'utf-8';

        if (this.isFileSync(path)) {
            var raw = fs.readFileSync(path, encode);

            try {
                var fn = new Function ('process', 'require', '__filename', '__dirname', 'module', 'exports', "return " + raw);
                return fn(process, require, __filename, __dirname, module, exports);
            } catch (e) {
                throw e;
            }
        }
        return {};
    },

    /**
     * change file modes or Access Control Lists
     * bash: $ chmod {mode} {path} ...
     *
     * @name chmodfilesSync
     * @memberof fsys
     * @method
     * @param {Array} list target files
     * @param {int} mode change file mode
     */
    chmodfilesSync: function(list, mode) {
        list = list || [];
        mode = mode || 0755;
        _.find(list, function (p) {
            fs.chmodSync(p, mode);
        });
    },

    /**
     * ファイルをコピーする
     *
     * @name cp
     * @memberof fsys
     * @method
     * @param {String} src コピー元のファイルパス
     * @param {String} dst コピー先のファイルパス
     * @param {function} callback コールバック
     */
    cp: function (src, dst, callback) {
        var srcstream = fs.createReadStream(src);
        var dststream = fs.createWriteStream(dst);

        srcstream.on('error', callback);
        dststream.on('error', callback);
        dststream.on('close', function() {
            return callback && callback();
        });
        srcstream.pipe(dststream);
    },

    /**
     * '~'付きのファイルパスから絶対パスを返却する
     *
     * @name resolveTilde
     * @memberof fsys
     * @method
     * @param {String} str 相対パス
     * @return {String} file path
     */
    resolveTilde: function (str) {
        if (!str) {
            return str;
        }
        if (str.substr(0,1) === '~') {
            str = process.env.HOME + str.substr(1);
        }
        return path.resolve(str);
    },

    /**
     * '~'付きのファイルパスの'~'をパスに置き換えて返却する
     *
     * @name resolveTilde
     * @memberof fsys
     * @method
     * @param {String} str 相対パス
     * @return {String} file path
     */
    pathTilde: function (str) {
        if (str && str.substr(0,1) === '~') {
            return process.env.HOME + str.substr(1);
        }
        return str;
    },

    /**
     * 拡張子が.jsはjavascript で、.jsonはJSON.parseでファイルをロードして返却します。
     *
     * @name readFileMultiConfigureSync
     * @memberof fsys
     * @method
     * @param {String} path read file path
     * @param {String} encode file read encode
     */
    readFileMultiConfigureSync: function (path, encode) {
        if (/.json$/.test(path)) {
            return this.readJsonSync(path, true, this.encode);
        } else if (/.js$/.test(path)) {
            return this.readFileFnJSONSync(path, this.encode);
        } else {
            throw new Error('Extension, please specify the ".json" or ".js".');
        }
    }

};
<commit_msg>Update: use the `vm.runInNewContext` from `new Function` in fsys.readFileFnJSONSync<commit_after>/**
 * @name index.js<lib/fsys>
 * @author Kei Funagayama <funagayama_kei@cyberagent.co.jp>
 * copyright (c) Cyberagent Inc.
 * @overview fsys library
 */

var fs = require('fs');
var path = require('path');
var util = require('util');
var vm = require('vm');

var _  =  require('lodash');
var mkdirp = require('mkdirp');
var jsonminify = require('jsonminify');
var jsonlint = require('jsonlint');

var store = require('./store');
var Checker = require('./checker');

/**
 * @name fsys
 * @namespace fsys
 */
module.exports = {

    /**
     * store library
     * @name store
     * @memberof fsys
     */
    store: store,

    /**
     * checker library
     * @name checker
     * @memberof fsys
     */
    Checker: Checker,

    /**
     * file type
     * @name TYPE
     * @memberof fsys
     */
    TYPE: {
        FILE: 'file',
        DIRECTORY: 'directory',
        BLOCK_DEVICE: 'block',
        CHARACTER_DEVICE: 'character',
        SYMLINK: 'symlink',
        FIFO: 'fifo',
        SOCKET: 'socket'
    },

    /**
     * @name isFileSync
     * @memberof fsys
     * @method
     * @param {String} p target file path
     * @return {boolean}
     */
    isFileSync: function (p) {
        if (!fs.existsSync(p)) {
            return false;
        }
        var stats = fs.statSync(p);
        return stats.isFile();
    },

    /**
     * @name isDirectorySync
     * @memberof fsys
     * @method
     * @param {String} p target directory path
     * @return {boolean}
     */
    isDirectorySync: function (p) {
        if (!fs.existsSync(p)) {
            return false;
        }
        var stats = fs.statSync(p);
        return stats.isDirectory();
    },

    /**
     * @name typeSync
     * @memberof fsys
     * @method
     * @param {String} p target path
     * @return {String} this.TYPES
     */
    typeSync: function (p) {
        if (!fs.existsSync(p)) {
            return undefined;
        }
        var TYPE = this.TYPE;
        var stats = fs.statSync(p);

        if (stats.isDirectory()) {
            return TYPE.DIRECTORY;
        } else if (stats.isFile()) {
            return TYPE.FILE;
        } else if (stats.isBlockDevice()) {
            return TYPE.BLOCK_DEVICE;
        } else if (stats.isCharacterDevice()) {
            return TYPE.CHARACTER_DEVICE;
        } else if (stats.isSymbolicLink()) {
            return TYPE.SYMLINK;
        } else if (stats.isFIFO()) {
            return TYPE.FIFO;
        } else if (stats.isSocket()) {
            return TYPE.SOCKET;
        } else {
            return undefined;
        }
    },

    /**
     * bash: $ rm -rf <path>
     *
     * @name typeSync
     * @param {String} p delete path
     * @param {String} f path.resolve#from
     * @memberof fsys
     * @method
     */
    rmrfSync: function (p, f) {
        var self = this;
        f = f || '';
        p = path.resolve(f, path.normalize(p));
        if (this.typeSync(p) === this.TYPE.DIRECTORY) {
            _.each(fs.readdirSync(p), function(f) {
                self.rmrfSync(path.join(p, f));
            });
            return fs.rmdirSync(p);
        }
        return fs.unlinkSync(p);
    },

    /**
     * bash: $ mkdir -p <path> (async)
     *
     * @name mkdirp
     * @memberof fsys
     * @method
     * @see https://npmjs.org/package/mkdirp
     */
    mkdirp: mkdirp,
    /**
     * bash: $ mkdir -p <path> (sync)
     *
     * @name mkdirpSync
     * @memberof fsys
     * @method
     * @see https://npmjs.org/package/mkdirp
     */
    mkdirpSync: mkdirp.sync,

    /**
     * file system walk function
     *
     * @name walk
     * @memberof fsys
     * @method
     * @param {String} basedir base path
     * @param {function} filefn Function to be executed when the file is found
     * @param {function} dirfnFunction to be executed when the directory is found
     *
     */
    walk: function (basedir, filefn, dirfn) {
        filefn = filefn || function() {};
        dirfn = dirfn || function() {};

        var readdirSync = function(dir) {
            var files = fs.readdirSync(dir);

            for (var i = 0; i < files.length; i++) {
                var file = dir+'/'+files[i];
                //debug('before fs.statsSync:', file);
                var stats = fs.statSync(file);

                if (stats.isFile()) {
                var prefix = dir.replace(basedir, '');
                    filefn(prefix, dir, files[i], stats);

                } else if (stats.isDirectory()) {
                    var prefix = file.replace(basedir, '');
                    dirfn(prefix, stats);
                    readdirSync(file);

                } else {
                    console.error('error:'.error, 'It is a file type that is not assumed. file:', file);
                    return;
                }
            }
        };
        readdirSync(basedir);
    },

    /**
     * Read file Sync(json format)
     *
     * @name readJsonSync
     * @memberof fsys
     * @method
     * @param {String} path read file path
     * @param {boolean} minify use jsonminify
     * @param {String} encode file read encode
     */
    readJsonSync: function (path, minify, encode) {
        minify = minify || false;
        encode = encode || 'utf-8';

        if (this.isFileSync(path)) {
            var raw = fs.readFileSync(path, encode);
            if (minify) {
                raw = jsonminify(raw);
            }

            try {
                return JSON.parse(raw);
            } catch (e1) {
                try {
                    jsonlint.parse(raw);
                } catch (e2) {
                    throw e2;
                }
            }
        }
        return {};
    },

    /**
     * JS設定ファイルからJSONデータを読み込む
     *
     * @name readFileFnJSONSync
     * @memberof fsys
     * @method
     * @param {String} filePath load file path
     * @param {String} encode file encode
     * @return {Object} load json data
     */
    readFileFnJSONSync: function (filePath, encode) {
        encode = encode || 'utf-8';

        if (this.isFileSync(filePath)) {
            var raw = fs.readFileSync(filePath, encode);
            var exports = {};
            var context = {
                process: process,
                require: function(name) {
                    var module;
                    try {
                        module = require((function (_module) {
                            if (_module.charAt(0) !== '.') {
                                return _module;
                            }
                            return path.resolve(path.dirname(filePath), _module);
                        }(name)));
                    } catch (e) {
                        throw e;
                    }
                    return module;
                },
                __filename: __filename,
                __dilename: __dirname,
                module: {
                    exports: exports
                },
                exports: exports
            };

            try {
                return vm.runInNewContext(raw, context);
            } catch (e) {
                throw e;
            }
        }
        return {};
    },

    /**
     * change file modes or Access Control Lists
     * bash: $ chmod {mode} {path} ...
     *
     * @name chmodfilesSync
     * @memberof fsys
     * @method
     * @param {Array} list target files
     * @param {int} mode change file mode
     */
    chmodfilesSync: function(list, mode) {
        list = list || [];
        mode = mode || 0755;
        _.find(list, function (p) {
            fs.chmodSync(p, mode);
        });
    },

    /**
     * ファイルをコピーする
     *
     * @name cp
     * @memberof fsys
     * @method
     * @param {String} src コピー元のファイルパス
     * @param {String} dst コピー先のファイルパス
     * @param {function} callback コールバック
     */
    cp: function (src, dst, callback) {
        var srcstream = fs.createReadStream(src);
        var dststream = fs.createWriteStream(dst);

        srcstream.on('error', callback);
        dststream.on('error', callback);
        dststream.on('close', function() {
            return callback && callback();
        });
        srcstream.pipe(dststream);
    },

    /**
     * '~'付きのファイルパスから絶対パスを返却する
     *
     * @name resolveTilde
     * @memberof fsys
     * @method
     * @param {String} str 相対パス
     * @return {String} file path
     */
    resolveTilde: function (str) {
        if (!str) {
            return str;
        }
        if (str.substr(0,1) === '~') {
            str = process.env.HOME + str.substr(1);
        }
        return path.resolve(str);
    },

    /**
     * '~'付きのファイルパスの'~'をパスに置き換えて返却する
     *
     * @name resolveTilde
     * @memberof fsys
     * @method
     * @param {String} str 相対パス
     * @return {String} file path
     */
    pathTilde: function (str) {
        if (str && str.substr(0,1) === '~') {
            return process.env.HOME + str.substr(1);
        }
        return str;
    },

    /**
     * 拡張子が.jsはjavascript で、.jsonはJSON.parseでファイルをロードして返却します。
     *
     * @name readFileMultiConfigureSync
     * @memberof fsys
     * @method
     * @param {String} path read file path
     * @param {String} encode file read encode
     */
    readFileMultiConfigureSync: function (path, encode) {
        if (/.json$/.test(path)) {
            return this.readJsonSync(path, true, this.encode);
        } else if (/.js$/.test(path)) {
            return this.readFileFnJSONSync(path, this.encode);
        } else {
            throw new Error('Extension, please specify the ".json" or ".js".');
        }
    }

};
<|endoftext|>


<commit_before>const config = require('./config/config.json')
const { getOCSMeta } = require('./helpers/ocsResponseParser')

describe('provider testing', () => {
  const { VerifierV3 } = require('@pact-foundation/pact/v3')
  const chai = require('chai')
  const chaiAsPromised = require('chai-as-promised')
  const path = require('path')
  const fetch = require('sync-fetch')
  const { parseString } = require('xml2js')

  const {
    validAdminAuthHeaders,
    applicationFormUrlEncoded
  } = require('./pactHelper.js')

  const {
    createFolderRecrusive,
    createFile,
    getFileId,
    listVersionsFolder
  } = require('./webdavHelper.js')

  chai.use(chaiAsPromised)

  const assertFoldersCreatedSuccessfully = function (results, folderName) {
    for (let i = 0; i < results.length; i++) {
      // 405 means that the folder already exists
      if (results[i].status !== 405) {
        chai.assert.isBelow(
          results[i].status, 300, `creating folder '${folderName}' failed`
        )
      }
    }
  }

  it('verifies the provider', () => {
    const opts = {
      provider: 'oc-server',
      providerBaseUrl: process.env.PROVIDER_BASE_URL || 'http://localhost/',
      disableSSLVerification: true,
      callbackTimeout: 10000
    }
    if (process.env.CI === 'true') {
      opts.pactBrokerUrl = 'https://jankaritech.pactflow.io'
      opts.publishVerificationResult = true
      opts.pactBrokerToken = process.env.PACTFLOW_TOKEN
      opts.enablePending = true
      opts.consumerVersionSelectors = [
        {
          tag: process.env.DRONE_SOURCE_BRANCH,
          latest: true
        }
      ]
      opts.providerVersion = process.env.PROVIDER_VERSION
    } else {
      opts.pactUrls = [path.resolve(process.cwd(), 'tests', 'pacts', 'owncloud-sdk-oc-server.json')]
    }

    opts.stateHandlers = {
      'group exists': (setup, parameters) => {
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups', {
            method: 'POST',
            body: 'groupid=' + parameters.groupName,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          return Promise.resolve({ description: 'group added' })
        } else {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          return Promise.resolve({ description: 'group deleted' })
        }
      },
      'group does not exist': (setup, parameters) => {
        fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
          method: 'DELETE',
          headers: validAdminAuthHeaders
        })
        return Promise.resolve({ description: 'group deleted' })
      },
      'folder exists': (setup, parameters) => {
        if (setup) {
          const results = createFolderRecrusive(
            parameters.username, parameters.password, parameters.folderName
          )
          assertFoldersCreatedSuccessfully(results, parameters.folderName)
        }
        return Promise.resolve({ description: 'folder created' })
      },
      'file exists': (setup, parameters) => {
        const dirname = path.dirname(parameters.fileName)
        if (setup) {
          if (dirname !== '' && dirname !== '/') {
            const results = createFolderRecrusive(
              parameters.username, parameters.password, dirname
            )
            assertFoldersCreatedSuccessfully(results, dirname)
          }
          const result = createFile(
            parameters.username, parameters.password, parameters.fileName, config.testContent
          )
          chai.assert.isBelow(
            result.status, 300, `creating file '${parameters.fileName}' failed`
          )
          return { fileId: result.headers.get('oc-fileid') }
        }
      },
      'the user is recreated': (setup, parameters) => {
        const email = `${parameters.username}@example.com`
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users/' + parameters.username, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          const result = fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users',
            {
              method: 'POST',
              body: `userid=${parameters.username}&password=${parameters.password}&email=${email}`,
              headers: {
                ...validAdminAuthHeaders,
                ...applicationFormUrlEncoded
              }
            })
          chai.assert.strictEqual(
            result.status, 200, `creating user '${parameters.username}' failed`
          )
          return Promise.resolve({ description: 'user created' })
        }
      },
      'provider base url is returned': () => {
        return { providerBaseURL: process.env.PROVIDER_BASE_URL }
      },
      'file version link is returned': (setup, parameters) => {
        if (setup) {
          const fileId = getFileId(parameters.username, parameters.password, parameters.fileName)
          const versionsResult = listVersionsFolder(parameters.username, parameters.password, fileId)
          let nodeValue = ''
          parseString(versionsResult, function (err, result) {
            if (
              err ||
              typeof result['d:multistatus']['d:response'][parameters.number]['d:href'][0] !== 'string'
            ) {
              throw new Error('could not parse PROPFIND response ' +
                              `to list versions of '${parameters.fileName}' ${err}`)
            }
            nodeValue = result['d:multistatus']['d:response'][parameters.number]['d:href'][0]
          })
          // strip away any subfolder, pact will add it again if neededq
          const link = nodeValue.replace(/^.*(\/remote\.php\/dav\/meta\/.*)$/, '$1')
          return { versionLink: link }
        }
      },
      'user is made group subadmin': (setup, parameters) => {
        if (setup) {
          const response = fetch(process.env.PROVIDER_BASE_URL +
                          '/ocs/v1.php/cloud/users/' + parameters.username +
                          '/subadmins?format=json', {
            method: 'POST',
            body: `groupid=${parameters.groupName}`,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          const { status } = getOCSMeta(response)
          chai.assert.strictEqual(status, 'ok',
          `making user ${parameters.username} subadmin of group ${parameters.groupName} failed`)
        }
        return Promise.resolve({
          description: `user '${parameters.username}' made subadmin of group '${parameters.groupName}'`
        })
      },
      'user is added to group': (setup, parameters) => {
        if (setup) {
          const response = fetch(process.env.PROVIDER_BASE_URL +
                          '/ocs/v1.php/cloud/users/' + parameters.username +
                          '/groups?format=json', {
            method: 'POST',
            body: `groupid=${parameters.groupName}`,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          const { status } = getOCSMeta(response)
          chai.assert.strictEqual(status, 'ok',
          `adding user ${parameters.username} to group ${parameters.groupName} failed`)
        }
        return Promise.resolve({
          description: `user '${parameters.username}' added to group '${parameters.groupName}'`
        })
      }
    }
    return new VerifierV3(opts).verifyProvider().then(output => {
      console.log('Pact Verification Complete!')
      console.log('Result:', output)
    }).catch(function (error) {
      chai.assert.fail(error.message)
    })
  }, 600000)
})
<commit_msg>add a hack for owncloud/ocis/issues/1675<commit_after>const config = require('./config/config.json')
const { getOCSMeta } = require('./helpers/ocsResponseParser')

describe('provider testing', () => {
  const { VerifierV3 } = require('@pact-foundation/pact/v3')
  const chai = require('chai')
  const chaiAsPromised = require('chai-as-promised')
  const path = require('path')
  const fetch = require('sync-fetch')
  const { parseString } = require('xml2js')

  const {
    validAdminAuthHeaders,
    applicationFormUrlEncoded,
    getAuthHeaders
  } = require('./pactHelper.js')

  const {
    createFolderRecrusive,
    createFile,
    getFileId,
    listVersionsFolder
  } = require('./webdavHelper.js')

  chai.use(chaiAsPromised)

  const assertFoldersCreatedSuccessfully = function (results, folderName) {
    for (let i = 0; i < results.length; i++) {
      // 405 means that the folder already exists
      if (results[i].status !== 405) {
        chai.assert.isBelow(
          results[i].status, 300, `creating folder '${folderName}' failed`
        )
      }
    }
  }

  it('verifies the provider', () => {
    const opts = {
      provider: 'oc-server',
      providerBaseUrl: process.env.PROVIDER_BASE_URL || 'http://localhost/',
      disableSSLVerification: true,
      callbackTimeout: 10000
    }
    if (process.env.CI === 'true') {
      opts.pactBrokerUrl = 'https://jankaritech.pactflow.io'
      opts.publishVerificationResult = true
      opts.pactBrokerToken = process.env.PACTFLOW_TOKEN
      opts.enablePending = true
      opts.consumerVersionSelectors = [
        {
          tag: process.env.DRONE_SOURCE_BRANCH,
          latest: true
        }
      ]
      opts.providerVersion = process.env.PROVIDER_VERSION
    } else {
      opts.pactUrls = [path.resolve(process.cwd(), 'tests', 'pacts', 'owncloud-sdk-oc-server.json')]
    }

    opts.stateHandlers = {
      'group exists': (setup, parameters) => {
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups', {
            method: 'POST',
            body: 'groupid=' + parameters.groupName,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          return Promise.resolve({ description: 'group added' })
        } else {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          return Promise.resolve({ description: 'group deleted' })
        }
      },
      'group does not exist': (setup, parameters) => {
        fetch(process.env.PROVIDER_BASE_URL + '/ocs/v1.php/cloud/groups/' + parameters.groupName, {
          method: 'DELETE',
          headers: validAdminAuthHeaders
        })
        return Promise.resolve({ description: 'group deleted' })
      },
      'folder exists': (setup, parameters) => {
        if (setup) {
          const results = createFolderRecrusive(
            parameters.username, parameters.password, parameters.folderName
          )
          assertFoldersCreatedSuccessfully(results, parameters.folderName)
        }
        return Promise.resolve({ description: 'folder created' })
      },
      'file exists': (setup, parameters) => {
        const dirname = path.dirname(parameters.fileName)
        if (setup) {
          if (dirname !== '' && dirname !== '/') {
            const results = createFolderRecrusive(
              parameters.username, parameters.password, dirname
            )
            assertFoldersCreatedSuccessfully(results, dirname)
          }
          const result = createFile(
            parameters.username, parameters.password, parameters.fileName, config.testContent
          )
          chai.assert.isBelow(
            result.status, 300, `creating file '${parameters.fileName}' failed`
          )
          return { fileId: result.headers.get('oc-fileid') }
        }
      },
      'the user is recreated': (setup, parameters) => {
        const email = `${parameters.username}@example.com`
        if (setup) {
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users/' + parameters.username, {
            method: 'DELETE',
            headers: validAdminAuthHeaders
          })
          const result = fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/users',
            {
              method: 'POST',
              body: `userid=${parameters.username}&password=${parameters.password}&email=${email}`,
              headers: {
                ...validAdminAuthHeaders,
                ...applicationFormUrlEncoded
              }
            })
          chai.assert.strictEqual(
            result.status, 200, `creating user '${parameters.username}' failed`
          )
          // a hack for https://github.com/owncloud/ocis/issues/1675
          fetch(process.env.PROVIDER_BASE_URL + '/ocs/v2.php/cloud/capabilities',
            {
              method: 'GET',
              headers: { authorization: getAuthHeaders(parameters.username, parameters.password) }
            })
          return Promise.resolve({ description: 'user created' })
        }
      },
      'provider base url is returned': () => {
        return { providerBaseURL: process.env.PROVIDER_BASE_URL }
      },
      'file version link is returned': (setup, parameters) => {
        if (setup) {
          const fileId = getFileId(parameters.username, parameters.password, parameters.fileName)
          const versionsResult = listVersionsFolder(parameters.username, parameters.password, fileId)
          let nodeValue = ''
          parseString(versionsResult, function (err, result) {
            if (
              err ||
              typeof result['d:multistatus']['d:response'][parameters.number]['d:href'][0] !== 'string'
            ) {
              throw new Error('could not parse PROPFIND response ' +
                              `to list versions of '${parameters.fileName}' ${err}`)
            }
            nodeValue = result['d:multistatus']['d:response'][parameters.number]['d:href'][0]
          })
          // strip away any subfolder, pact will add it again if neededq
          const link = nodeValue.replace(/^.*(\/remote\.php\/dav\/meta\/.*)$/, '$1')
          return { versionLink: link }
        }
      },
      'user is made group subadmin': (setup, parameters) => {
        if (setup) {
          const response = fetch(process.env.PROVIDER_BASE_URL +
                          '/ocs/v1.php/cloud/users/' + parameters.username +
                          '/subadmins?format=json', {
            method: 'POST',
            body: `groupid=${parameters.groupName}`,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          const { status } = getOCSMeta(response)
          chai.assert.strictEqual(status, 'ok',
          `making user ${parameters.username} subadmin of group ${parameters.groupName} failed`)
        }
        return Promise.resolve({
          description: `user '${parameters.username}' made subadmin of group '${parameters.groupName}'`
        })
      },
      'user is added to group': (setup, parameters) => {
        if (setup) {
          const response = fetch(process.env.PROVIDER_BASE_URL +
                          '/ocs/v1.php/cloud/users/' + parameters.username +
                          '/groups?format=json', {
            method: 'POST',
            body: `groupid=${parameters.groupName}`,
            headers: {
              ...validAdminAuthHeaders,
              ...applicationFormUrlEncoded
            }
          })
          const { status } = getOCSMeta(response)
          chai.assert.strictEqual(status, 'ok',
          `adding user ${parameters.username} to group ${parameters.groupName} failed`)
        }
        return Promise.resolve({
          description: `user '${parameters.username}' added to group '${parameters.groupName}'`
        })
      }
    }
    return new VerifierV3(opts).verifyProvider().then(output => {
      console.log('Pact Verification Complete!')
      console.log('Result:', output)
    }).catch(function (error) {
      chai.assert.fail(error.message)
    })
  }, 600000)
})
<|endoftext|>