<commit_before>/**
 * Created by lilu on 2017/10/15.
 */
/**
 * Created by lilu on 2017/9/18.
 */
import React from 'react';
import {connect} from 'react-redux';
import {Row, Col, Input, Select, Button, DatePicker, message} from 'antd';
import StationAccountList from './StationAccountList';
import {stationAction, stationSelector} from '../station/redux';
import {accountAction, accountSelector} from './redux'
import * as excelFuncs from '../../util/excel'
import moment from 'moment'
import mathjs from 'mathjs'
import {withRouter} from 'react-router'

const RangePicker = DatePicker.RangePicker;
const Option = Select.Option;
const ButtonGroup = Button.Group
// var Excel = require('exceljs');

class StationAccountManager extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      curUserId: -1,
      selectedRowId: undefined,
      selectedRowData: undefined,
      status: undefined,
      stationId: undefined,
      startDate: moment().day(-30).format(),
      endDate: moment().format(),
      selectedType: 'all',
      division: [],
      viewType: 'all',
    }
  }

  selectStation(value) {
    this.setState({
      stationId: value
    })
  }

  selectType(value) {
    this.setState({
      selectedType: value
    })
  }

  selectDate(date, dateString) {
    console.log('date=====>', mathjs.chain(date[1] - date[0]).multiply(1 / 31536000000).done())
    let dateRange = mathjs.chain(date[1] - date[0]).multiply(1 / 31536000000).done()

    if (dateRange > 2) {
      message.error('时间范围请不要超过2年')
    } else {
      this.setState({startDate: dateString[0], endDate: dateString[1]})

    }
  }

  componentWillMount() {
    this.props.fetchStationAccounts({
      ...this.state,
      success: ()=> {
      console.log('hahhahah')
    },})
    this.props.requestStations({})
  }

  refresh() {
    // this.props.requestStations({...this.state})
  }

  search() {
    let payload = {
      stationId: this.state.stationId,
      startDate: this.state.startDate,
      endDate: this.state.endDate,
      success: ()=> {
        this.setState({viewType: this.state.selectedType})
        console.log('success')
      },
      error: ()=> {
        console.log('error')
      }
    }
    if (this.state.selectedType == 'all') {
      this.props.fetchStationAccounts(payload)
    } else {
      this.props.fetchStationAccountsDetail(payload)
    }
  }

  clearSearch() {
    this.setState({
      stationId: undefined,
      startDate: moment().day(-30).format(),
      endDate: moment().format(),
    })
    if (this.state.selectedType == 'all') {
      this.props.fetchStationAccounts({
        ...this.state,
        success: ()=> {
          console.log('hahhahah')
        }
      })
    } else {
      this.props.fetchStationAccountsDetail({
        ...this.state,
        success: ()=> {
          console.log('hahhahah')
        }
      })
    }

  }

  renderSearchBar() {
    return (

        <Row gutter={24}>
          <Col span={4}>
            <Select defalutValue='' onChange={(value)=> {
              this.selectStation(value)
            }} style={{width: 120}} placeholder="选择服务网点">
              <Option value=''>全部</Option>
              {
                this.props.stations.map((station, index) => (
                  <Option key={index} value={station.id}>{station.name}</Option>
                ))
              }
            </Select>
          </Col>
          <Col span={8}>
            <RangePicker key='selectDate' defaultValue={undefined}
                         value={[this.state.startDate ? moment(this.state.startDate) : undefined, moment(this.state.endDate)]}
                         onChange={(date, dateString)=> {
                           this.selectDate(date, dateString)
                         }} placeholder="选择日期"/>
          </Col>
          <Col span={4}>
            <Select defalutValue='all' onChange={(value)=> {
              this.selectType(value)
            }} style={{width: 120}} placeholder="选择查询方式">
              <Option value='all'>按周期</Option>
              <Option value='detail'>按日期</Option>
            </Select>
          </Col>
          <Col span={4}>
            <ButtonGroup>
              <Button type='primary' onClick={()=> {
                this.search()
              }}>查询</Button>

              <Button type='primary' onClick={()=> {
                this.clearSearch()
              }}>重置</Button>
            </ButtonGroup>
          </Col>
        </Row>

    )
  }

  downloadFile() {
    let data = [["日期", "利润", "成本", "收益", "服务点名称"],]
    // let accountArray = []
    if (this.props.stationAccounts && this.props.stationAccounts.length) {
      this.props.stationAccounts.forEach((account)=> {
        let account2Arr = [account.accountDay, account.profit, account.cost, account.incoming, account.station.name]
        data.push(account2Arr)
      })
    }
    let params = {data: data, sheetName: '服务点日结数据', fileName: '服务点日结数据'}

    excelFuncs.exportExcel(params)

  }

  viewChart() {
    this.props.history.push({
      pathname: '/settlement_list/stationChart',
    })
  }

  render() {
    // console.log('[DEBUG] ---> SysUser props: ', this.props);
    return (

        <ButtonGroup>
          <Button onClick={()=> {
            this.downloadFile()
          }}>导出EXCEL</Button>
          <Button onClick={()=> {
            this.viewChart()
          }}>查看图表</Button>

        </ButtonGroup>
        {/*<StationMenu*/}
        {/*showDetail={()=> {*/}
        {/*this.props.history.push({*/}
        {/*pathname: '/site/showStation/' + (this.state.selectedRowId ? this.state.selectedRowId[0] : ''),*/}
        {/*})*/}
        {/*}}*/}
        {/*set={()=> {*/}
        {/*this.props.history.push({*/}
        {/*pathname: '/site/editStation/' + (this.state.selectedRowId ? this.state.selectedRowId[0] : ''),*/}
        {/*})*/}
        {/*}}*/}
        {/*add={()=>{this.props.history.push({pathname: '/site/addStation'})}}*/}
        {/*setStatus={()=> {*/}
        {/*this.setStatus()*/}
        {/*}}*/}
        {/*refresh={()=> {*/}
        {/*this.refresh()*/}
        {/*}}*/}
        {/*/>*/}
        {this.renderSearchBar()}

        <StationAccountList
          selectStation={(rowId, rowData)=> {
            this.selectStation(rowId, rowData)
          }}
          viewType={this.state.viewType}
          stationAccounts={this.state.viewType == 'all' ? this.props.stationAccounts : this.props.stationAccountsDetail}/>

    )
  };
}

const mapStateToProps = (state, ownProps) => {
  let stations = stationSelector.selectStations(state)
  let accounts = accountSelector.selectStationAccounts(state)
  let accountsDetail = accountSelector.selectStationAccountsDetail(state)
  return {
    stationAccounts: accounts,
    stations: stations,
    stationAccountsDetail: accountsDetail
  };
};

const mapDispatchToProps = {
  ...stationAction,
  ...accountAction

};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(StationAccountManager));

export {saga, reducer} from './redux';
<commit_msg> station search form<commit_after>/**
 * Created by lilu on 2017/10/15.
 */
/**
 * Created by lilu on 2017/9/18.
 */
import React from 'react';
import {connect} from 'react-redux';
import {Row, Col, Input, Select, Button, DatePicker, message, Form} from 'antd';
import StationAccountList from './StationAccountList';
import {stationAction, stationSelector} from '../station/redux';
import {accountAction, accountSelector} from './redux'
import * as excelFuncs from '../../util/excel'
import moment from 'moment'
import mathjs from 'mathjs'
import {withRouter} from 'react-router'

const RangePicker = DatePicker.RangePicker;
const Option = Select.Option;
const ButtonGroup = Button.Group
const FormItem = Form.Item
// var Excel = require('exceljs');

