<commit_before>import memoize from "lodash/memoize";
import { connect } from "react-redux";
import countries from "i18n-iso-countries";
import * as messages from "locales.js";

// active ones get prioritised in the ui (pull downs)
// ISO 3166-1 Alpha-2 (upper case)
export const activeCountries = [
  "DK",
  "DE",
  "CH",
  "US",
  "IT",
  "AU",
  "NL",
  "FI",
  "CA",
  "SE",
  "BE",
  "SV",
  "BR",
  "ES",
  "MX",
  "GE" // georgia (but like tblisi, not like atlanta)
];
// ISO 639-1 (2 characters, lower case)
export const activeLanguages = [
  "da",
  "de",
  "en",
  "it",
  "nl",
  "fi",
  "fr",
  "sv",
  "pt",
  "es",
  "ka" // georgian
];

// load country names in our languages
activeLanguages.forEach(lang =>
  countries.registerLocale(require(`i18n-iso-countries/langs/${lang}.json`))
);

export const createFormatter = (...locales) => {
  const index = locales.reduceRight(Object.assign, {});

  const formatter = (key, replacements) => {
    let message = (index[key] && index[key].message) || `TK(${key})`;
    if (replacements) {
      Object.keys(replacements).forEach(replacementKey => {
        message = message.replace(
          `$${replacementKey}$`,
          replacements[replacementKey]
        );
      });
    }
    return message;
  };

  return formatter;
};

export const getFormatter = memoize(({ language, country }) =>
  createFormatter(
    messages[`${language}_${country}`],
    messages[language],
    messages.en // always fallback to English
  )
);

export const withI18n = connect(({ language }) => ({
  getMessage: getFormatter(language),
  language
}));

export const getBrowserLocale = () => {
  const lang = browser.i18n.getUILanguage()
    ? browser.i18n.getUILanguage()
    : navigator.languages && navigator.languages.length
      ? navigator.languages[0]
      : navigator.language;
  return {
    language: lang.split("-")[0],
    country: lang.split("-")[1]
  };
};
<commit_msg>oof, dumb bug jeremy; fixes the i18n call to actually work in Chrome<commit_after>import memoize from "lodash/memoize";
import { connect } from "react-redux";
import countries from "i18n-iso-countries";
import * as messages from "locales.js";

// active ones get prioritised in the ui (pull downs)
// ISO 3166-1 Alpha-2 (upper case)
export const activeCountries = [
  "DK",
  "DE",
  "CH",
  "US",
  "IT",
  "AU",
  "NL",
  "FI",
  "CA",
  "SE",
  "BE",
  "SV",
  "BR",
  "ES",
  "MX",
  "GE" // georgia (but like tblisi, not like atlanta)
];
// ISO 639-1 (2 characters, lower case)
export const activeLanguages = [
  "da",
  "de",
  "en",
  "it",
  "nl",
  "fi",
  "fr",
  "sv",
  "pt",
  "es",
  "ka" // georgian
];

// load country names in our languages
activeLanguages.forEach(lang =>
  countries.registerLocale(require(`i18n-iso-countries/langs/${lang}.json`))
);

export const createFormatter = (...locales) => {
  const index = locales.reduceRight(Object.assign, {});

  const formatter = (key, replacements) => {
    let message = (index[key] && index[key].message) || `TK(${key})`;
    if (replacements) {
      Object.keys(replacements).forEach(replacementKey => {
        message = message.replace(
          `$${replacementKey}$`,
          replacements[replacementKey]
        );
      });
    }
    return message;
  };

  return formatter;
};

export const getFormatter = memoize(({ language, country }) =>
  createFormatter(
    messages[`${language}_${country}`],
    messages[language],
    messages.en // always fallback to English
  )
);

export const withI18n = connect(({ language }) => ({
  getMessage: getFormatter(language),
  language
}));

export const getBrowserLocale = () => {
  const lang = chrome.i18n.getUILanguage()
    ? chrome.i18n.getUILanguage()
    : navigator.languages && navigator.languages.length
      ? navigator.languages[0]
      : navigator.language;
  return {
    language: lang.split("-")[0],
    country: lang.split("-")[1]
  };
};
<|endoftext|>


<commit_before>function addNote(url, note) {
  var noteObjects = getNotes(url);
  noteObjects.push(note);
  saveNotes(url, noteObjects);
}

function getNotes(url){
  if (localStorage[url] === undefined){
    return [];
  } else {
    var retrievedObject = localStorage.getItem(url);
    return JSON.parse(retrievedObject);
  }
}

function removeNote(url, seconds){
  var notes = JSON.parse(localStorage.getItem(url));
  var result = notes.map(function(note){
    if (note.seconds != seconds){
      return note
    }
  })
  saveNotes(url, result);
}

function saveNotes(url, notes) {
  localStorage[url] = JSON.stringify(notes);
}

Array.prototype.clean = function(deleteValue) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == deleteValue) {
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

window.onload = function(){
  var onButton = document.getElementById('on');
  var offButton = document.getElementById('off');

  if (localStorage.enabled === undefined) {
    localStorage.enabled = true;
  }

  onButton.addEventListener('click', function(){
    localStorage["enabled"] = true
  });

  offButton.addEventListener('click', function(){
    localStorage["enabled"] = false
  });
}

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
  var enabled = localStorage.enabled === "true"
  if (message.method === "add note"){
    addNote(message.url, message.note);
  }
  else if (message.method === "remove note"){
    removeNote(message.url, message.seconds);
  }
  sendResponse({notesArray: getNotes(message.url), enable: enabled});
});

chrome.browserAction.setPopup({popup: "popup.html"});

<commit_msg>forgot to call the clean function<commit_after>function addNote(url, note) {
  var noteObjects = getNotes(url);
  noteObjects.push(note);
  saveNotes(url, noteObjects);
}

function getNotes(url){
  if (localStorage[url] === undefined){
    return [];
  } else {
    var retrievedObject = localStorage.getItem(url);
    return JSON.parse(retrievedObject);
  }
}

function removeNote(url, seconds){
  var notes = JSON.parse(localStorage.getItem(url));
  var result = notes.map(function(note){
    if (note.seconds != seconds){
      return note
    }
  })
  result.clean(undefined);
  saveNotes(url, result);
}

function saveNotes(url, notes) {
  localStorage[url] = JSON.stringify(notes);
}

Array.prototype.clean = function(deleteValue) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == deleteValue) {
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

window.onload = function(){
  var onButton = document.getElementById('on');
  var offButton = document.getElementById('off');

  if (localStorage.enabled === undefined) {
    localStorage.enabled = true;
  }

  onButton.addEventListener('click', function(){
    localStorage["enabled"] = true
  });

  offButton.addEventListener('click', function(){
    localStorage["enabled"] = false
  });
}

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
  var enabled = localStorage.enabled === "true"
  if (message.method === "add note"){
    addNote(message.url, message.note);
  }
  else if (message.method === "remove note"){
    removeNote(message.url, message.seconds);
  }
  sendResponse({notesArray: getNotes(message.url), enable: enabled});
});

chrome.browserAction.setPopup({popup: "popup.html"});

<|endoftext|>


<commit_before>jest.mock('homedir');

import path from 'path';
import { TEST_ENV_DIR } from './test-constants';
import { newProject } from '../src/index';
import { dirExists, fileExists, filesDontExist } from './test-utils';

describe('Main functions test', () => {
  beforeEach(() => {
    // Silence all console logs
    console.log = () => {};
    console.error = () => {};
  });

  it('should create new project', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'newProjectTest');
    newProject('project-with-config', destination);

    expect(dirExists(destination)).toBe(true);
  });

  it('should copy files', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'copyFilesTest');
    newProject('project-with-file', destination);

    const filePath = path.resolve(destination, 'index.html');
    expect(fileExists(filePath)).toBe(true);
  });

  it('should emit excluded files', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'excludeFileTest');
    newProject('project-with-ignore', destination);

    const existingFilePath = path.resolve(destination, 'index.html');
    expect(fileExists(existingFilePath)).toBe(true);

    expect(filesDontExist(
      destination,
      'a.js',
      'b.js',
      'exclude-me.txt',
      'src/c.js'
    )).toBe(true);
  });

  it('should exit process when there is no such project', () => {
    const processExit = process.exit;
    process.exit = jest.fn();
    const destination = path.resolve(TEST_ENV_DIR, 'doesnt-matter');
    newProject('project-doesnt-exist', destination);
    expect(process.exit).toBeCalled();
    process.exit = processExit;
  });
});
<commit_msg>(test) restore console log function after tests<commit_after>jest.mock('homedir');

import path from 'path';
import { TEST_ENV_DIR } from './test-constants';
import { newProject } from '../src/index';
import { dirExists, fileExists, filesDontExist } from './test-utils';

describe('New project creation test', () => {
  let consoleLog;
  let consoleError;

  beforeAll(() => {
    // Silence console methods
    consoleLog = console.log;
    console.log = () => {};
    consoleError = console.error;
    console.error = () => {};
  });

  afterAll(() => {
    // Recover console methods
    console.log = consoleLog;
    console.error = consoleError;
  });

  it('should create new project', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'newProjectTest');
    newProject('project-with-config', destination);

    expect(dirExists(destination)).toBe(true);
  });

  it('should copy files', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'copyFilesTest');
    newProject('project-with-file', destination);

    const filePath = path.resolve(destination, 'index.html');
    expect(fileExists(filePath)).toBe(true);
  });

  it('should emit excluded files', () => {
    const destination = path.resolve(TEST_ENV_DIR, 'excludeFileTest');
    newProject('project-with-ignore', destination);

    const existingFilePath = path.resolve(destination, 'index.html');
    expect(fileExists(existingFilePath)).toBe(true);

    expect(filesDontExist(
      destination,
      'a.js',
      'b.js',
      'exclude-me.txt',
      'src/c.js'
    )).toBe(true);
  });

  it('should exit process when there is no such project', () => {
    const processExit = process.exit;
    process.exit = jest.fn();
    const destination = path.resolve(TEST_ENV_DIR, 'doesnt-matter');
    newProject('project-doesnt-exist', destination);
    expect(process.exit).toBeCalled();
    process.exit = processExit;
  });
});
<|endoftext|>