class StationAccountManager extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      curUserId: -1,
      selectedRowId: undefined,
      selectedRowData: undefined,
      status: undefined,
      stationId: undefined,
      startDate: moment().day(-30).format(),
      endDate: moment().format(),
      selectedType: 'all',
      division: [],
      viewType: 'all',
    }
  }

  selectStation(value) {
    this.setState({
      stationId: value
    })
  }

  selectType(value) {
    this.setState({
      selectedType: value
    })
  }

  selectDate(date, dateString) {
    console.log('date=====>', mathjs.chain(date[1] - date[0]).multiply(1 / 31536000000).done())
    let dateRange = mathjs.chain(date[1] - date[0]).multiply(1 / 31536000000).done()

    if (dateRange > 2) {
      message.error('时间范围请不要超过2年')
    } else {
      this.setState({startDate: dateString[0], endDate: dateString[1]})

    }
  }

  componentWillMount() {
    this.props.fetchStationAccounts({
      ...this.state,
      success: ()=> {
        console.log('hahhahah')
      },
    })
    this.props.requestStations({})
  }

  refresh() {
    // this.props.requestStations({...this.state})
  }

  search(e) {
    e.preventDefault()
    this.props.form.validateFields((err, fieldsValue) => {
      if (err) {
        return
      }
      const rangeTimeValue = fieldsValue['rangeTimePicker']
      let values = fieldsValue
      console.log('==============value------->', values)
      if (rangeTimeValue && rangeTimeValue.length === 2) {
        values = {
          ...fieldsValue,
          'rangeTimePicker': [
            rangeTimeValue[0].format('YYYY-MM-DD'),
            rangeTimeValue[1].format('YYYY-MM-DD'),
          ],
        }
      }

      let payload = {
        stationId: values.stationId,
        startDate: values.rangeTimePicker ? values.rangeTimePicker[0] : moment().day(-30).formate(),
        endDate: values.rangeTimePicker ? values.rangeTimePicker[1] : moment().formate(),
        success: ()=> {
          console.log('success')
        },
        error: ()=> {
          console.log('error')
        }
      }
      this.setState({viewType: values.selectedType}, ()=> {
        if (values.selectedType == 'all') {
          this.props.fetchStationAccounts(payload)
        } else {
          this.props.fetchStationAccountsDetail(payload)
        }
      })
    })
  }

  clearSearch() {
    this.setState({
      stationId: undefined,
      startDate: moment().day(-30).format(),
      endDate: moment().format(),
    })
    if (this.state.selectedType == 'all') {
      this.props.fetchStationAccounts({
        ...this.state,
        success: ()=> {
          console.log('hahhahah')
        }
      })
    } else {
      this.props.fetchStationAccountsDetail({
        ...this.state,
        success: ()=> {
          console.log('hahhahah')
        }
      })
    }

  }

  renderSearchBar() {
    const {getFieldDecorator, getFieldsError, getFieldError, isFieldTouched} = this.props.form
    return (
      <Form style={{marginTop: 12, marginBottom: 12}} layout="inline" onSubmit={(e)=> {
        this.search(e)
      }}>
        <FormItem>
          {getFieldDecorator("rangeTimePicker", {
            initialValue: [moment().day(-30), moment()],
            rules: [{type: 'array'}],
          })(
            <RangePicker format="YYYY-MM-DD"/>
          )}
        </FormItem>
        <FormItem>
          {getFieldDecorator("stationId", {
            initialValue: '',
          })(
            <Select style={{width: 120}} placeholder="选择服务网点">
              <Option value=''>全部</Option>
              {
                this.props.stations.map((station, index) => (
                  <Option key={index} value={station.id}>{station.name}</Option>
                ))
              }
            </Select>
          )}
        </FormItem>
        <FormItem>
          {getFieldDecorator("selectedType", {
            initialValue: 'all',
          })(
            <Select style={{width: 120}} placeholder="选择查询方式">
              <Option value='all'>按周期</Option>
              <Option value='detail'>按日期</Option>
            </Select>
          )}
        </FormItem>
        <FormItem>
          <Button.Group>
            <Button onClick={() => {
              this.props.form.resetFields()
            }}>重置</Button>
            <Button type="primary" htmlType="submit">查询</Button>
          </Button.Group> </FormItem>
      </Form>

    )
  }

  downloadFile() {
    let data = [["日期", "利润", "成本", "收益", "服务点名称"],]
    // let accountArray = []
    if (this.props.stationAccounts && this.props.stationAccounts.length) {
      this.props.stationAccounts.forEach((account)=> {
        let account2Arr = [account.accountDay, account.profit, account.cost, account.incoming, account.station.name]
        data.push(account2Arr)
      })
    }
    let params = {data: data, sheetName: '服务点日结数据', fileName: '服务点日结数据'}

    excelFuncs.exportExcel(params)

  }

  viewChart() {
    this.props.history.push({
      pathname: '/settlement_list/stationChart',
    })
  }

  render() {
    // console.log('[DEBUG] ---> SysUser props: ', this.props);
    return (

        <ButtonGroup>
          <Button onClick={()=> {
            this.downloadFile()
          }}>导出EXCEL</Button>
          <Button onClick={()=> {
            this.viewChart()
          }}>查看图表</Button>

        </ButtonGroup>
        {/*<StationMenu*/}
        {/*showDetail={()=> {*/}
        {/*this.props.history.push({*/}
        {/*pathname: '/site/showStation/' + (this.state.selectedRowId ? this.state.selectedRowId[0] : ''),*/}
        {/*})*/}
        {/*}}*/}
        {/*set={()=> {*/}
        {/*this.props.history.push({*/}
        {/*pathname: '/site/editStation/' + (this.state.selectedRowId ? this.state.selectedRowId[0] : ''),*/}
        {/*})*/}
        {/*}}*/}
        {/*add={()=>{this.props.history.push({pathname: '/site/addStation'})}}*/}
        {/*setStatus={()=> {*/}
        {/*this.setStatus()*/}
        {/*}}*/}
        {/*refresh={()=> {*/}
        {/*this.refresh()*/}
        {/*}}*/}
        {/*/>*/}
        {this.renderSearchBar()}

        <StationAccountList
          selectStation={(rowId, rowData)=> {
            this.selectStation(rowId, rowData)
          }}
          viewType={this.state.viewType}
          stationAccounts={this.state.viewType == 'all' ? this.props.stationAccounts : this.props.stationAccountsDetail}/>

    )
  };
}

const mapStateToProps = (state, ownProps) => {
  let stations = stationSelector.selectStations(state)
  let accounts = accountSelector.selectStationAccounts(state)
  let accountsDetail = accountSelector.selectStationAccountsDetail(state)
  return {
    stationAccounts: accounts,
    stations: stations,
    stationAccountsDetail: accountsDetail
  };
};

const mapDispatchToProps = {
  ...stationAction,
  ...accountAction

};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Form.create()(StationAccountManager)));

export {saga, reducer} from './redux';
<|endoftext|>


<commit_before>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  describe("NewDeviceCtrl", function() {
    var scope, location, controller;

    beforeEach(inject(function($location, $controller) {
      location = $location;
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    }));

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope, controller;

    beforeEach(inject(function($controller) {
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    }));

    it("should setup pager", function() {
      httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
      controller('DevicesCtrl', { $scope: scope });
      httpBackend.flush();
      expect(scope.page).to.have.been.calledWith(1, 25, 2);
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<commit_msg>tests: ajax: device index 'new' button handling<commit_after>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  describe("NewDeviceCtrl", function() {
    var scope, location, controller;

    beforeEach(inject(function($location, $controller) {
      location = $location;
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    }));

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope, controller;

    beforeEach(inject(function($controller) {
      controller = $controller;
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };

      httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
      controller('DevicesCtrl', { $scope: scope });
    }));

    it("should setup pager", function() {
      httpBackend.flush();
      expect(scope.page).to.have.been.calledWith(1, 25, 2);
    });

    it("should call setNewURL", function() {
      expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<|endoftext|>


<commit_before>Components.utils.import("resource:///modules/gloda/index_msg.js");
Components.utils.import("resource:///modules/gloda/mimemsg.js");
// This is Thunderbird 3.3 only!
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");

var DateRec = {
  do: function () {
    // First we get msgHdr, a nsIMsgDbHdr
    let msgHdr = gFolderDisplay.selectedMessage;
    let text = [];
    let add = function (s) text.push(s);
    let count = 3;
    let top = function () {
      if (--count == 0)
        document.getElementById("tabmail").openTab("contentTab", {
          contentPage: "about:blank",
          onLoad: function (aEvent, aBrowser) {
            let doc = aBrowser.contentDocument;
            let pre = doc.createElement("pre");
            pre.textContent = text.join("");
            doc.body.appendChild(pre);
          },
        });
    }
    // The first way of examining it is through the MimeMessage representation
    MsgHdrToMimeMessage(msgHdr, null, function (aMsgHdr, aMimeMsg) {
      var message_body=(aMimeMsg.coerceBodyToPlaintext());
        var regex=/(\d+)\/(\d+)\/(\d+)/;
        var match=regex.exec(message_body);
        //alert(match[1]+"th" + match[2]+","+match[3]);
        alert(match[0]);
      top();

    });
  }
}

<commit_msg>event addition and common date formats implemented<commit_after>Components.utils.import("resource:///modules/gloda/index_msg.js");
Components.utils.import("resource:///modules/gloda/mimemsg.js");
// This is Thunderbird 3.3 only!
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");

var months={
  "January" : 1,
  "February" : 2,
  "March" : 3,
  "April": 4,
  "May": 5,
  "June": 6,
  "July": 7,
  "August":8,
  "September" : 9,
  "October": 10,
  "November": 11,
  "December": 12,
  "01": 1,
  "1": 1,
  "02": 2,
  "2": 2,
  "03": 3,
  "3": 3,
  "04": 4,
  "4": 4,
  "05": 5,
  "5": 5,
  "06": 6,
  "6": 6,
  "07" : 7,
  "7": 7,
  "08": 8,
  "8": 8,
  "09": 9,
  "9": 9,
  "10": 10,
  "11": 11,
  "12": 12
};

var DateRec = {
  do: function () {
    // First we get msgHdr, a nsIMsgDbHdr
    let msgHdr = gFolderDisplay.selectedMessage;
    let text = [];
    let add = function (s) text.push(s);
    let count = 3;
    let top = function () {
      if (--count == 0)
        document.getElementById("tabmail").openTab("contentTab", {
          contentPage: "about:blank",
          onLoad: function (aEvent, aBrowser) {
            let doc = aBrowser.contentDocument;
            let pre = doc.createElement("pre");
            pre.textContent = text.join("");
            doc.body.appendChild(pre);
          },
        });
    }
    // The first way of examining it is through the MimeMessage representation
    MsgHdrToMimeMessage(msgHdr, null, function (aMsgHdr, aMimeMsg) {
      var message_body=(aMimeMsg.coerceBodyToPlaintext());
      var regex=new Array(
        /(\d+)\/(\d+)\/(\d+)/,
        /(\d+)-(\S+)-(\d+)/,
        /(\d+) (\S+) (\d+)/
      );

      var num_dates=0;
      for(var i=0;i<regex.length;++i){
        var match=regex[i].exec(message_body);
        if(match==null || !(match[2] in months))
          continue;
        ++num_dates
        if (confirm("Add event on " + match[0]+ "?")) {
          test(match);
        }
        else
          continue;
      }
      if(num_dates==0)
        alert("Sorry! No dates detected in this email");
      top();

    });
  }

}

function test(match){
  var newItem = createEvent();
  var aMsgHdr=gFolderDisplay.selectedMessage;
  var aItem=newItem;

  aItem.calendar = getSelectedCalendar();
  aItem.title = aMsgHdr.mime2DecodedSubject;
  cal.setDefaultStartEndHour(aItem);

  aItem.startDate.second=0;
  aItem.startDate.minute=0;
  aItem.startDate.hour=16;
  aItem.startDate.day=match[1];

  aItem.startDate.month=months[match[2]]-1;

  aItem.startDate.year=match[3];

  aItem.endDate = aItem.startDate.clone();
  aItem.endDate.hour += 1;
  createEventWithDialog(null, null, null, null, newItem);
}
<|endoftext|>


<commit_before>import test from 'ava';
import createMountNode from '../src/create-mount-node';
import document from 'global/document';

global.document = document;

test('createMountNode()', (assert) => {
  const node = createMountNode();

  assert.is(node.tagName, 'DIV', 'should create a `div` element');
  assert.is(node.parentNode.tagName, 'BODY', 'should be created inside `body` tag');
  assert.deepEqual(node.childNodes, [], 'should create an empty `div` element');
});
<commit_msg>Update create-mount-node-test<commit_after>import test from 'ava';
import createMountNode from '../src/create-mount-node';
import document from 'global/document';

test('createMountNode()', (assert) => {
  global.document = document;

  const node = createMountNode();
  const parent = node.parentNode;

  assert.is(node.tagName, 'DIV', 'should create a `div` element');
  assert.deepEqual(node.childNodes, [], 'should create an empty `div` element');
  assert.is(parent.tagName, 'BODY', 'should be created inside `body` tag');
  assert.deepEqual(parent.childNodes[0], node, 'should be created as the first element in `body` tag');
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import UserPreferencesStore from '../../stores/UserPreferencesStore';
import de from './de.json';
import am from './am.json';
import zh from './zh.json';
import es from './es.json';
import hi from './hi.json';
import fr from './fr.json';
import gr from './gr.json';
import ru from './ru.json';
import jp from './jp.json';
import nl from './nl.json';
import pb from './pb.json';
import np from './np.json';

class Translate extends Component{

  constructor(props){
    super(props);
    this.state ={
      text: this.props.text,
      defaultPrefLanguage: UserPreferencesStore.getPrefLang()
    }
  }

  changeLanguage = (text) => {
        this.setState({
            text:text
        })
  }

  componentDidMount() {
    let defaultPrefLanguage = this.state.defaultPrefLanguage;

    var arr, file;

    let text = this.state.text;
    if(defaultPrefLanguage!=='en-US'){

      if(defaultPrefLanguage==='de-DE'){
        arr = Object.keys(de);
        file = de;
      }
      else if(defaultPrefLanguage==='am-AM'){
        arr = Object.keys(am);
        file = am;
      }
      else if(defaultPrefLanguage==='es-SP'){
        arr = Object.keys(es);
        file = es;
      }
      else if(defaultPrefLanguage==='zh-CH'){
        arr = Object.keys(zh);
        file = zh;
			}
      else if(defaultPrefLanguage==='hi-IN'){
        arr = Object.keys(hi);
        file = hi;
      }
			else if(defaultPrefLanguage==='pb-IN'){
        arr = Object.keys(pb);
        file = pb;
      }
			else if(defaultPrefLanguage==='np-NP'){
        arr = Object.keys(np);
        file = np;
      }
      else if(defaultPrefLanguage==='fr-FR'){
        arr = Object.keys(fr);
        file = fr;
      }
      else if(defaultPrefLanguage==='ru-RU'){
        arr = Object.keys(ru);
        file = ru;
      }
      else if(defaultPrefLanguage==='gr-GR'){
        arr = Object.keys(gr);
        file = gr;
      }
      else if(defaultPrefLanguage==='nl-NL'){
        arr = Object.keys(nl);
        file = nl;
      }
      else{
        arr = Object.keys(jp);
        file = jp;
      }

      for (let key=0;key<arr.length;key++) {
        if (arr[key]===text) {
            this.changeLanguage(file[arr[key]]);
        }
      }

  }
}
  render() {
    return {this.state.text}
  }

}

Translate.propTypes = {
  text:PropTypes.string
}
export default Translate;
<commit_msg>Translate code refactor (#1318)<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import UserPreferencesStore from '../../stores/UserPreferencesStore';
import de from './de.json';
import am from './am.json';
import zh from './zh.json';
import es from './es.json';
import hi from './hi.json';
import fr from './fr.json';
import gr from './gr.json';
import ru from './ru.json';
import jp from './jp.json';
import nl from './nl.json';
import pb from './pb.json';
import np from './np.json';

class Translate extends Component{

  constructor(props){
    super(props);
    this.state ={
      text: this.props.text,
      defaultPrefLanguage: UserPreferencesStore.getPrefLang()
    }
  }

  changeLanguage = (text) => {
        this.setState({
            text:text
        })
  }

  lang = {
    'de-DE': de,
    'am-AM': am,
    'es-SP': es,
    'zh-CH': zh,
    'hi-IN': hi,
    'pb-IN': pb,
    'np-NP': np,
    'fr-FR': fr,
    'ru-RU': ru,
    'gr-GR': gr,
    'nl-NL': nl
  };

  componentDidMount() {
    let arr, file, defaultPrefLanguage = this.state.defaultPrefLanguage;
    let text = this.state.text;
    if(defaultPrefLanguage!=='en-US'){
      if(this.lang.hasOwnProperty(defaultPrefLanguage)) {
        arr = Object.keys(this.lang[defaultPrefLanguage]);
        file = this.lang[defaultPrefLanguage];
      } else {
        arr = Object.keys(jp);
        file = jp;
      }
      arr.forEach((val,index)=> {
        if (arr.index===text) {
        this.changeLanguage(file.arr.index);
        }
      })
    }
  }

  render() {
    return {this.state.text}
  }

}

Translate.propTypes = {
  text:PropTypes.string
}
export default Translate;
<|endoftext|>


<commit_before>/**
 * @author Pedro Sanders
 * @since v1
 */
import RegisterHandler from 'core/processor/register_handler'
import CancelHandler from 'core/processor/cancel_handler'
import RouteInfo from 'core/processor/route_info'
import Context from 'core/context'
import AclUtil from 'core/acl/acl_util'
import getConfig from 'core/config_util'
import { Status } from 'location/status'
import { RoutingType } from 'core/routing_type'
import isEmpty from 'utils/obj_util'
import IPUtil from 'core/ip_util'

const SipFactory = Packages.javax.sip.SipFactory
const RouteHeader = Packages.javax.sip.header.RouteHeader
const ToHeader = Packages.javax.sip.header.ToHeader
const FromHeader = Packages.javax.sip.header.FromHeader
const ContactHeader = Packages.javax.sip.header.ContactHeader
const ViaHeader = Packages.javax.sip.header.ViaHeader
const MaxForwardsHeader = Packages.javax.sip.header.MaxForwardsHeader
const ProxyAuthorizationHeader = Packages.javax.sip.header.ProxyAuthorizationHeader
const Request = Packages.javax.sip.message.Request
const Response = Packages.javax.sip.message.Response
const HashMap = Packages.java.util.HashMap
const LogManager = Packages.org.apache.logging.log4j.LogManager
const LOG = LogManager.getLogger()

export default class RequestProcessor {

    constructor(sipProvider, locator, registry, registrar, dataAPIs, contextStorage) {
        this.sipProvider = sipProvider
        this.sipStack = this.sipProvider.getSipStack()
        this.contextStorage = contextStorage
        this.locator = locator
        this.registry = registry
        this.dataAPIs = dataAPIs
        this.domainsAPI = dataAPIs.DomainsAPI
        this.peersAPI = dataAPIs.PeersAPI
        this.agentsAPI = dataAPIs.AgentsAPI
        this.didsAPI = dataAPIs.DIDsAPI
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.dsam = new Packages.gov.nist.javax.sip.clientauthutils.DigestServerAuthenticationHelper()
        this.config = getConfig()
        this.generalAcl = this.config.spec.accessControlList
        this.registerHandler = new RegisterHandler(locator, registrar)
        this.cancelHandler = new CancelHandler(sipProvider, contextStorage)
        this.ipUtil = new IPUtil()
    }

    process(event) {
        const requestIn = event.getRequest()
        const method = requestIn.getMethod()
        let serverTransaction = event.getServerTransaction()

        // ACK does not need a transaction
        if (serverTransaction == null && !method.equals(Request.ACK)) {
            serverTransaction = this.sipProvider.getNewServerTransaction(requestIn)
        }

        const requestOut = requestIn.clone()

        if (method.equals(Request.REGISTER)) {
            // Should we apply ACL rules here too?
            this.registerHandler.register(requestIn, serverTransaction)
            return
        } else if(method.equals(Request.CANCEL)) {
            this.cancelHandler.cancel(requestIn, serverTransaction)
            return
        } else {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const fromURI = fromHeader.getAddress().getURI()
            const remoteIp = event.getRemoteIpAddress()
            const routeInfo = new RouteInfo(requestIn, this.dataAPIs)

            LOG.debug('routing type -> ' + routeInfo.getRoutingType())

            // 1. Security check
            // This routing type is not yet supported
            if (routeInfo.getRoutingType().equals(RoutingType.INTER_DOMAIN_ROUTING)) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.FORBIDDEN, requestIn))
                LOG.debug(requestIn)
                return
            }

            // Other routing types are assume to be already login(registered)
            /*if (!routeInfo.getRoutingType().equals(RoutingType.DOMAIN_INGRESS_ROUTING)) {
                // Do not need to authorized ACK or BYE messages...
                if (!method.equals(Request.ACK)
                    && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'UNAUTHORIZED') {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                } else if (!method.equals(Request.ACK) && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'SENT_CHALLENGE') {
                    LOG.debug(requestIn)
                    return
                }
            } else {
                if (!this.registry.hasIp(remoteIp)) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                }
            }*/

            let addressOfRecord = this.getAOR(requestIn)

            // We only apply ACL rules to Domain Routing.
            if (routeInfo.getRoutingType().equals(RoutingType.INTRA_DOMAIN_ROUTING)) {
                const result = this.domainsAPI.getDomain(addressOfRecord.getHost())
                if (result.status == Status.OK) {
                    const domainObj = result.obj
                    if(!new AclUtil(this.generalAcl).isIpAllowed(domainObj, remoteIp)) {
                        serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                        LOG.debug(requestIn)
                        return
                    }
                }
            }

            // 2. Decrement the max forwards value
            const maxForwardsHeader = requestOut.getHeader(MaxForwardsHeader.NAME)
            maxForwardsHeader.decrementMaxForwards()

            // 3. Determine route
            // 3.0 Peer Egress Routing (PR)
            if (routeInfo.getRoutingType().equals(RoutingType.PEER_EGRESS_ROUTING)) {
                let telUrl

                // First look for the header 'DIDRef'
                if (requestOut.getHeader('DIDRef')) {
                    telUrl = this.addressFactory.createTelURL(requestOut.getHeader('DIDRef'))
                } else {
                    telUrl = this.addressFactory.createTelURL(fromURI.getUser())
                }

                let result = this.didsAPI.getDIDByTelUrl(telUrl)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                const didRef = result.obj.metadata.ref
                result = this.locator.getEgressRouteForPeer(addressOfRecord, didRef)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                this.processRoute(requestIn, requestOut, result.obj, serverTransaction, routeInfo)

                LOG.debug(requestOut)
                return
            }

            // 3.1 Intra-Domain Routing(IDR), Domain Ingress Routing (DIR), & Domain Egress Routing (DER)
            const result = this.locator.findEndpoint(addressOfRecord)

            if (result.status == Status.NOT_FOUND) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                LOG.debug(requestIn)
                return
            }

            // 4. Send response
            const location = result.obj

            if (location instanceof HashMap) {
                let caIterator

                try {
                    caIterator = location.values().iterator()
                } catch(e) {}

                if (!caIterator.hasNext()) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                // Fork the call if needed
                while(caIterator.hasNext()) {
                    const route = caIterator.next()
                    this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
                }
            } else {
                const route = location
                this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
            }

            return
        }
        LOG.debug(requestIn)
    }

    processRoute(requestIn, requestOut, route, serverTransaction, routeInfo) {
        requestOut.setRequestURI(route.contactURI)
        const routeHeader = requestIn.getHeader(RouteHeader.NAME)
        const rVia = requestIn.getHeader(ViaHeader.NAME)
        const transport = rVia.getTransport().toLowerCase()
        const lp = this.sipProvider.getListeningPoint(transport)
        const localPort = lp.getPort()
        const localIp = lp.getIPAddress().toString()
        const method = requestIn.getMethod()
        const rcvHost = route.contactURI.getHost()

        LOG.debug('contactURI is -> ' + route.contactURI)
        LOG.debug('Behind nat -> ' + route.nat)
        LOG.debug('rcvHost is -> ' + rcvHost)
        LOG.debug('sentByAddress -> ' + route.sentByAddress)
        LOG.debug('sentByPort -> ' + route.sentByPort)
        LOG.debug('received -> ' + route.received)
        LOG.debug('rport -> ' + route.rport)

        let advertisedAddr
        let advertisedPort

        // No egress routing has sentByAddress. They are assume to be entities outside the local network.
        if (this.config.spec.externAddr && (route.sentByAddress == undefined || !this.ipUtil.isLocalnet(route.sentByAddress))) {
            advertisedAddr = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[0] : this.config.spec.externAddr
            advertisedPort = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[1] : localPort
        }  else {
            advertisedAddr = localIp
            advertisedPort = localPort
        }

        LOG.debug('advertisedAddr is -> ' + advertisedAddr)
        LOG.debug('advertisedPort is -> ' + advertisedPort)

        // Remove route header if host is same as the proxy
        if (routeHeader) {
            const routeHeaderHost = routeHeader.getAddress().getURI().getHost()
            const routeHeaderPort = routeHeader.getAddress().getURI().getPort()
            if ((routeHeaderHost.equals(localIp) && routeHeaderPort.equals(localPort))
                || ((routeHeaderHost.equals(advertisedAddr) && routeHeaderPort.equals(advertisedPort)))) {
                requestOut.removeFirst(RouteHeader.NAME)
            }
        }

        // Stay in the signaling path
        if (this.config.spec.recordRoute) {
            const proxyURI = this.addressFactory.createSipURI(null, advertisedAddr)
            proxyURI.setLrParam()
            proxyURI.setPort(advertisedPort)
            const proxyAddress = this.addressFactory.createAddress(proxyURI)
            const recordRouteHeader = this.headerFactory.createRecordRouteHeader(proxyAddress)
            requestOut.addHeader(recordRouteHeader)
        }

        // Request RPort to enable Symmetric Response in accordance with RFC 3581 and RFC 6314
        const viaHeader = this.headerFactory.createViaHeader(advertisedAddr, advertisedPort, transport, null)
        viaHeader.setRPort()
        requestOut.addFirst(viaHeader)

        if (route.thruGw) {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const toHeader = requestIn.getHeader(ToHeader.NAME)
            const gwRefHeader = this.headerFactory.createHeader('X-Gateway-Ref', route.gwRef)
            const remotePartyIdHeader = this.headerFactory
                .createHeader('Remote-Party-ID', '<sip:'+ route.did + '@' + route.gwHost+ '>;screen=yes;party=calling')

            const from = 'sip:' + route.gwUsername + '@' + route.gwHost
            const to = 'sip:' + toHeader.getAddress().toString().match('sips?:(.*)@(.*)')[1] + '@' + route.gwHost

            // This might not work with all provider
            const fromAddress = this.addressFactory.createAddress(from)
            const toAddress = this.addressFactory.createAddress(to)

            fromHeader.setAddress(fromAddress)
            toHeader.setAddress(toAddress)

            requestOut.setHeader(gwRefHeader)
            //requestOut.setHeader(fromHeader)
            //requestOut.setHeader(toHeader)
            requestOut.setHeader(remotePartyIdHeader)
        }

        // Warning: Not yet test :(
        requestOut.removeHeader("Proxy-Authorization")

        // Does not need a transaction
        if(method.equals(Request.ACK)) {
            this.sipProvider.sendRequest(requestOut)
        } else {
            try {
                // The request must be cloned or the stack will not fork the call
                const clientTransaction = this.sipProvider.getNewClientTransaction(requestOut.clone())
                clientTransaction.sendRequest()

                // Transaction context
                const context = new Context()
                context.clientTransaction = clientTransaction
                context.serverTransaction = serverTransaction
                context.method = method
                context.requestIn = requestIn
                context.requestOut = requestOut
                this.contextStorage.saveContext(context)
            } catch (e) {
                if (e instanceof java.net.ConnectException) {
                    LOG.error('Connection refused. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/ConnectException.html')
                } else if (e instanceof java.net.NoRouteToHostException) {
                    LOG.error('No route to host. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/NoRouteToHostException.html')
                } else {
                    LOG.error(e.getMessage())
                }
            }
        }

        LOG.debug(requestOut)
    }

    authorized(request, serverTransaction) {
        const authHeader = request.getHeader(ProxyAuthorizationHeader.NAME)
        const fromHeader = request.getHeader(FromHeader.NAME)
        const fromURI = fromHeader.getAddress().getURI()

        // WARNING: Should limit the amount of attempts...
        if (authHeader == null) {
            const challengeResponse = this.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED, request)
            this.dsam.generateChallenge(this.headerFactory, challengeResponse, "sipio")
            serverTransaction.sendResponse(challengeResponse)
            LOG.debug(request)
            return 'SENT_CHALLENGE'
        }

        // WARNING: If they are multiple peers with the same name this might be an issue
        let result = this.peersAPI.getPeer(authHeader.getUsername())

        let user

        if (result.status == Status.OK) {
            user = result.obj
        } else {
            // This is also a security check. The user in the authentication must exist for the 'fromURI.getHost()' domain
            result = this.agentsAPI.getAgent(fromURI.getHost(), authHeader.getUsername())
            if (result.status == Status.OK ) {
                user = result.obj
            }
        }

        if (!user || !this.dsam.doAuthenticatePlainTextPassword(request, user.spec.credentials.secret)) {
            return 'UNAUTHORIZED'
        }

        return 'AUTHORIZED'
    }

    /**
     * Discover DIDs sent via a non-standard header
     * The header must be added at config.spec.addressInfo[*]
     * If the such header is present then overwrite the AOR
     */
    getAOR (request) {
        for (let x in this.config.spec.addressInfo) {
            let info = this.config.spec.addressInfo[x]
            if (!!request.getHeader(info)) {
                let v = request.getHeader(info).getValue()
                if (/sips?:.*@.*/.test(v) || /tel:\d+/.test(v)) {
                    return this.addressFactory.createURI(v)
                }
                LOG.error('Invalid address: ' + v)
            }
        }
        return request.getHeader(ToHeader.NAME).getAddress().getURI()
    }
}
<commit_msg>Cleanup<commit_after>/**
 * @author Pedro Sanders
 * @since v1
 */
import RegisterHandler from 'core/processor/register_handler'
import CancelHandler from 'core/processor/cancel_handler'
import RouteInfo from 'core/processor/route_info'
import Context from 'core/context'
import AclUtil from 'core/acl/acl_util'
import getConfig from 'core/config_util'
import { Status } from 'location/status'
import { RoutingType } from 'core/routing_type'
import isEmpty from 'utils/obj_util'
import IPUtil from 'core/ip_util'

const SipFactory = Packages.javax.sip.SipFactory
const RouteHeader = Packages.javax.sip.header.RouteHeader
const ToHeader = Packages.javax.sip.header.ToHeader
const FromHeader = Packages.javax.sip.header.FromHeader
const ContactHeader = Packages.javax.sip.header.ContactHeader
const ViaHeader = Packages.javax.sip.header.ViaHeader
const MaxForwardsHeader = Packages.javax.sip.header.MaxForwardsHeader
const ProxyAuthorizationHeader = Packages.javax.sip.header.ProxyAuthorizationHeader
const Request = Packages.javax.sip.message.Request
const Response = Packages.javax.sip.message.Response
const HashMap = Packages.java.util.HashMap
const LogManager = Packages.org.apache.logging.log4j.LogManager
const LOG = LogManager.getLogger()

export default class RequestProcessor {

    constructor(sipProvider, locator, registry, registrar, dataAPIs, contextStorage) {
        this.sipProvider = sipProvider
        this.sipStack = this.sipProvider.getSipStack()
        this.contextStorage = contextStorage
        this.locator = locator
        this.registry = registry
        this.dataAPIs = dataAPIs
        this.domainsAPI = dataAPIs.DomainsAPI
        this.peersAPI = dataAPIs.PeersAPI
        this.agentsAPI = dataAPIs.AgentsAPI
        this.didsAPI = dataAPIs.DIDsAPI
        this.messageFactory = SipFactory.getInstance().createMessageFactory()
        this.headerFactory = SipFactory.getInstance().createHeaderFactory()
        this.addressFactory = SipFactory.getInstance().createAddressFactory()
        this.dsam = new Packages.gov.nist.javax.sip.clientauthutils.DigestServerAuthenticationHelper()
        this.config = getConfig()
        this.generalAcl = this.config.spec.accessControlList
        this.registerHandler = new RegisterHandler(locator, registrar)
        this.cancelHandler = new CancelHandler(sipProvider, contextStorage)
        this.ipUtil = new IPUtil()
    }

    process(event) {
        const requestIn = event.getRequest()
        const method = requestIn.getMethod()
        let serverTransaction = event.getServerTransaction()

        // ACK does not need a transaction
        if (serverTransaction == null && !method.equals(Request.ACK)) {
            serverTransaction = this.sipProvider.getNewServerTransaction(requestIn)
        }

        const requestOut = requestIn.clone()

        if (method.equals(Request.REGISTER)) {
            // Should we apply ACL rules here too?
            this.registerHandler.register(requestIn, serverTransaction)
            return
        } else if(method.equals(Request.CANCEL)) {
            this.cancelHandler.cancel(requestIn, serverTransaction)
            return
        } else {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const fromURI = fromHeader.getAddress().getURI()
            const remoteIp = event.getRemoteIpAddress()
            const routeInfo = new RouteInfo(requestIn, this.dataAPIs)

            LOG.debug('routing type -> ' + routeInfo.getRoutingType())

            // 1. Security check
            // This routing type is not yet supported
            if (routeInfo.getRoutingType().equals(RoutingType.INTER_DOMAIN_ROUTING)) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.FORBIDDEN, requestIn))
                LOG.debug(requestIn)
                return
            }

            // Other routing types are assume to be already login(registered)
            /*if (!routeInfo.getRoutingType().equals(RoutingType.DOMAIN_INGRESS_ROUTING)) {
                // Do not need to authorized ACK or BYE messages...
                if (!method.equals(Request.ACK)
                    && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'UNAUTHORIZED') {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                } else if (!method.equals(Request.ACK) && !method.equals(Request.BYE)
                    && this.authorized(requestIn, serverTransaction) == 'SENT_CHALLENGE') {
                    LOG.debug(requestIn)
                    return
                }
            } else {
                if (!this.registry.hasIp(remoteIp)) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                    LOG.debug(requestIn)
                    return
                }
            }*/

            let addressOfRecord = this.getAOR(requestIn)

            // We only apply ACL rules to Domain Routing.
            if (routeInfo.getRoutingType().equals(RoutingType.INTRA_DOMAIN_ROUTING)) {
                const result = this.domainsAPI.getDomain(addressOfRecord.getHost())
                if (result.status == Status.OK) {
                    const domainObj = result.obj
                    if(!new AclUtil(this.generalAcl).isIpAllowed(domainObj, remoteIp)) {
                        serverTransaction.sendResponse(this.messageFactory.createResponse(Response.UNAUTHORIZED, requestIn))
                        LOG.debug(requestIn)
                        return
                    }
                }
            }

            // 2. Decrement the max forwards value
            const maxForwardsHeader = requestOut.getHeader(MaxForwardsHeader.NAME)
            maxForwardsHeader.decrementMaxForwards()

            // 3. Determine route
            // 3.0 Peer Egress Routing (PR)
            if (routeInfo.getRoutingType().equals(RoutingType.PEER_EGRESS_ROUTING)) {
                let telUrl

                // First look for the header 'DIDRef'
                if (requestOut.getHeader('DIDRef')) {
                    telUrl = this.addressFactory.createTelURL(requestOut.getHeader('DIDRef'))
                } else {
                    telUrl = this.addressFactory.createTelURL(fromURI.getUser())
                }

                let result = this.didsAPI.getDIDByTelUrl(telUrl)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                const didRef = result.obj.metadata.ref
                result = this.locator.getEgressRouteForPeer(addressOfRecord, didRef)

                if (result.status == Status.NOT_FOUND) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                this.processRoute(requestIn, requestOut, result.obj, serverTransaction, routeInfo)

                LOG.debug(requestOut)
                return
            }

            // 3.1 Intra-Domain Routing(IDR), Domain Ingress Routing (DIR), & Domain Egress Routing (DER)
            const result = this.locator.findEndpoint(addressOfRecord)

            if (result.status == Status.NOT_FOUND) {
                serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                LOG.debug(requestIn)
                return
            }

            // 4. Send response
            const location = result.obj

            if (location instanceof HashMap) {
                let caIterator

                try {
                    caIterator = location.values().iterator()
                } catch(e) {}

                if (!caIterator.hasNext()) {
                    serverTransaction.sendResponse(this.messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, requestIn))
                    LOG.debug(requestIn)
                    return
                }

                // Fork the call if needed
                while(caIterator.hasNext()) {
                    const route = caIterator.next()
                    this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
                }
            } else {
                const route = location
                this.processRoute(requestIn, requestOut, route, serverTransaction, routeInfo)
            }

            return
        }
        LOG.debug(requestIn)
    }

    processRoute(requestIn, requestOut, route, serverTransaction, routeInfo) {
        requestOut.setRequestURI(route.contactURI)
        const routeHeader = requestIn.getHeader(RouteHeader.NAME)
        const rVia = requestIn.getHeader(ViaHeader.NAME)
        const transport = rVia.getTransport().toLowerCase()
        const lp = this.sipProvider.getListeningPoint(transport)
        const localPort = lp.getPort()
        const localIp = lp.getIPAddress().toString()
        const method = requestIn.getMethod()
        const rcvHost = route.contactURI.getHost()

        LOG.debug('contactURI is -> ' + route.contactURI)
        LOG.debug('Behind nat -> ' + route.nat)
        LOG.debug('rcvHost is -> ' + rcvHost)
        LOG.debug('sentByAddress -> ' + route.sentByAddress)
        LOG.debug('sentByPort -> ' + route.sentByPort)
        LOG.debug('received -> ' + route.received)
        LOG.debug('rport -> ' + route.rport)

        let advertisedAddr
        let advertisedPort

        // No egress routing has sentByAddress. They are assume to be entities outside the local network.
        if (this.config.spec.externAddr && (route.sentByAddress == undefined || !this.ipUtil.isLocalnet(route.sentByAddress))) {
            advertisedAddr = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[0] : this.config.spec.externAddr
            advertisedPort = this.config.spec.externAddr.contains(":") ? this.config.spec.externAddr.split(":")[1] : localPort
        }  else {
            advertisedAddr = localIp
            advertisedPort = localPort
        }

        LOG.debug('advertisedAddr is -> ' + advertisedAddr)
        LOG.debug('advertisedPort is -> ' + advertisedPort)

        // Remove route header if host is same as the proxy
        if (routeHeader) {
            const routeHeaderHost = routeHeader.getAddress().getURI().getHost()
            const routeHeaderPort = routeHeader.getAddress().getURI().getPort()
            if ((routeHeaderHost.equals(localIp) && routeHeaderPort.equals(localPort))
                || ((routeHeaderHost.equals(advertisedAddr) && routeHeaderPort.equals(advertisedPort)))) {
                requestOut.removeFirst(RouteHeader.NAME)
            }
        }

        // Stay in the signaling path
        if (this.config.spec.recordRoute) {
            const proxyURI = this.addressFactory.createSipURI(null, advertisedAddr)
            proxyURI.setLrParam()
            proxyURI.setPort(advertisedPort)
            const proxyAddress = this.addressFactory.createAddress(proxyURI)
            const recordRouteHeader = this.headerFactory.createRecordRouteHeader(proxyAddress)
            requestOut.addHeader(recordRouteHeader)
        }

        // Request RPort to enable Symmetric Response in accordance with RFC 3581 and RFC 6314
        const viaHeader = this.headerFactory.createViaHeader(advertisedAddr, advertisedPort, transport, null)
        viaHeader.setRPort()
        requestOut.addFirst(viaHeader)

        if (route.thruGw) {
            const fromHeader = requestIn.getHeader(FromHeader.NAME)
            const toHeader = requestIn.getHeader(ToHeader.NAME)
            const gwRefHeader = this.headerFactory.createHeader('X-Gateway-Ref', route.gwRef)
            const remotePartyIdHeader = this.headerFactory
                .createHeader('Remote-Party-ID', '<sip:'+ route.did + '@' + route.gwHost+ '>;screen=yes;party=calling')

            const from = 'sip:' + route.gwUsername + '@' + route.gwHost
            const to = 'sip:' + toHeader.getAddress().toString().match('sips?:(.*)@(.*)')[1] + '@' + route.gwHost

            // This might not work with all provider
            /*
              const fromAddress = this.addressFactory.createAddress(from)
              const toAddress = this.addressFactory.createAddress(to)
              fromHeader.setAddress(fromAddress)
              toHeader.setAddress(toAddress)
              requestOut.setHeader(fromHeader)
              requestOut.setHeader(toHeader)
            */

            requestOut.setHeader(gwRefHeader)
            requestOut.setHeader(remotePartyIdHeader)
        }

        requestOut.removeHeader("Proxy-Authorization")

        // Does not need a transaction
        if(method.equals(Request.ACK)) {
            this.sipProvider.sendRequest(requestOut)
        } else {
            try {
                // The request must be cloned or the stack will not fork the call
                const clientTransaction = this.sipProvider.getNewClientTransaction(requestOut.clone())
                clientTransaction.sendRequest()

                // Transaction context
                const context = new Context()
                context.clientTransaction = clientTransaction
                context.serverTransaction = serverTransaction
                context.method = method
                context.requestIn = requestIn
                context.requestOut = requestOut
                this.contextStorage.saveContext(context)
            } catch (e) {
                if (e instanceof java.net.ConnectException) {
                    LOG.error('Connection refused. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/ConnectException.html')
                } else if (e instanceof java.net.NoRouteToHostException) {
                    LOG.error('No route to host. Please see: https://docs.oracle.com/javase/7/docs/api/java/net/NoRouteToHostException.html')
                } else {
                    LOG.error(e.getMessage())
                }
            }
        }

        LOG.debug(requestOut)
    }

    authorized(request, serverTransaction) {
        const authHeader = request.getHeader(ProxyAuthorizationHeader.NAME)
        const fromHeader = request.getHeader(FromHeader.NAME)
        const fromURI = fromHeader.getAddress().getURI()

        // WARNING: Should limit the amount of attempts...
        if (authHeader == null) {
            const challengeResponse = this.messageFactory.createResponse(Response.PROXY_AUTHENTICATION_REQUIRED, request)
            this.dsam.generateChallenge(this.headerFactory, challengeResponse, "sipio")
            serverTransaction.sendResponse(challengeResponse)
            LOG.debug(request)
            return 'SENT_CHALLENGE'
        }

        // WARNING: If they are multiple peers with the same name this might be an issue
        let result = this.peersAPI.getPeer(authHeader.getUsername())

        let user

        if (result.status == Status.OK) {
            user = result.obj
        } else {
            // This is also a security check. The user in the authentication must exist for the 'fromURI.getHost()' domain
            result = this.agentsAPI.getAgent(fromURI.getHost(), authHeader.getUsername())
            if (result.status == Status.OK ) {
                user = result.obj
            }
        }

        if (!user || !this.dsam.doAuthenticatePlainTextPassword(request, user.spec.credentials.secret)) {
            return 'UNAUTHORIZED'
        }

        return 'AUTHORIZED'
    }

    /**
     * Discover DIDs sent via a non-standard header
     * The header must be added at config.spec.addressInfo[*]
     * If the such header is present then overwrite the AOR
     */
    getAOR (request) {
        for (let x in this.config.spec.addressInfo) {
            let info = this.config.spec.addressInfo[x]
            if (!!request.getHeader(info)) {
                let v = request.getHeader(info).getValue()
                if (/sips?:.*@.*/.test(v) || /tel:\d+/.test(v)) {
                    return this.addressFactory.createURI(v)
                }
                LOG.error('Invalid address: ' + v)
            }
        }
        return request.getHeader(ToHeader.NAME).getAddress().getURI()
    }
}
<|endoftext|>


<commit_before>const handleErrors = (response) => {
  if (!response.ok) {
    if (response.message) {
      throw Error(response.message);
    }
    throw Error(response.statusText);
  }
  return response;
};

export const getRepos = (username) => {
  let name = username.trim().toLowerCase();
  if (name === '') {
    return [];
  }
  return fetch(`https://api.github.com/users/${name}/repos`)
    .then(handleErrors)
    .then((response) => {return response.json()})
    .catch((error) => {
      console.error(error);
    })
};

<commit_msg>Add function to get readme Simple function that does a get request to get a GitHub's repo README file and receive the data as html<commit_after>const handleErrors = (response) => {
  if (!response.ok) {
    if (response.message) {
      throw Error(response.message);
    }
    throw Error(response.statusText);
  }
  return response;
};