<commit_before>var registeredEvents = {};
var registerType = function(type) {
  if (typeof registeredEvents[e] !== 'object' || registeredEvents[e].constructor.name !== 'Array') {
    registeredEvents[e] = [];
  }
};
var isRegisteredEvent = function(type) {
  return (typeof registeredEvents[e] === 'object' && registeredEvents[e].constructor.name === 'Array');
};
var registerEvent = function(e, cb, args) {
  registeredEvents[e].push({cb: cb, args: args});
};
var triggerEvent = function(e, args) {
  registeredEvents[e].map(function(item) {
    item.cb(item.args);
  });
};
module.exports = function(System) {
  var plugin = {
    /**
     * The helper register method
     * @return {Void}
     */
    register: function () {
      return {
        on: function(e, cb, args) {
          registerType(e);
          registerEvent(e, cb, args);
        },
        trigger: function(e, args) {
          if (isRegisteredEvent(e)) {
            triggerEvent(e, args);
          }
        }
      };
    }
  };

  /**
   * Attributes to identify the plugin
   * @type {Object}
   */
  plugin.register.attributes = {
    name: 'Events Helper',
    key: 'event',
    version: '1.0.0'
  };
  return plugin;
};<commit_msg>Changes to event helper<commit_after>var registeredEvents = {};
var registerType = function(e) {
  if (typeof registeredEvents[e] !== 'object' || registeredEvents[e].constructor.name !== 'Array') {
    registeredEvents[e] = [];
  }
};
var isRegisteredEvent = function(e) {
  return (typeof registeredEvents[e] === 'object' && registeredEvents[e].constructor.name === 'Array');
};
var registerEvent = function(e, cb) {
  registeredEvents[e].push(cb);
};
var triggerEvent = function(e, args) {
  registeredEvents[e].map(function(cb) {
    cb(args);
  });
};
module.exports = function(System) {
  var plugin = {
    /**
     * The helper register method
     * @return {Void}
     */
    register: function () {
      return {
        on: function(e, cb, args) {
          registerType(e);
          registerEvent(e, cb, args);
        },
        trigger: function(e, args) {
          if (isRegisteredEvent(e)) {
            triggerEvent(e, args);
          }
        }
      };
    }
  };

  /**
   * Attributes to identify the plugin
   * @type {Object}
   */
  plugin.register.attributes = {
    name: 'Events Helper',
    key: 'event',
    version: '1.0.0'
  };
  return plugin;
};<|endoftext|>


<commit_before>module.exports = function killWorkers(workers, timeout, signal) {
  const killed = workers.map(worker => {
    if (worker.kill(signal, timeout)) {
      return worker.once('exit')
    }
  }).filter(p => p)

  return Promise.all(killed)
}
<commit_msg>update killWorkers<commit_after>/**
 * Kills all workers. Returns the number of killed workers.
 * @param {*} workers
 * @param {number} timeout
 * @param {string} signal
 * @returns {number}
 */
async function killWorkers(workers, timeout, signal) {
  const killed = workers.map(async worker => {
    if (worker.kill(signal, timeout)) {
      await worker.once('exit')
      return true
    }
    return false
  })

  const result = await Promise.all(killed)

  return result.filter(w => w).length
}

module.exports = killWorkers
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import Pane from 'part:@sanity/desk-tool/pane'
import TypePane from './pane/TypePane'
import EditorPane from './pane/EditorPane'
import TypePaneItem from './pane/TypePaneItem.js'
import QueryContainer from 'part:@sanity/base/query-container'

import dataAspects from './utils/dataAspects'
import schema from 'part:@sanity/base/schema'
import documentStore from 'part:@sanity/base/datastore/document'
import styles from './styles/SchemaPaneResolver.css'
import Preview from 'part:@sanity/base/preview'
import FullscreenDialog from 'part:@sanity/components/dialogs/fullscreen'
import StateLinkListItem from 'part:@sanity/components/lists/items/statelink'
import {withRouterHOC} from 'part:@sanity/base/router'
import elementResizeDetectorMaker from 'element-resize-detector'

// Debounce function on requestAnimationFrame
function debounceRAF(fn) {
  let scheduled
  return function debounced(...args) {
    if (!scheduled) {
      requestAnimationFrame(() => {
        fn.call(this, ...scheduled)
        scheduled = null
      })
    }
    scheduled = args
  }
}

const TYPE_ITEMS = dataAspects.getInferredTypes().map(typeName => ({
  key: typeName,
  name: typeName,
  title: dataAspects.getDisplayName(typeName)
}))

function readListLayoutSettings() {
  return JSON.parse(window.localStorage.getItem('desk-tool.listlayout-settings') || '{}')
}
function writeListLayoutSettings(settings) {
  window.localStorage.setItem('desk-tool.listlayout-settings', JSON.stringify(settings))
}

function isCreate(routerState) {
  return routerState.action === 'create' && !routerState.selectedDocumentId
}

function getListItemKey(item) {
  return item._id
}

export default withRouterHOC(class SchemaPaneResolver extends React.PureComponent {
  static propTypes = {
    router: PropTypes.shape({
      state: PropTypes.object
    })
  }

  state = {
    listLayoutSettings: readListLayoutSettings(),
    sorting: '_updatedAt desc',
    navTranslateX: 0,
    editorWidth: '100%',
    editorTranslateX: 0,
    navIsMinimized: false,
    navIsHovered: false,
    navIsClicked: false
  }

  hasBeenResized = false
  oldNavTranslateX = 0
  lastNavOffsetWidth = 0

  componentDidMount() {
    this.handleResize()
    window.addEventListener('resize', this.handleResize, false)
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize, false)
    this.erd.removeAllListeners(this.navigationElement)
    // this.erd.uninstall(this.navigationElement)
  }

  componentWillMount() {
    this.erd = elementResizeDetectorMaker({strategy: 'scroll'})
    const {router} = this.props
    if (isCreate(router.state)) {
      this.doCreate(router)
    }
  }

  componentWillReceiveProps(nextProps) {
    if (!isCreate(this.props.router.state) && isCreate(nextProps.router.state)) {
      this.doCreate(nextProps.router)
    }
  }

  componentDidUpdate() {
    // Hack
    // Panes needs to be resized after the content is loaded
    // Look at this later
    this.handleResize()
  }

  doCreate(router) {
    const {selectedType} = router.state
    documentStore.create({_type: selectedType})
      .subscribe(document => {
        router.navigate({
          selectedDocumentId: document._id,
          selectedType: selectedType,
          action: 'edit'
        }, {replace: true})
      })
  }

  renderTypePaneItem = item => {
    const {selectedType} = this.props.router.state
    const selected = item.name === selectedType
    return (
      <TypePaneItem
        key={item.key}
        selected={selected}
        type={item}
        onClick={this.handleItemClick}
      />
    )
  }

  renderDocumentPaneItem = (item, index, options) => {
    const {selectedType} = this.props.router.state
    const listLayout = this.getListLayoutForType(selectedType)
    const type = schema.get(selectedType)
    const linkState = {selectedDocumentId: item._id, selectedType: type.name, action: 'edit'}
    return (
      <StateLinkListItem
        state={linkState}
        highlighted={options.isHighlighted}
        selected={options.isSelected}
        hasFocus={options.hasFocus}
      >
        <Preview
          value={item}
          layout={listLayout}
          type={type}
        />
      </StateLinkListItem>
    )
  }

  getDocumentsPane(schemaType) {
    // todo: use this when order is implemented:
    // const query = `*[is $type] | order(${this.state.sorting}) [0...2000] {_id, _type}`
    const query = '*[is $type] [0...2000] {_id, _type}'
    const params = {type: schemaType.name}

    return (
      <QueryContainer query={query} params={params} type={schemaType} listLayout={this.getListLayoutForType(schemaType.name)}>
        {({result, loading, error, type, listLayout}) => {
          if (error) {
            return (
              <FullscreenDialog kind="danger" title="An error occurred while loading items" isOpen>
                {error.message}
              </FullscreenDialog>
            )
          }

          // Hack
          // Panes needs to be resized after the content is loaded
          // Look at this later
          if (!this.hasBeenResized) {
            this.handleResize()
          }

          const items = result ? result.documents : []
          return (
            <Pane
              contentType="documents"
              type={type}
              loading={loading}
              items={items}
              getItemKey={getListItemKey}
              renderItem={this.renderDocumentPaneItem}
              onSetListLayout={this.handleSetListLayout}
              onSetSorting={this.handleSetSort}
              listLayout={listLayout}
            />
          )
        }}
      </QueryContainer>
    )
  }

  handleSetListLayout = listLayout => {
    const {selectedType} = this.props.router.state
    const nextSettings = Object.assign(readListLayoutSettings(), {
      [selectedType]: listLayout
    })
    writeListLayoutSettings(nextSettings)
    this.setState({listLayoutSettings: nextSettings})
  }

  getListLayoutForType(typeName) {
    return this.state.listLayoutSettings[typeName] || 'default'
  }

  handleSetSort = sorting => {
    this.setState({
      sorting: sorting
    })
  }

  setContainerElement = element => {
    this.containerElement = element
  }

  setNavigationElement = element => {
    this.navigationElement = element
    if (this.navigationElement) {
      this.erd.listenTo(this.navigationElement, el => {
        if (el.offsetWidth != this.lastNavOffsetWidth) {
          this.lastNavOffsetWidth = el.offsetWidth
          this.handleResize()
        }
      })
    }
  }

  setEditorPaneElement = element => {
    this.editorPaneElement = element
  }

  canReposition = () => {
    const {selectedType, selectedDocumentId} = this.props.router.state
    return !!(this.navigationElement && this.editorPaneElement && this.containerElement && selectedType && selectedDocumentId)
  }

  resetPosition = () => {
    this.setState({
      navTranslateX: 0,
      editorWidth: '100%',
      navIsMinimized: false,
      editorTranslateX: 0
    })
  }

  handleResize = debounceRAF(() => {
    // Todo optimize later so that we dont resize when we dont need to
    // if (this.initialWindowWidth === window.innerWidth) {
    //   return
    // }

    const {selectedType, selectedDocumentId} = this.props.router.state
    if (!selectedDocumentId || !selectedType) {
      this.resetPosition()
      return
    }

    // Uses the css the determine if it should reposition with an Media Query
    // check if the window has resized
    const computedStyle = window.getComputedStyle(this.containerElement, '::before')
    const contentValue = computedStyle.getPropertyValue('content')
    this.shouldReposition = contentValue === '"shouldReposition"' || contentValue === 'shouldReposition' // Is quoted

    if (!this.shouldReposition || this.state.navIsHovered) {
      return
    }

    // Setup
    this.navWidth = this.navigationElement.offsetWidth
    const editorPaneWidth = this.editorPaneElement.offsetWidth
    const containerWidth = this.containerElement.offsetWidth
    let navTranslateX = 0
    let editorWidth = `${containerWidth - this.navWidth}px`

    // Setting dimensions based on font-size.
    this.padding = parseInt(window.getComputedStyle(document.body).fontSize, 10) * 3
    const editorPaneMinWidth = parseInt(window.getComputedStyle(this.editorPaneElement, null).minWidth, 10)

    const diff = containerWidth - editorPaneWidth - this.navWidth

    // Check if we need to push the navbar outside view
    if (diff <= 0) {
      navTranslateX = Math.min(containerWidth - editorPaneMinWidth - this.navWidth, 0)
      editorWidth = `${containerWidth - navTranslateX - this.navWidth}px`
    }

    // Set states that triggers re-render
    this.setState({
      navTranslateX: navTranslateX,
      navIsMinimized: navTranslateX < 0,
      editorWidth: editorWidth
    })

    return false
  })

  handlePanesMouseEnter = event => {
    const {navTranslateX} = this.state
    this.oldNavTranslateX = navTranslateX

    if (!this.state.navIsMinimized || !this.shouldReposition) {
      return
    }

    if (!this.canReposition() || !this.shouldReposition || navTranslateX == 0) {
      this.resetPosition()
      return
    }

    const x = 20

    this.setState({
      navTranslateX: navTranslateX + x,
      editorTranslateX: x,
      navIsHovered: true
    })

  }

  handlePanesMouseLeave = event => {
    if (this.shouldReposition) {
      this.setState({
        navTranslateX: Math.min(this.oldNavTranslateX, 0),
        editorTranslateX: 0,
        navIsHovered: false
      })
    }
  }

  handlePanesClick = event => {
    const {navWidth, oldNavTranslateX} = this
    const navVisibleWidth = navWidth + oldNavTranslateX
    if (this.shouldReposition) {
      this.setState({
        navTranslateX: 0,
        editorTranslateX: navWidth - navVisibleWidth,
        navIsMinimized: false,
        navIsClicked: true
      })
    }
  }

  render() {
    const {router} = this.props
    const {selectedType, selectedDocumentId} = router.state
    const {navTranslateX, editorTranslateX, editorWidth, navIsMinimized, navIsClicked} = this.state

    const typesPane = (
      <TypePane
        items={TYPE_ITEMS}
        renderItem={this.renderTypePaneItem}
      />
    )

    const schemaType = schema.get(router.state.selectedType)

    const documentsPane = schemaType ? this.getDocumentsPane(schemaType) : schemaType

    return (

        <div
          className={`
            ${navIsMinimized ? styles.navigationPanesContainerIsMinimized : styles.navigationPanesContainer}
            ${navIsClicked ? styles.navigationPanesContainerIsClicked : ''}
          `}
          ref={this.setNavigationElement}
          onClick={this.handlePanesClick}
          onMouseEnter={this.handlePanesMouseEnter}
          onMouseLeave={this.handlePanesMouseLeave}
          style={{
            transform: `translateX(${navTranslateX}px)`
          }}
        >
          {typesPane}
          {documentsPane}

        <div
          className={styles.editorContainer}
          ref={this.setEditorPaneElement}
          id="Sanity_Default_DeskTool_Editor_ScrollContainer"
          style={{
            width: editorWidth,
            transform: `translateX(${editorTranslateX}px)`
          }}
        >
          {
            schemaType && selectedDocumentId && (
              <EditorPane
                documentId={selectedDocumentId && selectedDocumentId}
                typeName={schemaType.name}
              />
            )
          }
          {selectedType && !schemaType && (

              Could not find any type
               named {selectedType} in
               schema {schema.name}…

          )}
          {!selectedType && (

Select a type to begin…

          )}

    )
  }
})
<commit_msg>[desk-tool] Make sorting work again<commit_after>import React, {PropTypes} from 'react'
import Pane from 'part:@sanity/desk-tool/pane'
import TypePane from './pane/TypePane'
import EditorPane from './pane/EditorPane'
import TypePaneItem from './pane/TypePaneItem.js'
import QueryContainer from 'part:@sanity/base/query-container'