export const getRepos = (username) => {
  let name = username.trim().toLowerCase();
  if (name === '') {
    return [];
  }
  return fetch(`https://api.github.com/users/${name}/repos`)
    .then(handleErrors)
    .then((response) => {return response.json()})
    .catch((error) => {
      console.error(error);
    });
};

export const getReadme = (url) => {
  let headers = new Headers();
  headers.append('Accept', 'application/vnd.github.VERSION.html');
  return fetch(`${url}/readme`, {headers})
    .then(handleErrors)
    .then((response => {return response.text()}))
    .catch((error) => {
      console.error(error);
    });
}

<|endoftext|>


<commit_before>import { version } from '../package.json';
import Alchemist from './alchemist.js';
import Parasite from './parasite.js';
import Nudist from './nudist.js';

let query = (object, property) => {
	let regexp = /[.{}]/g;
	let filter = (source) => { return source; };
	let reduce = (source, key) => { return source[key]; };

	return property
	.split(regexp)
	.filter(filter)
	.reduce(reduce, object);
};

let compile = (value, data) => {
	let regexp = /\{([^}]+)\}/g;
	let replacement = (original, property) => {
		return query(data, property);
	};

	value = value.trim();
	value = value.replace(regexp, replacement);
	console.log(value);
	return value;
};