import dataAspects from './utils/dataAspects'
import schema from 'part:@sanity/base/schema'
import documentStore from 'part:@sanity/base/datastore/document'
import styles from './styles/SchemaPaneResolver.css'
import Preview from 'part:@sanity/base/preview'
import FullscreenDialog from 'part:@sanity/components/dialogs/fullscreen'
import StateLinkListItem from 'part:@sanity/components/lists/items/statelink'
import {withRouterHOC} from 'part:@sanity/base/router'
import elementResizeDetectorMaker from 'element-resize-detector'

// Debounce function on requestAnimationFrame
function debounceRAF(fn) {
  let scheduled
  return function debounced(...args) {
    if (!scheduled) {
      requestAnimationFrame(() => {
        fn.call(this, ...scheduled)
        scheduled = null
      })
    }
    scheduled = args
  }
}

const TYPE_ITEMS = dataAspects.getInferredTypes().map(typeName => ({
  key: typeName,
  name: typeName,
  title: dataAspects.getDisplayName(typeName)
}))

function readListLayoutSettings() {
  return JSON.parse(window.localStorage.getItem('desk-tool.listlayout-settings') || '{}')
}
function writeListLayoutSettings(settings) {
  window.localStorage.setItem('desk-tool.listlayout-settings', JSON.stringify(settings))
}

function isCreate(routerState) {
  return routerState.action === 'create' && !routerState.selectedDocumentId
}

function getListItemKey(item) {
  return item._id
}

export default withRouterHOC(class SchemaPaneResolver extends React.PureComponent {
  static propTypes = {
    router: PropTypes.shape({
      state: PropTypes.object
    })
  }

  state = {
    listLayoutSettings: readListLayoutSettings(),
    sorting: '_updatedAt desc',
    navTranslateX: 0,
    editorWidth: '100%',
    editorTranslateX: 0,
    navIsMinimized: false,
    navIsHovered: false,
    navIsClicked: false
  }

  hasBeenResized = false
  oldNavTranslateX = 0
  lastNavOffsetWidth = 0

  componentDidMount() {
    this.handleResize()
    window.addEventListener('resize', this.handleResize, false)
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize, false)
    this.erd.removeAllListeners(this.navigationElement)
    // this.erd.uninstall(this.navigationElement)
  }

  componentWillMount() {
    this.erd = elementResizeDetectorMaker({strategy: 'scroll'})
    const {router} = this.props
    if (isCreate(router.state)) {
      this.doCreate(router)
    }
  }

  componentWillReceiveProps(nextProps) {
    if (!isCreate(this.props.router.state) && isCreate(nextProps.router.state)) {
      this.doCreate(nextProps.router)
    }
  }

  componentDidUpdate() {
    // Hack
    // Panes needs to be resized after the content is loaded
    // Look at this later
    this.handleResize()
  }

  doCreate(router) {
    const {selectedType} = router.state
    documentStore.create({_type: selectedType})
      .subscribe(document => {
        router.navigate({
          selectedDocumentId: document._id,
          selectedType: selectedType,
          action: 'edit'
        }, {replace: true})
      })
  }

  renderTypePaneItem = item => {
    const {selectedType} = this.props.router.state
    const selected = item.name === selectedType
    return (
      <TypePaneItem
        key={item.key}
        selected={selected}
        type={item}
        onClick={this.handleItemClick}
      />
    )
  }

  renderDocumentPaneItem = (item, index, options) => {
    const {selectedType} = this.props.router.state
    const listLayout = this.getListLayoutForType(selectedType)
    const type = schema.get(selectedType)
    const linkState = {selectedDocumentId: item._id, selectedType: type.name, action: 'edit'}
    return (
      <StateLinkListItem
        state={linkState}
        highlighted={options.isHighlighted}
        selected={options.isSelected}
        hasFocus={options.hasFocus}
      >
        <Preview
          value={item}
          layout={listLayout}
          type={type}
        />
      </StateLinkListItem>
    )
  }

  getDocumentsPane(schemaType) {
    const query = `*[is $type] | order(${this.state.sorting}) [0...2000] {_id, _type}`
    // const query = '*[is $type] [0...2000] {_id, _type}'
    const params = {type: schemaType.name}

    return (
      <QueryContainer query={query} params={params} type={schemaType} listLayout={this.getListLayoutForType(schemaType.name)}>
        {({result, loading, error, type, listLayout}) => {
          if (error) {
            return (
              <FullscreenDialog kind="danger" title="An error occurred while loading items" isOpen>
                {error.message}
              </FullscreenDialog>
            )
          }

          // Hack
          // Panes needs to be resized after the content is loaded
          // Look at this later
          if (!this.hasBeenResized) {
            this.handleResize()
          }

          const items = result ? result.documents : []
          return (
            <Pane
              contentType="documents"
              type={type}
              loading={loading}
              items={items}
              getItemKey={getListItemKey}
              renderItem={this.renderDocumentPaneItem}
              onSetListLayout={this.handleSetListLayout}
              onSetSorting={this.handleSetSort}
              listLayout={listLayout}
            />
          )
        }}
      </QueryContainer>
    )
  }

  handleSetListLayout = listLayout => {
    const {selectedType} = this.props.router.state
    const nextSettings = Object.assign(readListLayoutSettings(), {
      [selectedType]: listLayout
    })
    writeListLayoutSettings(nextSettings)
    this.setState({listLayoutSettings: nextSettings})
  }

  getListLayoutForType(typeName) {
    return this.state.listLayoutSettings[typeName] || 'default'
  }

  handleSetSort = sorting => {
    this.setState({
      sorting: sorting
    })
  }

  setContainerElement = element => {
    this.containerElement = element
  }

  setNavigationElement = element => {
    this.navigationElement = element
    if (this.navigationElement) {
      this.erd.listenTo(this.navigationElement, el => {
        if (el.offsetWidth != this.lastNavOffsetWidth) {
          this.lastNavOffsetWidth = el.offsetWidth
          this.handleResize()
        }
      })
    }
  }

  setEditorPaneElement = element => {
    this.editorPaneElement = element
  }

  canReposition = () => {
    const {selectedType, selectedDocumentId} = this.props.router.state
    return !!(this.navigationElement && this.editorPaneElement && this.containerElement && selectedType && selectedDocumentId)
  }

  resetPosition = () => {
    this.setState({
      navTranslateX: 0,
      editorWidth: '100%',
      navIsMinimized: false,
      editorTranslateX: 0
    })
  }

  handleResize = debounceRAF(() => {
    // Todo optimize later so that we dont resize when we dont need to
    // if (this.initialWindowWidth === window.innerWidth) {
    //   return
    // }

    const {selectedType, selectedDocumentId} = this.props.router.state
    if (!selectedDocumentId || !selectedType) {
      this.resetPosition()
      return
    }

    // Uses the css the determine if it should reposition with an Media Query
    // check if the window has resized
    const computedStyle = window.getComputedStyle(this.containerElement, '::before')
    const contentValue = computedStyle.getPropertyValue('content')
    this.shouldReposition = contentValue === '"shouldReposition"' || contentValue === 'shouldReposition' // Is quoted

    if (!this.shouldReposition || this.state.navIsHovered) {
      return
    }

    // Setup
    this.navWidth = this.navigationElement.offsetWidth
    const editorPaneWidth = this.editorPaneElement.offsetWidth
    const containerWidth = this.containerElement.offsetWidth
    let navTranslateX = 0
    let editorWidth = `${containerWidth - this.navWidth}px`

    // Setting dimensions based on font-size.
    this.padding = parseInt(window.getComputedStyle(document.body).fontSize, 10) * 3
    const editorPaneMinWidth = parseInt(window.getComputedStyle(this.editorPaneElement, null).minWidth, 10)

    const diff = containerWidth - editorPaneWidth - this.navWidth

    // Check if we need to push the navbar outside view
    if (diff <= 0) {
      navTranslateX = Math.min(containerWidth - editorPaneMinWidth - this.navWidth, 0)
      editorWidth = `${containerWidth - navTranslateX - this.navWidth}px`
    }

    // Set states that triggers re-render
    this.setState({
      navTranslateX: navTranslateX,
      navIsMinimized: navTranslateX < 0,
      editorWidth: editorWidth
    })

    return false
  })

  handlePanesMouseEnter = event => {
    const {navTranslateX} = this.state
    this.oldNavTranslateX = navTranslateX

    if (!this.state.navIsMinimized || !this.shouldReposition) {
      return
    }

    if (!this.canReposition() || !this.shouldReposition || navTranslateX == 0) {
      this.resetPosition()
      return
    }

    const x = 20

    this.setState({
      navTranslateX: navTranslateX + x,
      editorTranslateX: x,
      navIsHovered: true
    })

  }

  handlePanesMouseLeave = event => {
    if (this.shouldReposition) {
      this.setState({
        navTranslateX: Math.min(this.oldNavTranslateX, 0),
        editorTranslateX: 0,
        navIsHovered: false
      })
    }
  }

  handlePanesClick = event => {
    const {navWidth, oldNavTranslateX} = this
    const navVisibleWidth = navWidth + oldNavTranslateX
    if (this.shouldReposition) {
      this.setState({
        navTranslateX: 0,
        editorTranslateX: navWidth - navVisibleWidth,
        navIsMinimized: false,
        navIsClicked: true
      })
    }
  }

  render() {
    const {router} = this.props
    const {selectedType, selectedDocumentId} = router.state
    const {navTranslateX, editorTranslateX, editorWidth, navIsMinimized, navIsClicked} = this.state

    const typesPane = (
      <TypePane
        items={TYPE_ITEMS}
        renderItem={this.renderTypePaneItem}
      />
    )

    const schemaType = schema.get(router.state.selectedType)

    const documentsPane = schemaType ? this.getDocumentsPane(schemaType) : schemaType

    return (

        <div
          className={`
            ${navIsMinimized ? styles.navigationPanesContainerIsMinimized : styles.navigationPanesContainer}
            ${navIsClicked ? styles.navigationPanesContainerIsClicked : ''}
          `}
          ref={this.setNavigationElement}
          onClick={this.handlePanesClick}
          onMouseEnter={this.handlePanesMouseEnter}
          onMouseLeave={this.handlePanesMouseLeave}
          style={{
            transform: `translateX(${navTranslateX}px)`
          }}
        >
          {typesPane}
          {documentsPane}

        <div
          className={styles.editorContainer}
          ref={this.setEditorPaneElement}
          id="Sanity_Default_DeskTool_Editor_ScrollContainer"
          style={{
            width: editorWidth,
            transform: `translateX(${editorTranslateX}px)`
          }}
        >
          {
            schemaType && selectedDocumentId && (
              <EditorPane
                documentId={selectedDocumentId && selectedDocumentId}
                typeName={schemaType.name}
              />
            )
          }
          {selectedType && !schemaType && (

              Could not find any type
               named {selectedType} in
               schema {schema.name}…

          )}
          {!selectedType && (

Select a type to begin…

          )}

    )
  }
})
<|endoftext|>