let encoder = (data) => {
	return btoa(function() {
		var $ref = {};

		for (var key in data) {
			if (data.hasOwnProperty((key))) {
				$ref[key] = escape(data[key]);
			}
		}

		return JSON.stringify($ref);
	}());
}

// what we're actually dealing with.
export default class Template {
	constructor(element) {
		this.pipeline = [];
		this.mutators = [];

		this.sources = [];
		this.outputs = [];

		this.setElement(element);
	}

	get version() {
		return version;
	}

	getElement(element) {
		if (typeof Alchemist !== 'undefined') {
      element = Alchemist.asElement(element);
    }

		return element;
	}

	setElement(element) {
		element = this.getElement(element);

    this.element = element;

		return element;
	}

	fromEventSource(source) {
		// on 'data', <pipe>
	}

	fromPromise(action) {
		// then <pipe>
	}

	fromEvent(action) {
		// addEventListener 'click', <pipe>
	}

	fromData(data) {
		var tracker;

		tracker = {};
		tracker.source = source;
		tracker.passed = [];

		this.sources.push(tracker);

		return tracker;
	}

	fromHandler(handler) {
		// <pipe> addEventListener, 'click'
	}

	fromMutator(mutator) {
		// element level transformations
	}

	fromElement(element) {
		this.outputs.push(element);
	}