<commit_before>module.exports = {
    "parser": "babel-eslint",
    "plugins": [
        "babel"
    ],
    "parserOptions": {
        "sourceType": "module"
    },
    "extends": [
        "@treblefm/rules/eslint/best-practices",
        "@treblefm/rules/eslint/errors",
        "@treblefm/rules/eslint/es6",
        "@treblefm/rules/eslint/node",
        "@treblefm/rules/eslint/strict",
        "@treblefm/rules/eslint/style",
        "@treblefm/rules/eslint/variables",
        "@treblefm/rules/babel"
    ]
};
<commit_msg>REALLY fix references<commit_after>module.exports = {
    "parser": "babel-eslint",
    "plugins": [
        "babel"
    ],
    "parserOptions": {
        "sourceType": "module"
    },
    "extends": [
        "@treblefm/eslint-config/rules/eslint/best-practices",
        "@treblefm/eslint-config/rules/eslint/errors",
        "@treblefm/eslint-config/rules/eslint/es6",
        "@treblefm/eslint-config/rules/eslint/node",
        "@treblefm/eslint-config/rules/eslint/strict",
        "@treblefm/eslint-config/rules/eslint/style",
        "@treblefm/eslint-config/rules/eslint/variables",
        "@treblefm/eslint-config/rules/babel"
    ]
};
<|endoftext|>


<commit_before>var vendormodels = {
  "8devices": {
    "Carambola Board 2": "8devices-carambola2-board"
  },

  "Alfa": {
    "AP121": {"alfa-ap121": "", "alfa-network-ap121": ""},
    "AP121U": {"alfa-ap121u": "", "alfa-network-ap121u": ""},
    "Hornet-UB": {"alfa-hornet-ub": "", "alfa-network-hornet-ub": ""},
    "Tube2H": {"alfa-tube2h": "", "alfa-network-tube2h": ""},
    "N2 / N5": {"alfa-n2-n5": "", "alfa-network-n2-n5": ""},
  },

  "Allnet": {
    "ALL0315N": "allnet-all0315n"
  },

  "Buffalo": {
    "WZR-600DHP": {"buffalo-wzr-600dhp": "v2"},
    "WZR-HP-AG300H": {"buffalo-wzr-hp-ag300h": "", "buffalo-wzr-hp-ag300h-wzr-600dhp": ""},
    "WZR-HP-G300H": {"buffalo-wzr-hp-g300h": ""},
    "WZR-HP-G300NH": {"buffalo-wzr-hp-g300nh": "v1", "buffalo-wzr-hp-g300nh2": "v2"},
    "WZR-HP-G450H": {"buffalo-wzr-hp-g450h": ""},
  },

  "D-Link": {
    "DIR-505": "d-link-dir-505-rev",
    "DIR-615": {"d-link-dir-615-c1": "c1/c2", "d-link-dir-615-rev-c1": "c1/c2",
                "d-link-dir-615-d": "d1-d4", "d-link-dir-615-e1": "e1/e2",
                "d-link-dir-615-e4": "e3-e5", "d-link-dir-615-h1": "h1/h2"},
    "DIR-825": "d-link-dir-825-rev",
    "DIR-860L": "d-link-dir-860l"
  },

  "GL Innovations": {
    "AR150": "gl-ar150",
    "iNet 6408a": "gl-inet-6408a",
    "iNet 6416a": "gl-inet-6416a"
  },

  "LeMaker": {
    "Banana Pi": "lemaker-banana-pi",
    "Banana Pro": "lemaker-banana-pro",
    "Banana Pi R1 (Lamobo)": {"lamobo-r1": "", "lemaker-lamobo-r1": ""}
  },

  "Linksys": {
    "WRT160NL": "linksys-wrt160nl",
    "WRT1200AC": "linksys-wrt1200ac"
  },

  "Meraki": {
    "MR12": "meraki-mr12",
    "MR16": "meraki-mr16",
    "MR62": "meraki-mr62",
    "MR66": "meraki-mr66"
  },

  "Mikrotik": {
    "vmlinux": {"mikrotik-vmlinux-lzma" : "", "mikrotik-vmlinux.lzma" : ""},
    "nand": {"mikrotik-nand-64m" : "64m", "mikrotik-nand-large" : "large"}
  },

  "Netgear": {
    "WNR2200": "netgear-wnr2200",
    "WNDR3700": {"netgear-wndr3700": "v1", "netgear-wndr3700v2": "v2", "netgear-wndr3700v3": "v3", "netgear-wndr3700v4": "v4"},
    "WNDR3800": "netgear-wndr3800",
    "WNDR4300": "netgear-wndr4300",
    "WNDRMAC": {"netgear-wndrmac": "v1", "netgear-wndrmacv2": "v2"},
  },

  "Onion": {
    "Omega": "onion-omega"
  },

  "Open-Mesh": {
    "MR1750": {"openmesh-mr1750": "v1", "openmesh-mr1750v2": "v2"},
    "MR600": {"openmesh-mr600": "v1", "openmesh-mr600v2": "v2"},
    "MR900": {"openmesh-mr900": "v1", "openmesh-mr900v2": "v2"},
    "OM2P HS": {"openmesh-om2p-hs": "v1", "openmesh-om2p-hsv3": "v3"},
    "OM2P LC": "openmesh-om2p-lc",
    "OM2P": {"openmesh-om2p": "v1", "openmesh-om2pv2": "v2"},
    "OM5P-AC": {"openmesh-om5p-ac": "v1", "openmesh-om5p-acv2": "v2"},
    "OM5P-AN": "openmesh-om5p-an",
    "OM5P": "openmesh-om5p"
  },

  "PC Engines": {
    "ALIX": "x86-geode"
  },

  "Raspberry Pi Foundation": {
    "PI": "raspberry-pi",
    "PI 2": "raspberry-pi-2"
  },

  "TP-Link": {
    "Archer C2600": {"tp-link-archer-c2600": "v1"},
    "Archer C5": {"tp-link-archer-c5": "v1"},
    "Archer C7": "tp-link-archer-c7",
    "CPE 210": {"tp-link-cpe210": "", "tp-link-cpe210-220": ""},
    "CPE 220": {"tp-link-cpe220": "", "tp-link-cpe210-220": ""},
    "CPE 510": {"tp-link-cpe510": "", "tp-link-cpe510-520": ""},
    "CPE 520": {"tp-link-cpe520": "", "tp-link-cpe510-520": ""},
    "WBS 210": "tp-link-wbs210",
    "WBS 510": "tp-link-wbs510",
    "RE450": "tp-link-re450",
    "TL-MR13U": "tp-link-tl-mr13u",
    "TL-MR3020": "tp-link-tl-mr3020",
    "TL-MR3040": "tp-link-tl-mr3040",
    "TL-MR3220": "tp-link-tl-mr3220",
    "TL-MR3420": "tp-link-tl-mr3420",
    "TL-WA701N/ND": {"tp-link-tl-wa701nd": "", "tp-link-tl-wa701n-nd": ""},
    "TL-WA7210N/ND": "tp-link-tl-wa7210n",
    "TL-WA730RE": "tp-link-tl-wa730re",
    "TL-WA750RE": "tp-link-tl-wa750re",
    "TL-WA7510N": "tp-link-tl-wa7510n",
    "TL-WA801N/ND": {"tp-link-tl-wa801n": "", "tp-link-tl-wa801n-nd": ""},
    "TL-WA830RE": "tp-link-tl-wa830re",
    "TL-WA850RE": "tp-link-tl-wa850re",
    "TL-WA860RE": "tp-link-tl-wa860re",
    "TL-WA901N/ND": {"tp-link-tl-wa901nd": "", "tp-link-tl-wa901n-nd": ""},
    "TL-WDR3500": "tp-link-tl-wdr3500",
    "TL-WDR3600": "tp-link-tl-wdr3600",
    "TL-WDR4300": "tp-link-tl-wdr4300",
    "TL-WDR4900": "tp-link-tl-wdr4900",
    "TL-WR1043N/ND": {"tp-link-tl-wr1043n-nd": ""},
    "TL-WR2543N/ND": {"tp-link-tl-wr2543n-nd": ""},
    "TL-WR703N": "tp-link-tl-wr703n",
    "TL-WR710N": "tp-link-tl-wr710n",
    "TL-WR740N/ND": "tp-link-tl-wr740n-nd",
    "TL-WR741N/ND": "tp-link-tl-wr741n-nd",
    "TL-WR743N/ND": "tp-link-tl-wr743n-nd",
    "TL-WR841N/ND": {"tp-link-tl-wr841n-nd": "", "tp-link-tl-wr841nd": ""},
    "TL-WR842N/ND": {"tp-link-tl-wr842n-nd": ""},
    "TL-WR843N/ND": {"tp-link-tl-wr843n-nd": ""},
    "TL-WR940N/ND": {"tp-link-tl-wr940n": "", "tp-link-tl-wr940n-nd": "", "tp-link-tl-wr941nd-v4": "v1", "tp-link-tl-wr941nd-v5": "v2", "tp-link-tl-wr941nd-v6": "v3"},
    "TL-WR941N/ND": {"tp-link-tl-wr941nd": "", "tp-link-tl-wr941n-nd": "", "tp-link-tl-wr941nd-v4": "v4", "tp-link-tl-wr941nd-v5": "v5", "tp-link-tl-wr941nd-v6": "v6"}
  },

  "Ubiquiti": {
    "AirGateway": {"ubnt-air-gateway": "", "ubiquiti-airgateway": "",
                   "ubiquiti-airgateway-lr": "LR", "ubiquiti-airgateway-pro": "Pro"},
    "AirRouter": {"ubnt-air-router": "", "ubiquiti-airrouter": ""},
    "AirRouter X": "ubnt-erx",
    "Bullet": {"ubiquiti-bullet-m2": "M2", "ubiquiti-bullet-m5": "M5", "bullet-m": "--ignore--"},
    "Litestation SR71": "ubiquiti-ls-sr71",
    "NanoStation Loco": {"ubiquiti-loco-m-xw": "--ignore--",
                         "ubiquiti-nanostation-loco-m2": "M2 XM", "ubiquiti-nanostation-loco-m2-xw": "M2 XW",
                         "ubiquiti-nanostation-loco-m5": "M5 XM", "ubiquiti-nanostation-loco-m5-xw": "M5 XW"},
    "NanoStation": {"ubiquiti-nanostation-m": "--ignore--", "ubiquiti-nano-m": "--ignore--", "ubiquiti-nanostation-m-xw": "--ignore--", "ubiquiti-nano-m-xw": "--ignore--",
                    "ubiquiti-nanostation-m2": "M2 XM", "ubiquiti-nano-m2": "M2 XM", "ubiquiti-nanostation-m2-xw": "M2 XW", "ubiquiti-nano-m2-xw": "M2 XW",
                    "ubiquiti-nanostation-m5": "M5 XM", "ubiquiti-nano-m5": "M5 XM", "ubiquiti-nanostation-m5-xw": "M5 XW", "ubiquiti-nano-m5-xw": "M5 XW"},
    "PicoStation": {"ubiquiti-picostation-m": "M",
                    "ubiquiti-picostation-m2": "M2"},
    "Rocket": {"ubiquiti-rocket-m": "M", "ubiquiti-rocket-m-xw": "M XW",
               "ubiquiti-rocket-m2": "M2", "ubiquiti-rocket-m2-xw": "M2 XW",
               "ubiquiti-rocket-m5": "M5", "ubiquiti-rocket-m5-xw": "M5 XW"},
    "Rocket Titanium": {"ubiquiti-rocket-m-ti": "--ignore--",
                        "ubiquiti-rocket-m2-ti": "M2",
                        "ubiquiti-rocket-m5-ti": "M5"},
    "UniFi AP": {"ubiquiti-unifi": "--ignore--", "ubiquiti-unifi-ap": ""},
    "UniFi AP LR": "ubiquiti-unifi-ap-lr",
    "UniFi AP Pro": "ubiquiti-unifi-ap-pro",
    "UniFi AP AC Pro": "ubiquiti-unifi-ac-pro",
    "UniFi AP AC Lite": "ubiquiti-unifi-ac-lite",
    "UniFi AP Outdoor": {"ubiquiti-unifi-outdoor": "", "ubiquiti-unifiap-outdoor": ""},
    "UniFi AP Outdoor+": {"ubiquiti-unifi-outdoor-plus": "", "ubiquiti-unifiap-outdoor\\\+": "", "ubiquiti-unifiap-outdoor%2B": "", "ubiquiti-unifiap-outdoor%2b": ""}
  },

  "VoCore": {
    "VoCore": "vocore",
    "VoCore 2": "vocore2"
  },

  "Western Digital": {
    "My Net N600": {"wd-my-net-n600": ""},
    "My Net N750": {"wd-my-net-n750": ""}
  },

  "x86": {
    "generic 32bit": "x86-generic",
    "generic 64bit": "x86-64",
    "VirtualBox 32bit": {"x86-virtualbox.vdi": "", "x86-generic.vdi": ""},
    "VirtualBox 64bit": {"x86-64-virtualbox.vdi": "", "x86-64.vdi": ""},
    "VMware 32bit": {"x86-vmware.vmdk": "", "x86-generic.vmdk": ""},
    "VMware 64bit": {"x86-64-vmware.vmdk": "", "x86-64-generic.vmdk": "",
                     "x86-64.vmdk": ""},
    "KVM 32bit": "x86-kvm",
    "XEN 32bit": "x86-xen",
  }
};
<commit_msg>Add support for Raspberry Pi 3<commit_after>var vendormodels = {
  "8devices": {
    "Carambola Board 2": "8devices-carambola2-board"
  },

  "Alfa": {
    "AP121": {"alfa-ap121": "", "alfa-network-ap121": ""},
    "AP121U": {"alfa-ap121u": "", "alfa-network-ap121u": ""},
    "Hornet-UB": {"alfa-hornet-ub": "", "alfa-network-hornet-ub": ""},
    "Tube2H": {"alfa-tube2h": "", "alfa-network-tube2h": ""},
    "N2 / N5": {"alfa-n2-n5": "", "alfa-network-n2-n5": ""},
  },

  "Allnet": {
    "ALL0315N": "allnet-all0315n"
  },

  "Buffalo": {
    "WZR-600DHP": {"buffalo-wzr-600dhp": "v2"},
    "WZR-HP-AG300H": {"buffalo-wzr-hp-ag300h": "", "buffalo-wzr-hp-ag300h-wzr-600dhp": ""},
    "WZR-HP-G300H": {"buffalo-wzr-hp-g300h": ""},
    "WZR-HP-G300NH": {"buffalo-wzr-hp-g300nh": "v1", "buffalo-wzr-hp-g300nh2": "v2"},
    "WZR-HP-G450H": {"buffalo-wzr-hp-g450h": ""},
  },

  "D-Link": {
    "DIR-505": "d-link-dir-505-rev",
    "DIR-615": {"d-link-dir-615-c1": "c1/c2", "d-link-dir-615-rev-c1": "c1/c2",
                "d-link-dir-615-d": "d1-d4", "d-link-dir-615-e1": "e1/e2",
                "d-link-dir-615-e4": "e3-e5", "d-link-dir-615-h1": "h1/h2"},
    "DIR-825": "d-link-dir-825-rev",
    "DIR-860L": "d-link-dir-860l"
  },

  "GL Innovations": {
    "AR150": "gl-ar150",
    "iNet 6408a": "gl-inet-6408a",
    "iNet 6416a": "gl-inet-6416a"
  },

  "LeMaker": {
    "Banana Pi": "lemaker-banana-pi",
    "Banana Pro": "lemaker-banana-pro",
    "Banana Pi R1 (Lamobo)": {"lamobo-r1": "", "lemaker-lamobo-r1": ""}
  },

  "Linksys": {
    "WRT160NL": "linksys-wrt160nl",
    "WRT1200AC": "linksys-wrt1200ac"
  },

  "Meraki": {
    "MR12": "meraki-mr12",
    "MR16": "meraki-mr16",
    "MR62": "meraki-mr62",
    "MR66": "meraki-mr66"
  },

  "Mikrotik": {
    "vmlinux": {"mikrotik-vmlinux-lzma" : "", "mikrotik-vmlinux.lzma" : ""},
    "nand": {"mikrotik-nand-64m" : "64m", "mikrotik-nand-large" : "large"}
  },

  "Netgear": {
    "WNR2200": "netgear-wnr2200",
    "WNDR3700": {"netgear-wndr3700": "v1", "netgear-wndr3700v2": "v2", "netgear-wndr3700v3": "v3", "netgear-wndr3700v4": "v4"},
    "WNDR3800": "netgear-wndr3800",
    "WNDR4300": "netgear-wndr4300",
    "WNDRMAC": {"netgear-wndrmac": "v1", "netgear-wndrmacv2": "v2"},
  },

  "Onion": {
    "Omega": "onion-omega"
  },

  "Open-Mesh": {
    "MR1750": {"openmesh-mr1750": "v1", "openmesh-mr1750v2": "v2"},
    "MR600": {"openmesh-mr600": "v1", "openmesh-mr600v2": "v2"},
    "MR900": {"openmesh-mr900": "v1", "openmesh-mr900v2": "v2"},
    "OM2P HS": {"openmesh-om2p-hs": "v1", "openmesh-om2p-hsv3": "v3"},
    "OM2P LC": "openmesh-om2p-lc",
    "OM2P": {"openmesh-om2p": "v1", "openmesh-om2pv2": "v2"},
    "OM5P-AC": {"openmesh-om5p-ac": "v1", "openmesh-om5p-acv2": "v2"},
    "OM5P-AN": "openmesh-om5p-an",
    "OM5P": "openmesh-om5p"
  },

  "PC Engines": {
    "ALIX": "x86-geode"
  },

  "Raspberry Pi Foundation": {
    "PI": "raspberry-pi",
    "PI 2": "raspberry-pi-2",
    "PI 3": "raspberry-pi-3"
  },

  "TP-Link": {
    "Archer C2600": {"tp-link-archer-c2600": "v1"},
    "Archer C5": {"tp-link-archer-c5": "v1"},
    "Archer C7": "tp-link-archer-c7",
    "CPE 210": {"tp-link-cpe210": "", "tp-link-cpe210-220": ""},
    "CPE 220": {"tp-link-cpe220": "", "tp-link-cpe210-220": ""},
    "CPE 510": {"tp-link-cpe510": "", "tp-link-cpe510-520": ""},
    "CPE 520": {"tp-link-cpe520": "", "tp-link-cpe510-520": ""},
    "WBS 210": "tp-link-wbs210",
    "WBS 510": "tp-link-wbs510",
    "RE450": "tp-link-re450",
    "TL-MR13U": "tp-link-tl-mr13u",
    "TL-MR3020": "tp-link-tl-mr3020",
    "TL-MR3040": "tp-link-tl-mr3040",
    "TL-MR3220": "tp-link-tl-mr3220",
    "TL-MR3420": "tp-link-tl-mr3420",
    "TL-WA701N/ND": {"tp-link-tl-wa701nd": "", "tp-link-tl-wa701n-nd": ""},
    "TL-WA7210N/ND": "tp-link-tl-wa7210n",
    "TL-WA730RE": "tp-link-tl-wa730re",
    "TL-WA750RE": "tp-link-tl-wa750re",
    "TL-WA7510N": "tp-link-tl-wa7510n",
    "TL-WA801N/ND": {"tp-link-tl-wa801n": "", "tp-link-tl-wa801n-nd": ""},
    "TL-WA830RE": "tp-link-tl-wa830re",
    "TL-WA850RE": "tp-link-tl-wa850re",
    "TL-WA860RE": "tp-link-tl-wa860re",
    "TL-WA901N/ND": {"tp-link-tl-wa901nd": "", "tp-link-tl-wa901n-nd": ""},
    "TL-WDR3500": "tp-link-tl-wdr3500",
    "TL-WDR3600": "tp-link-tl-wdr3600",
    "TL-WDR4300": "tp-link-tl-wdr4300",
    "TL-WDR4900": "tp-link-tl-wdr4900",
    "TL-WR1043N/ND": {"tp-link-tl-wr1043n-nd": ""},
    "TL-WR2543N/ND": {"tp-link-tl-wr2543n-nd": ""},
    "TL-WR703N": "tp-link-tl-wr703n",
    "TL-WR710N": "tp-link-tl-wr710n",
    "TL-WR740N/ND": "tp-link-tl-wr740n-nd",
    "TL-WR741N/ND": "tp-link-tl-wr741n-nd",
    "TL-WR743N/ND": "tp-link-tl-wr743n-nd",
    "TL-WR841N/ND": {"tp-link-tl-wr841n-nd": "", "tp-link-tl-wr841nd": ""},
    "TL-WR842N/ND": {"tp-link-tl-wr842n-nd": ""},
    "TL-WR843N/ND": {"tp-link-tl-wr843n-nd": ""},
    "TL-WR940N/ND": {"tp-link-tl-wr940n": "", "tp-link-tl-wr940n-nd": "", "tp-link-tl-wr941nd-v4": "v1", "tp-link-tl-wr941nd-v5": "v2", "tp-link-tl-wr941nd-v6": "v3"},
    "TL-WR941N/ND": {"tp-link-tl-wr941nd": "", "tp-link-tl-wr941n-nd": "", "tp-link-tl-wr941nd-v4": "v4", "tp-link-tl-wr941nd-v5": "v5", "tp-link-tl-wr941nd-v6": "v6"}
  },

  "Ubiquiti": {
    "AirGateway": {"ubnt-air-gateway": "", "ubiquiti-airgateway": "",
                   "ubiquiti-airgateway-lr": "LR", "ubiquiti-airgateway-pro": "Pro"},
    "AirRouter": {"ubnt-air-router": "", "ubiquiti-airrouter": ""},
    "AirRouter X": "ubnt-erx",
    "Bullet": {"ubiquiti-bullet-m2": "M2", "ubiquiti-bullet-m5": "M5", "bullet-m": "--ignore--"},
    "Litestation SR71": "ubiquiti-ls-sr71",
    "NanoStation Loco": {"ubiquiti-loco-m-xw": "--ignore--",
                         "ubiquiti-nanostation-loco-m2": "M2 XM", "ubiquiti-nanostation-loco-m2-xw": "M2 XW",
                         "ubiquiti-nanostation-loco-m5": "M5 XM", "ubiquiti-nanostation-loco-m5-xw": "M5 XW"},
    "NanoStation": {"ubiquiti-nanostation-m": "--ignore--", "ubiquiti-nano-m": "--ignore--", "ubiquiti-nanostation-m-xw": "--ignore--", "ubiquiti-nano-m-xw": "--ignore--",
                    "ubiquiti-nanostation-m2": "M2 XM", "ubiquiti-nano-m2": "M2 XM", "ubiquiti-nanostation-m2-xw": "M2 XW", "ubiquiti-nano-m2-xw": "M2 XW",
                    "ubiquiti-nanostation-m5": "M5 XM", "ubiquiti-nano-m5": "M5 XM", "ubiquiti-nanostation-m5-xw": "M5 XW", "ubiquiti-nano-m5-xw": "M5 XW"},
    "PicoStation": {"ubiquiti-picostation-m": "M",
                    "ubiquiti-picostation-m2": "M2"},
    "Rocket": {"ubiquiti-rocket-m": "M", "ubiquiti-rocket-m-xw": "M XW",
               "ubiquiti-rocket-m2": "M2", "ubiquiti-rocket-m2-xw": "M2 XW",
               "ubiquiti-rocket-m5": "M5", "ubiquiti-rocket-m5-xw": "M5 XW"},
    "Rocket Titanium": {"ubiquiti-rocket-m-ti": "--ignore--",
                        "ubiquiti-rocket-m2-ti": "M2",
                        "ubiquiti-rocket-m5-ti": "M5"},
    "UniFi AP": {"ubiquiti-unifi": "--ignore--", "ubiquiti-unifi-ap": ""},
    "UniFi AP LR": "ubiquiti-unifi-ap-lr",
    "UniFi AP Pro": "ubiquiti-unifi-ap-pro",
    "UniFi AP AC Pro": "ubiquiti-unifi-ac-pro",
    "UniFi AP AC Lite": "ubiquiti-unifi-ac-lite",
    "UniFi AP Outdoor": {"ubiquiti-unifi-outdoor": "", "ubiquiti-unifiap-outdoor": ""},
    "UniFi AP Outdoor+": {"ubiquiti-unifi-outdoor-plus": "", "ubiquiti-unifiap-outdoor\\\+": "", "ubiquiti-unifiap-outdoor%2B": "", "ubiquiti-unifiap-outdoor%2b": ""}
  },

  "VoCore": {
    "VoCore": "vocore",
    "VoCore 2": "vocore2"
  },

  "Western Digital": {
    "My Net N600": {"wd-my-net-n600": ""},
    "My Net N750": {"wd-my-net-n750": ""}
  },

  "x86": {
    "generic 32bit": "x86-generic",
    "generic 64bit": "x86-64",
    "VirtualBox 32bit": {"x86-virtualbox.vdi": "", "x86-generic.vdi": ""},
    "VirtualBox 64bit": {"x86-64-virtualbox.vdi": "", "x86-64.vdi": ""},
    "VMware 32bit": {"x86-vmware.vmdk": "", "x86-generic.vmdk": ""},
    "VMware 64bit": {"x86-64-vmware.vmdk": "", "x86-64-generic.vmdk": "",
                     "x86-64.vmdk": ""},
    "KVM 32bit": "x86-kvm",
    "XEN 32bit": "x86-xen",
  }
};
<|endoftext|>