	route(connection) {
		this.pipeline.push(connection);
	}

	render() {
		let parser = ((previous, current) => {
			if (previous.passed.indexOf(current) !== -1) {
				return previous;
			}

			let response = current.call(previous, previous.source);

			previous.passed.push(current);

			if (response !== undefined && response !== null) {
				previous.source = response;
			}

			return previous;
		}).bind(this);

		for (let source of this.sources) {
			let cloned = this.element.cloneNode(true);
			let parsed = this.pipeline.reduce(parser, source);
			let genetics = ((input) => {
				return compile(input, parsed.source);
			});

			let parasite = new Parasite(genetics);
			let template = parasite.infect(cloned);

			// reduce across mutators

			template.rendered = encoder(parsed.source);

			for (let output of this.outputs) {
				var rendered;
				for (let child of output.childNodes) {
					if (child.rendered === template.rendered) {
						rendered = output.replaceChild(template, child);
					}
				}
				if (rendered === undefined) {
					output.appendChild(template);
				}
			}
		}
	}

	pipe(flow) {
		if (flow.constructor === Object) {
			this.fromData(flow);
		} else if (flow instanceof Element) {
			this.fromElement(flow);
		} else if (flow instanceof String) {
			this.fromElement(this.getElement(flow));
		} else {
			this.route.apply(this, arguments);
		}

		this.render();

		return this;
	}
}
<commit_msg>Export Parasite and Alchemist via Nudist<commit_after>import { version } from '../package.json';
import Alchemist from './alchemist.js';
import Parasite from './parasite.js';
import Nudist from './nudist.js';