<commit_before>import * as colors from 'colorette';
import { compose } from '../utils.js';
import { bold, underline } from 'colorette';
import { withMargin } from './utils.js';

const badge = (fn) => compose([fn, withMargin, String]);

export const createTheme = ({
  bgError = colors.bgRedBright,
  bgSuccess = colors.bgGreenBright,
  bgSkip = colors.bgYellowBright,
  disableFont = colors.gray,
  badgeFont = colors.whiteBright,
  adornerFont = colors.cyan,
} = {}) => {
  const success = compose([bgSuccess, badgeFont]);
  const error = compose([bgError, badgeFont]);
  return {
    errorBadge: badge(error),
    successBadge: badge(success),
    skipBadge: badge(compose([bgSkip, badgeFont])),
    disable: compose([disableFont, withMargin]),
    header: bold,
    adorner: adornerFont,
    emphasis: compose([underline, bold]),
    operator: adornerFont,
    light: disableFont,
    diffExpected: success,
    diffActual: error,
  };
};

export const dark = createTheme();

export const light = createTheme();
<commit_msg>Update Diff reporter theme (#100)<commit_after>import * as colors from 'colorette';
import { compose } from '../utils.js';
import { bold, underline } from 'colorette';
import { withMargin } from './utils.js';

const badge = (fn) => compose([fn, bold, withMargin, String]);

export const createTheme = ({
  bgError = colors.bgRed,
  bgSuccess = colors.bgGreen,
  bgSkip = colors.bgYellow,
  disableFont = colors.gray,
  badgeFont = colors.whiteBright,
  adornerFont = colors.cyan,
} = {}) => {
  const success = compose([bgSuccess, badgeFont]);
  const error = compose([bgError, badgeFont]);
  return {
    errorBadge: badge(error),
    successBadge: badge(success),
    skipBadge: badge(compose([bgSkip, badgeFont])),
    disable: compose([disableFont, withMargin]),
    header: bold,
    adorner: adornerFont,
    emphasis: compose([underline, bold]),
    operator: adornerFont,
    light: disableFont,
    diffExpected: success,
    diffActual: error,
  };
};

export const dark = createTheme();

export const light = createTheme();
<|endoftext|>


<commit_before>/*
 * Copyright © 2013 VillageReach.  All Rights Reserved.  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 *
 * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

describe("Facility Controller", function () {
  beforeEach(module('openlmis.services'));
  beforeEach(module('ui.bootstrap.dialog'));
  beforeEach(module('openlmis.localStorage'));

  describe("Create Facility", function () {
    var scope, $httpBackend, ctrl, routeParams, facility, messageService;

    beforeEach(inject(function ($rootScope, _$httpBackend_, $controller, $routeParams, _messageService_) {
      messageService = _messageService_;
      scope = $rootScope.$new();
      routeParams = $routeParams;
      $httpBackend = _$httpBackend_;
      var facilityReferenceData = {"facilityTypes": [
        {"type": "warehouse"}
      ], "programs": [
        {"code": "programCode", "id": "programId"}
      ], "geographicZones": [
        {"zoneId": "testId"}
      ], "facilityOperators": [
        {"operatorCode": "testCode"}
      ]};
      $rootScope.fixToolBar = function () {
      };
      ctrl = $controller(FacilityController, {$scope: scope, $routeParams: routeParams, facilityReferenceData: facilityReferenceData, facility: undefined,
        messageService: messageService});
      scope.facilityForm = {$error: { pattern: "" }};
    }));

    it('should set facility reference data', function () {
      expect(scope.facilityTypes).toEqual([
        {"type": "warehouse"}
      ]);
      expect(scope.facilityOperators).toEqual([
        {"operatorCode": "testCode"}
      ]);
      expect(scope.geographicZones).toEqual([
        {"zoneId": "testId"}
      ]);
      expect(scope.programs).toEqual([
        {"code": "programCode", "id": "programId"}
      ]);
    });

    it('should give success message if save successful', function () {
      facility = {"code": "code", supportedPrograms: []};
      $httpBackend.expectPOST('/facilities.json').respond(200, {"success": "Saved successfully", "facility": facility});
      scope.saveFacility();
      $httpBackend.flush();
      expect("Saved successfully").toEqual(scope.$parent.message);
      expect("").toEqual(scope.error);
    });

    it('should give error if save failed', function () {
      $httpBackend.expectPOST('/facilities.json').respond(404, {"error": "Save failed"});
      scope.saveFacility();
      $httpBackend.flush();
      expect("Save failed").toEqual(scope.error);
      expect("").toEqual(scope.message);
    });

    it('should give field validation error message if form has pattern errors', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.pattern = "{}";
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");
      expect("true").toEqual(scope.showError);
    });

    it('should give field validation error message if form has required errors', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.required = "{}";
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");
      expect("").toEqual(scope.message);
      expect("true").toEqual(scope.showError);
    });

    it('should not add program supported to facility if active program does not contain start date', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.required = "{}";
      scope.facility.supportedPrograms = [
        {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12"},
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true}
      ];
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");

      expect("").toEqual(scope.message);
      expect("true").toEqual(scope.showError);
    });

    it('should add program supported to facility', function () {
      scope.facility.supportedPrograms = [];
      var supportedProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "editedStartDate": "1/12/12", "program": {"id": "programId"}};

      scope.addSupportedProgram(supportedProgram);

      expect(scope.facility.supportedPrograms[0].code).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].name).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].active).toEqual(true);
      expect(scope.facility.supportedPrograms[0].program.id).toEqual("programId");
      expect(scope.supportedProgram).toBeUndefined();
    });

    it('should remove program supported to facility', function () {
      scope.facility.supportedPrograms = [];
      var arvProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12", "program": {"id": 1}};
      scope.facility.supportedPrograms = [
        arvProgram,
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 2}}
      ];

      scope.selectedSupportedProgram = arvProgram;

      scope.removeSupportedProgramConfirm(true);

      expect(scope.facility.supportedPrograms.length).toEqual(1);
      expect(scope.facility.supportedPrograms[0].code).toEqual("HIV");
      expect(scope.facility.supportedPrograms[0].program.id).toEqual(2);
      expect(scope.selectedSupportedProgram).toEqual(undefined);
    });

    it('should not remove program supported when not confirmed on dialog', function () {
      scope.facility.supportedPrograms = [];
      var arvProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12", "program": {"id": 1}};
      scope.facility.supportedPrograms = [
        arvProgram,
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 2}}
      ];

      scope.selectedSupportedProgram = arvProgram;

      scope.removeSupportedProgramConfirm(false);

      expect(scope.facility.supportedPrograms.length).toEqual(2);
      expect(scope.facility.supportedPrograms[0].code).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].program.id).toEqual(1);
      expect(scope.selectedSupportedProgram).toEqual(undefined);
    });

    it('should edit start date', function () {
      window.program = {'startDate': 2, 'editedStartDate': 7};
      scope.dateChangeCallback(true);
      expect(window.program.startDate).toEqual(7);
    });

    it('should reset old start date', function () {
      window.program = {'startDate': 2, 'editedStartDate': 7};
      scope.dateChangeCallback(false);
      expect(window.program.editedStartDate).toEqual(2);
    });
  });

  describe("Facility resolve", function () {
    var $httpBackend, ctrl, $timeout, $route;
    beforeEach(module('openlmis.services'));

    beforeEach(inject(function(_$httpBackend_, $controller, _$timeout_, _$route_) {
      $httpBackend = _$httpBackend_;
      $timeout = _$timeout_;
      ctrl = $controller;
      $route = _$route_;
    }))

    it('should get facility reference data', function () {
      $httpBackend.expect('GET', '/facilities/reference-data.json').respond({'id' : '23'});
      ctrl(FacilityController.resolve.facilityReferenceData, {});
      $timeout.flush();
    });

    it('should get facility if edit route contains id', function () {
      $route = {current: {params:{facilityId: 1}}};
      $httpBackend.expect('GET', '/facilities/1.json').respond({'id' : '23'});
      ctrl(FacilityController.resolve.facility, {$route: $route});
      $timeout.flush();
    });
  });

    describe("Edit/Delete Facility", function () {
      var scope, httpBackend;

      beforeEach(inject(function ($rootScope, _$httpBackend_, $controller, $routeParams) {
        httpBackend = _$httpBackend_;
        scope = $rootScope.$new();
        $rootScope.fixToolBar = function () {
        };
        var routeParams = $routeParams;
        routeParams.facilityId = "1";
        var facilityReferenceData = {"facilityTypes": [
          {"type": "warehouse"}
        ], "programs": [
          {"code": "ARV", "name": "ARV", "description": "ARV", "active": true},
          {"code": "HIV", "name": "HIV", "description": "HIV", "active": true},
          {"code": "ABC", "name": "ABC", "description": "ABC", "active": false}
        ],
          "geographicZones": [
            {"zoneId": "testId"}
          ], "facilityOperators": [
            {"operatorCode": "testCode"}
          ]};
        var facility = {"id": 1, "code": "F1756", "name": "Village Dispensary", "description": "IT department", "gln": "G7645", "mainPhone": "9876234981",
          "fax": "fax", "address1": "A", "address2": "B", "geographicZone": {"id": 1}, "facilityType": {"code": "warehouse"}, "catchmentPopulation": 333,
          "latitude": 22.1, "longitude": 1.2, "altitude": 3.3, "operatedBy": {"code": "NGO"}, "coldStorageGrossCapacity": 9.9, "coldStorageNetCapacity": 6.6,
          "suppliesOthers": true, "sdp": true, "hasElectricity": true, "online": true, "hasElectronicScc": true, "hasElectronicDar": null, "active": true,
          "goLiveDate": 1352572200000, "goDownDate": -2592106200000, "satellite": true, "satelliteParentId": null, "comment": "fc", "dataReportable": true,
          "supportedPrograms": [
            {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "program": {"id": 1}, "startDate": 1352572200000},
            {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 1}, "startDate": 1352572200000}
          ], "modifiedBy": null, "modifiedDate": null};
        $controller(FacilityController, {$scope: scope, $routeParams: routeParams, facilityReferenceData: facilityReferenceData, facility: facility});
        scope.facilityForm = {$error: { pattern: "" }};
      }));

      it('should get facility if defined', function () {
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.facility.supportedPrograms).toEqual([
          {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "program": {"id": 1}, "startDate": new Date(1352572200000)},
          {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 1}, "startDate": new Date(1352572200000)}
        ]);
      });

      it('should delete a facility', function () {
        httpBackend.expect('DELETE', '/facilities/1.json').respond(200, {"success": "Deleted successfully", "facility": scope.facility});

        scope.deleteFacilityCallBack(true);
        httpBackend.flush();

        expect(scope.message).toEqual("Deleted successfully");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should not delete a facility if error occurs', function () {
        httpBackend.expect('DELETE', '/facilities/1.json').respond(404, {"error": "something went wrong", "facility": scope.facility});

        scope.deleteFacilityCallBack(true);
        httpBackend.flush();

        expect(scope.error).toEqual("something went wrong");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should restore a facility', function () {
        httpBackend.expect('PUT', '/facilities/1/restore.json?active=true').respond(200, {"success": "Restored Successfully", "facility": scope.facility});

        scope.restoreFacility(true);
        httpBackend.flush();

        expect(scope.message).toEqual("Restored Successfully");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should not restore a facility if error occurs', function () {
        httpBackend.expect('PUT', '/facilities/1/restore.json?active=true').respond(400, {"error": "something went wrong", "facility": scope.facility});

        scope.restoreFacility(true);
        httpBackend.flush();

        expect(scope.error).toEqual("something went wrong");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });
    });
  });<commit_msg>|#0|Adding test for request and promise in facility resolve<commit_after>/*
 * Copyright © 2013 VillageReach.  All Rights Reserved.  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 *
 * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

describe("Facility Controller", function () {
  beforeEach(module('openlmis.services'));
  beforeEach(module('ui.bootstrap.dialog'));
  beforeEach(module('openlmis.localStorage'));

  describe("Create Facility", function () {
    var scope, $httpBackend, ctrl, routeParams, facility, messageService;

    beforeEach(inject(function ($rootScope, _$httpBackend_, $controller, $routeParams, _messageService_) {
      messageService = _messageService_;
      scope = $rootScope.$new();
      routeParams = $routeParams;
      $httpBackend = _$httpBackend_;
      var facilityReferenceData = {"facilityTypes": [
        {"type": "warehouse"}
      ], "programs": [
        {"code": "programCode", "id": "programId"}
      ], "geographicZones": [
        {"zoneId": "testId"}
      ], "facilityOperators": [
        {"operatorCode": "testCode"}
      ]};
      $rootScope.fixToolBar = function () {
      };
      ctrl = $controller(FacilityController, {$scope: scope, $routeParams: routeParams, facilityReferenceData: facilityReferenceData, facility: undefined,
        messageService: messageService});
      scope.facilityForm = {$error: { pattern: "" }};
    }));

    it('should set facility reference data', function () {
      expect(scope.facilityTypes).toEqual([
        {"type": "warehouse"}
      ]);
      expect(scope.facilityOperators).toEqual([
        {"operatorCode": "testCode"}
      ]);
      expect(scope.geographicZones).toEqual([
        {"zoneId": "testId"}
      ]);
      expect(scope.programs).toEqual([
        {"code": "programCode", "id": "programId"}
      ]);
    });

    it('should give success message if save successful', function () {
      facility = {"code": "code", supportedPrograms: []};
      $httpBackend.expectPOST('/facilities.json').respond(200, {"success": "Saved successfully", "facility": facility});
      scope.saveFacility();
      $httpBackend.flush();
      expect("Saved successfully").toEqual(scope.$parent.message);
      expect("").toEqual(scope.error);
    });

    it('should give error if save failed', function () {
      $httpBackend.expectPOST('/facilities.json').respond(404, {"error": "Save failed"});
      scope.saveFacility();
      $httpBackend.flush();
      expect("Save failed").toEqual(scope.error);
      expect("").toEqual(scope.message);
    });

    it('should give field validation error message if form has pattern errors', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.pattern = "{}";
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");
      expect("true").toEqual(scope.showError);
    });

    it('should give field validation error message if form has required errors', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.required = "{}";
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");
      expect("").toEqual(scope.message);
      expect("true").toEqual(scope.showError);
    });

    it('should not add program supported to facility if active program does not contain start date', function () {
      spyOn(messageService, 'get');
      scope.facilityForm.$error.required = "{}";
      scope.facility.supportedPrograms = [
        {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12"},
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true}
      ];
      scope.saveFacility();
      expect(messageService.get).toHaveBeenCalledWith("form.error");

      expect("").toEqual(scope.message);
      expect("true").toEqual(scope.showError);
    });

    it('should add program supported to facility', function () {
      scope.facility.supportedPrograms = [];
      var supportedProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "editedStartDate": "1/12/12", "program": {"id": "programId"}};

      scope.addSupportedProgram(supportedProgram);

      expect(scope.facility.supportedPrograms[0].code).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].name).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].active).toEqual(true);
      expect(scope.facility.supportedPrograms[0].program.id).toEqual("programId");
      expect(scope.supportedProgram).toBeUndefined();
    });

    it('should remove program supported to facility', function () {
      scope.facility.supportedPrograms = [];
      var arvProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12", "program": {"id": 1}};
      scope.facility.supportedPrograms = [
        arvProgram,
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 2}}
      ];

      scope.selectedSupportedProgram = arvProgram;

      scope.removeSupportedProgramConfirm(true);

      expect(scope.facility.supportedPrograms.length).toEqual(1);
      expect(scope.facility.supportedPrograms[0].code).toEqual("HIV");
      expect(scope.facility.supportedPrograms[0].program.id).toEqual(2);
      expect(scope.selectedSupportedProgram).toEqual(undefined);
    });

    it('should not remove program supported when not confirmed on dialog', function () {
      scope.facility.supportedPrograms = [];
      var arvProgram = {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "startDate": "1/12/12", "program": {"id": 1}};
      scope.facility.supportedPrograms = [
        arvProgram,
        {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 2}}
      ];

      scope.selectedSupportedProgram = arvProgram;

      scope.removeSupportedProgramConfirm(false);

      expect(scope.facility.supportedPrograms.length).toEqual(2);
      expect(scope.facility.supportedPrograms[0].code).toEqual("ARV");
      expect(scope.facility.supportedPrograms[0].program.id).toEqual(1);
      expect(scope.selectedSupportedProgram).toEqual(undefined);
    });

    it('should edit start date', function () {
      window.program = {'startDate': 2, 'editedStartDate': 7};
      scope.dateChangeCallback(true);
      expect(window.program.startDate).toEqual(7);
    });

    it('should reset old start date', function () {
      window.program = {'startDate': 2, 'editedStartDate': 7};
      scope.dateChangeCallback(false);
      expect(window.program.editedStartDate).toEqual(2);
    });
  });

  describe("Facility resolve", function () {
    var $httpBackend, ctrl, $timeout, $route, $q;
    var deferredObject;
    beforeEach(module('openlmis.services'));

    beforeEach(inject(function(_$httpBackend_, $controller, _$timeout_, _$route_) {
      $httpBackend = _$httpBackend_;
      deferredObject = {promise: {id: 1}, resolve: function () {}};
      spyOn(deferredObject, 'resolve');
      $q = {defer: function() {return deferredObject}};
      $timeout = _$timeout_;
      ctrl = $controller;
      $route = _$route_;
    }));

    it('should get facility reference data', function () {
      $httpBackend.expect('GET', '/facilities/reference-data.json').respond({facility: {'id' : '23'}});
      ctrl(FacilityController.resolve.facilityReferenceData, {$q: $q});
      $timeout.flush();
      $httpBackend.flush();
      expect(deferredObject.resolve).toHaveBeenCalled();
    });

    it('should get facility if edit route contains id', function () {
      $route = {current: {params:{facilityId: 1}}};
      $httpBackend.expect('GET', '/facilities/1.json').respond({'id' : '23'});
      ctrl(FacilityController.resolve.facility, {$route: $route});
      $timeout.flush();
    });
  });

    describe("Edit/Delete Facility", function () {
      var scope, httpBackend;

      beforeEach(inject(function ($rootScope, _$httpBackend_, $controller, $routeParams) {
        httpBackend = _$httpBackend_;
        scope = $rootScope.$new();
        $rootScope.fixToolBar = function () {
        };
        var routeParams = $routeParams;
        routeParams.facilityId = "1";
        var facilityReferenceData = {"facilityTypes": [
          {"type": "warehouse"}
        ], "programs": [
          {"code": "ARV", "name": "ARV", "description": "ARV", "active": true},
          {"code": "HIV", "name": "HIV", "description": "HIV", "active": true},
          {"code": "ABC", "name": "ABC", "description": "ABC", "active": false}
        ],
          "geographicZones": [
            {"zoneId": "testId"}
          ], "facilityOperators": [
            {"operatorCode": "testCode"}
          ]};
        var facility = {"id": 1, "code": "F1756", "name": "Village Dispensary", "description": "IT department", "gln": "G7645", "mainPhone": "9876234981",
          "fax": "fax", "address1": "A", "address2": "B", "geographicZone": {"id": 1}, "facilityType": {"code": "warehouse"}, "catchmentPopulation": 333,
          "latitude": 22.1, "longitude": 1.2, "altitude": 3.3, "operatedBy": {"code": "NGO"}, "coldStorageGrossCapacity": 9.9, "coldStorageNetCapacity": 6.6,
          "suppliesOthers": true, "sdp": true, "hasElectricity": true, "online": true, "hasElectronicScc": true, "hasElectronicDar": null, "active": true,
          "goLiveDate": 1352572200000, "goDownDate": -2592106200000, "satellite": true, "satelliteParentId": null, "comment": "fc", "dataReportable": true,
          "supportedPrograms": [
            {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "program": {"id": 1}, "startDate": 1352572200000},
            {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 1}, "startDate": 1352572200000}
          ], "modifiedBy": null, "modifiedDate": null};
        $controller(FacilityController, {$scope: scope, $routeParams: routeParams, facilityReferenceData: facilityReferenceData, facility: facility});
        scope.facilityForm = {$error: { pattern: "" }};
      }));

      it('should get facility if defined', function () {
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.facility.supportedPrograms).toEqual([
          {"code": "ARV", "name": "ARV", "description": "ARV", "active": true, "program": {"id": 1}, "startDate": new Date(1352572200000)},
          {"code": "HIV", "name": "HIV", "description": "HIV", "active": true, "program": {"id": 1}, "startDate": new Date(1352572200000)}
        ]);
      });

      it('should delete a facility', function () {
        httpBackend.expect('DELETE', '/facilities/1.json').respond(200, {"success": "Deleted successfully", "facility": scope.facility});

        scope.deleteFacilityCallBack(true);
        httpBackend.flush();

        expect(scope.message).toEqual("Deleted successfully");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should not delete a facility if error occurs', function () {
        httpBackend.expect('DELETE', '/facilities/1.json').respond(404, {"error": "something went wrong", "facility": scope.facility});

        scope.deleteFacilityCallBack(true);
        httpBackend.flush();

        expect(scope.error).toEqual("something went wrong");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should restore a facility', function () {
        httpBackend.expect('PUT', '/facilities/1/restore.json?active=true').respond(200, {"success": "Restored Successfully", "facility": scope.facility});

        scope.restoreFacility(true);
        httpBackend.flush();

        expect(scope.message).toEqual("Restored Successfully");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });

      it('should not restore a facility if error occurs', function () {
        httpBackend.expect('PUT', '/facilities/1/restore.json?active=true').respond(400, {"error": "something went wrong", "facility": scope.facility});

        scope.restoreFacility(true);
        httpBackend.flush();

        expect(scope.error).toEqual("something went wrong");
        expect(scope.facility.goLiveDate).toEqual(new Date(1352572200000));
        expect(scope.facility.goDownDate).toEqual(new Date(-2592106200000));
        expect(scope.originalFacilityCode).toEqual(scope.facility.code);
        expect(scope.originalFacilityName).toEqual(scope.facility.name);
      });
    });
  });<|endoftext|>