let query = (object, property) => {
	let regexp = /[.{}]/g;
	let filter = (source) => { return source; };
	let reduce = (source, key) => { return source[key]; };

	return property
	.split(regexp)
	.filter(filter)
	.reduce(reduce, object);
};

let compile = (value, data) => {
	let regexp = /\{([^}]+)\}/g;
	let replacement = (original, property) => {
		return query(data, property);
	};

	value = value.trim();
	value = value.replace(regexp, replacement);
	console.log(value);
	return value;
};

let encoder = (data) => {
	return btoa(function() {
		var $ref = {};

		for (var key in data) {
			if (data.hasOwnProperty((key))) {
				$ref[key] = escape(data[key]);
			}
		}

		return JSON.stringify($ref);
	}());
}

// what we're actually dealing with.
export default class Template {
	constructor(element) {
		this.pipeline = [];
		this.mutators = [];

		this.sources = [];
		this.outputs = [];

		this.setElement(element);
	}

	get version() {
		return version;
	}

	getElement(element) {
		if (typeof Alchemist !== 'undefined') {
      element = Alchemist.asElement(element);
    }

		return element;
	}

	setElement(element) {
		element = this.getElement(element);

    this.element = element;

		return element;
	}

	fromEventSource(source) {
		// on 'data', <pipe>
	}

	fromPromise(action) {
		// then <pipe>
	}

	fromEvent(action) {
		// addEventListener 'click', <pipe>
	}

	fromData(data) {
		var tracker;

		tracker = {};
		tracker.source = source;
		tracker.passed = [];

		this.sources.push(tracker);

		return tracker;
	}

	fromHandler(handler) {
		// <pipe> addEventListener, 'click'
	}

	fromMutator(mutator) {
		// element level transformations
	}

	fromElement(element) {
		this.outputs.push(element);
	}

	route(connection) {
		this.pipeline.push(connection);
	}

	render() {
		let parser = ((previous, current) => {
			if (previous.passed.indexOf(current) !== -1) {
				return previous;
			}

			let response = current.call(previous, previous.source);

			previous.passed.push(current);

			if (response !== undefined && response !== null) {
				previous.source = response;
			}

			return previous;
		}).bind(this);

		for (let source of this.sources) {
			let cloned = this.element.cloneNode(true);
			let parsed = this.pipeline.reduce(parser, source);
			let genetics = ((input) => {
				return compile(input, parsed.source);
			});

			let parasite = new Parasite(genetics);
			let template = parasite.infect(cloned);

			// reduce across mutators

			template.rendered = encoder(parsed.source);

			for (let output of this.outputs) {
				var rendered;
				for (let child of output.childNodes) {
					if (child.rendered === template.rendered) {
						rendered = output.replaceChild(template, child);
					}
				}
				if (rendered === undefined) {
					output.appendChild(template);
				}
			}
		}
	}

	pipe(flow) {
		if (flow.constructor === Object) {
			this.fromData(flow);
		} else if (flow instanceof Element) {
			this.fromElement(flow);
		} else if (flow instanceof String) {
			this.fromElement(this.getElement(flow));
		} else {
			this.route.apply(this, arguments);
		}

		this.render();

		return this;
	}
}

new Nudist(Parasite);
new Nudist(Alchemist);
<|endoftext|>


<commit_before>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  var location, controller;
  beforeEach(inject(function($location, $controller) {
    location = $location;
    controller = $controller;
  }));

  describe("NewDeviceCtrl", function() {
    var scope;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    });

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    });

    describe("first page", function() {
      beforeEach(function() {
        httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
        controller('DevicesCtrl', { $scope: scope });
      });

      it("should setup pager", function() {
        httpBackend.flush();
        expect(scope.page).to.have.been.calledWith(1, 25, 2);
      });

      it("should call setNewURL", function() {
        expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
      });

      it("should fill devices", function() {
        httpBackend.flush();
        expect(scope.devices.length).to.equal(2);
        expect(scope.devices[0]._id).to.equal(1);
      });
    });

    describe("second page", function() {
      beforeEach(function() {
        location.search({page: 2});
        httpBackend.expectGET('/devices?page=2').respond([{_id: 26}, {_id: 27}, {count: 2}]);
        controller('DevicesCtrl', { $scope: scope });
      });

      it("should setup pager", function() {
        httpBackend.flush();
        expect(scope.page).to.have.been.calledWith(2, 25, 2);
      });
    });
  });

  describe("DeviceCtrl", function() {
    var scope, routeParams;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
        $on: sinon.spy(),
      };
      routeParams = { deviceId: 2 };
      httpBackend.expectGET('/devices/2').respond({_id: 2, name: "hello"});
      httpBackend.expectGET('/devices/2/setpoints').respond({a: 1, b: 2});
    });

    it("should clear pager", function() {
      controller('DeviceCtrl', { $scope: scope, $routeParams: routeParams });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<commit_msg>tests: ajax: show device 'new' button handling<commit_after>/* test/browser/device_controllers_test.js -- test Device angular controllers
 * Copyright 2014 Sergei Ianovich
 *
 * Licensed under AGPL-3.0 or later, see LICENSE
 * Process Control Service Web Interface
 */
'use strict'

describe("Device Controllers", function() {
  beforeEach(function() {
    angular.mock.module('pcs.services');
    angular.mock.module('pcs.controllers');
  });

  var httpBackend;

  beforeEach(inject(function($httpBackend) {
    httpBackend = $httpBackend;
  }));

  afterEach(function(){
    httpBackend.verifyNoOutstandingExpectation();
  });

  var location, controller;
  beforeEach(inject(function($location, $controller) {
    location = $location;
    controller = $controller;
  }));

  describe("NewDeviceCtrl", function() {
    var scope;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    });

    it("should clear pager", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should clear setNewURL", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.setNewURL).to.have.been.calledWith(null);
    });

    it("should create device in scope", function() {
      controller('NewDeviceCtrl', { $scope: scope });
      expect(scope.device).to.exist();
    });

    describe("#save", function() {
      beforeEach(function() {
        scope.deviceForm = {
          $setPristine: sinon.spy(),
        };

        httpBackend.expectPOST('/devices', { name: "hello" }).respond({_id: 2, name: "hello"});
        controller('NewDeviceCtrl', { $scope: scope });
        scope.device.name = "hello";
      });

      it("should save device", function() {
        scope.save();
      });

      it("should set the form pristine", function() {
        scope.save();
        httpBackend.flush();
        expect(scope.deviceForm.$setPristine).to.have.been.called;
      });

      it("should change location path", function() {
        scope.save();
        httpBackend.flush();
        expect(location.path()).to.equal('/devices/2');
      });
    });
  });

  describe("DevicesCtrl", function() {
    var scope;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
      };
    });

    describe("first page", function() {
      beforeEach(function() {
        httpBackend.expectGET('/devices?page=1').respond([{_id: 1}, {_id: 2}, {count: 2}]);
        controller('DevicesCtrl', { $scope: scope });
      });

      it("should setup pager", function() {
        httpBackend.flush();
        expect(scope.page).to.have.been.calledWith(1, 25, 2);
      });

      it("should call setNewURL", function() {
        expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
      });

      it("should fill devices", function() {
        httpBackend.flush();
        expect(scope.devices.length).to.equal(2);
        expect(scope.devices[0]._id).to.equal(1);
      });
    });

    describe("second page", function() {
      beforeEach(function() {
        location.search({page: 2});
        httpBackend.expectGET('/devices?page=2').respond([{_id: 26}, {_id: 27}, {count: 2}]);
        controller('DevicesCtrl', { $scope: scope });
      });

      it("should setup pager", function() {
        httpBackend.flush();
        expect(scope.page).to.have.been.calledWith(2, 25, 2);
      });
    });
  });

  describe("DeviceCtrl", function() {
    var scope, routeParams;

    beforeEach(function() {
      scope = {
        page: sinon.spy(),
        setNewURL: sinon.spy(),
        $on: sinon.spy(),
      };
      routeParams = { deviceId: 2 };
      httpBackend.expectGET('/devices/2').respond({_id: 2, name: "hello"});
      httpBackend.expectGET('/devices/2/setpoints').respond({a: 1, b: 2});
      controller('DeviceCtrl', { $scope: scope, $routeParams: routeParams });
    });

    it("should clear pager", function() {
      expect(scope.page).to.have.been.calledWith(1, 1, 0);
    });

    it("should call setNewURL with params", function() {
      expect(scope.setNewURL).to.have.been.calledWith('#/devices/new');
    });
  });
});
// vim:ts=2 sts=2 sw=2 et:
<|endoftext|>


<commit_before>/*global define*/
define(
	function()
	{
		var signals;
		var instructions = { };
		var valid_value_types = [ 'string', 'number' ];
		var valid_shapes = [ 'rect', 'circle', 'line' ];
		var reserved_keys = [ 'updated' ];
		var flush = false;

		function init( shared )
		{
			signals = shared.signals;

			signals['instructed'].add( checkInstructions );
			signals['looped'].add( drawInstructions );
			signals['input-updated'].add( flushInstructions );
		}

		function checkInstructions( obj )
		{
			if ( flush )
			{
				instructions = { };

				flush = false;
			}

			for ( var id in obj )
			{
				if ( isValidInstruction( obj[id] ) )
				{
					if ( instructions[id] )
					{
						updateInstruction( id, obj[id] );
					}

					else
					{
						addInstruction( id, obj[id] );
					}
				}

				else
				{
					removeInstruction( id );
				}
			}
		}

		function updateInstruction( id, obj )
		{
			var updated = false;

			for ( var key in obj )
			{
				var new_value = obj[key];

				if ( valid_value_types.indexOf( typeof new_value ) !== -1 )
				{
					updated = true;
					instructions[id][key] = new_value;
				}
			}

			instructions[id].updated = updated;
		}

		function addInstruction( id, obj )
		{
			instructions[id] = obj;
			instructions[id].updated = true;
		}

		function removeInstruction( id )
		{
			instructions[id] = undefined;
		}

		function flushInstructions()
		{
			flush = true;
		}

		function drawInstructions()
		{
			signals['draw'].dispatch( instructions );
		}

		function isValidInstruction( obj )
		{
			return ( typeof obj === 'object' && valid_shapes.indexOf( obj.shape ) !== -1 );
		}

		var i = {
			init: init
		};

		return i;
	}
);<commit_msg>flush intructions when new effect is selected<commit_after>/*global define*/
define(
	function()
	{
		var signals;
		var instructions = { };
		var valid_value_types = [ 'string', 'number' ];
		var valid_shapes = [ 'rect', 'circle', 'line' ];
		var reserved_keys = [ 'updated' ];
		var flush = false;

		function init( shared )
		{
			signals = shared.signals;

			signals['instructed'].add( checkInstructions );
			signals['looped'].add( drawInstructions );
			signals['input-updated'].add( flushInstructions );
			signals['effect-updated'].add( flushInstructions );
		}

		function checkInstructions( obj )
		{
			if ( flush )
			{
				instructions = { };

				flush = false;
			}

			for ( var id in obj )
			{
				if ( isValidInstruction( obj[id] ) )
				{
					if ( instructions[id] )
					{
						updateInstruction( id, obj[id] );
					}

					else
					{
						addInstruction( id, obj[id] );
					}
				}

				else
				{
					removeInstruction( id );
				}
			}
		}

		function updateInstruction( id, obj )
		{
			var updated = false;

			for ( var key in obj )
			{
				var new_value = obj[key];

				if ( valid_value_types.indexOf( typeof new_value ) !== -1 )
				{
					updated = true;
					instructions[id][key] = new_value;
				}
			}

			instructions[id].updated = updated;
		}

		function addInstruction( id, obj )
		{
			instructions[id] = obj;
			instructions[id].updated = true;
		}

		function removeInstruction( id )
		{
			instructions[id] = undefined;
		}

		function flushInstructions()
		{
			flush = true;
		}

		function drawInstructions()
		{
			signals['draw'].dispatch( instructions );
		}

		function isValidInstruction( obj )
		{
			return ( typeof obj === 'object' && valid_shapes.indexOf( obj.shape ) !== -1 );
		}

		var i = {
			init: init
		};

		return i;
	}
);<|endoftext|>