<commit_before>import * as React from 'react';
import PropTypes from 'prop-types';
import MuiError from '@mui/utils/macros/MuiError.macro';
import { GlobalStyles } from '@mui/styled-engine';
import { deepmerge } from '@mui/utils';
import createSpacing from '../createTheme/createSpacing';
import createBreakpoints from '../createTheme/createBreakpoints';
import cssVarsParser from './cssVarsParser';
import ThemeProvider from '../ThemeProvider';
import getInitColorSchemeScript, {
  DEFAULT_ATTRIBUTE,
  DEFAULT_MODE_STORAGE_KEY,
} from './getInitColorSchemeScript';
import useCurrentColorScheme from './useCurrentColorScheme';

export const DISABLE_CSS_TRANSITION =
  '*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}';

export default function createCssVarsProvider(options) {
  const {
    theme: baseTheme = {},
    defaultMode: desisgnSystemMode = 'light',
    defaultColorScheme: designSystemColorScheme,
    disableTransitionOnChange = false,
    enableColorScheme = true,
    prefix: designSystemPrefix = '',
    shouldSkipGeneratingVar,
  } = options;

  const systemSpacing = createSpacing(baseTheme.spacing);
  const systemBreakpoints = createBreakpoints(baseTheme.breakpoints ?? {});

  if (
    !baseTheme.colorSchemes ||
    (typeof designSystemColorScheme === 'string' &&
      !baseTheme.colorSchemes[designSystemColorScheme]) ||
    (typeof designSystemColorScheme === 'object' &&
      !baseTheme.colorSchemes[designSystemColorScheme?.light]) ||
    (typeof designSystemColorScheme === 'object' &&
      !baseTheme.colorSchemes[designSystemColorScheme?.dark])
  ) {
    console.error(`MUI: \`${designSystemColorScheme}\` does not exist in \`theme.colorSchemes\`.`);
  }
  const ColorSchemeContext = React.createContext(undefined);

  const useColorScheme = () => {
    const value = React.useContext(ColorSchemeContext);
    if (!value) {
      throw new MuiError('MUI: `useColorScheme` must be called under <CssVarsProvider />');
    }
    return value;
  };

  function CssVarsProvider({
    children,
    theme: themeProp = {},
    prefix = designSystemPrefix,
    modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
    attribute = DEFAULT_ATTRIBUTE,
    defaultMode = desisgnSystemMode,
    defaultColorScheme = designSystemColorScheme,
  }) {
    // make sure that baseTheme is always independent of each <CssVarsProvider /> call.
    // JSON.parse(JSON.stringify(...)) is okay to be used as long as the baseTheme is a plain object.
    const clonedBaseTheme = React.useMemo(() => JSON.parse(JSON.stringify(baseTheme)), []);

    const { colorSchemes: baseColorSchemes = {}, ...restBaseTheme } = clonedBaseTheme;
    const { colorSchemes: colorSchemesProp = {}, ...restThemeProp } = themeProp;
    const hasMounted = React.useRef(null);

    // eslint-disable-next-line prefer-const
    let { components = {}, ...mergedTheme } = deepmerge(restBaseTheme, restThemeProp);
    const colorSchemes = deepmerge(baseColorSchemes, colorSchemesProp);

    const allColorSchemes = Object.keys(colorSchemes);

    const defaultLightColorScheme =
      typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.light;
    const defaultDarkColorScheme =
      typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.dark;
    const {
      mode,
      setMode,
      systemMode,
      lightColorScheme,
      darkColorScheme,
      colorScheme,
      setColorScheme,
    } = useCurrentColorScheme({
      supportedColorSchemes: allColorSchemes,
      defaultLightColorScheme,
      defaultDarkColorScheme,
      modeStorageKey,
      defaultMode,
    });
    const resolvedColorScheme = (() => {
      if (!colorScheme) {
        // This scope occurs on the server
        if (defaultMode === 'dark') {
          return defaultDarkColorScheme;
        }
        // use light color scheme, if default mode is 'light' | 'auto'
        return defaultLightColorScheme;
      }
      return colorScheme;
    })();

    const { css: rootCss, vars: rootVars } = cssVarsParser(mergedTheme, {
      prefix,
      basePrefix: designSystemPrefix,
      shouldSkipGeneratingVar,
    });

    mergedTheme = {
      ...mergedTheme,
      ...colorSchemes[resolvedColorScheme],
      components,
      colorSchemes,
      vars: rootVars,
      spacing: themeProp.spacing ? createSpacing(themeProp.spacing) : systemSpacing,
      breakpoints: themeProp.breakpoints
        ? createBreakpoints(themeProp.breakpoints)
        : systemBreakpoints,
    };

    const styleSheet = {};

    Object.entries(colorSchemes).forEach(([key, scheme]) => {
      const { css, vars } = cssVarsParser(scheme, {
        prefix,
        basePrefix: designSystemPrefix,
        shouldSkipGeneratingVar,
      });
      mergedTheme.vars = deepmerge(mergedTheme.vars, vars);
      const resolvedDefaultColorScheme = (() => {
        if (typeof defaultColorScheme === 'string') {
          return defaultColorScheme;
        }
        if (defaultMode === 'dark') {
          return defaultColorScheme.dark;
        }
        return defaultColorScheme.light;
      })();
      if (key === resolvedDefaultColorScheme) {
        styleSheet[':root'] = css;
      } else {
        styleSheet[`[${attribute}="${key}"]`] = css;
      }
    });

    React.useEffect(() => {
      if (colorScheme) {
        // attaches attribute to <html> because the css variables are attached to :root (html)
        document.documentElement.setAttribute(attribute, colorScheme);
      }
    }, [colorScheme, attribute]);

    React.useEffect(() => {
      if (!mode || !enableColorScheme) {
        return undefined;
      }
      const priorColorScheme = document.documentElement.style.getPropertyValue('color-scheme');
      // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
      if (mode === 'system') {
        document.documentElement.style.setProperty('color-scheme', systemMode);
      } else {
        document.documentElement.style.setProperty('color-scheme', mode);
      }

      return () => {
        document.documentElement.style.setProperty('color-scheme', priorColorScheme);
      };
    }, [mode, systemMode]);

    React.useEffect(() => {
      let timer;
      if (disableTransitionOnChange && hasMounted.current) {
        // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313
        const css = document.createElement('style');
        css.appendChild(document.createTextNode(DISABLE_CSS_TRANSITION));
        document.head.appendChild(css);

        // Force browser repaint
        (() => window.getComputedStyle(document.body))();

        timer = setTimeout(() => {
          document.head.removeChild(css);
        }, 1);
      }
      return () => {
        clearTimeout(timer);
      };
    }, [colorScheme]);

    React.useEffect(() => {
      hasMounted.current = true;
    }, []);

    return (
      <ColorSchemeContext.Provider
        value={{
          mode,
          setMode,
          lightColorScheme,
          darkColorScheme,
          colorScheme,
          setColorScheme,
          allColorSchemes,
        }}
      >
        <GlobalStyles styles={{ ':root': rootCss }} />
        <GlobalStyles styles={styleSheet} />
        <ThemeProvider theme={mergedTheme}>{children}</ThemeProvider>
      </ColorSchemeContext.Provider>
    );
  }

  CssVarsProvider.propTypes = {
    /**
     * The body attribute name to attach colorScheme.
     */
    attribute: PropTypes.string,
    /**
     * The component tree.
     */
    children: PropTypes.node,
    /**
     * The initial color scheme used.
     */
    defaultColorScheme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    /**
     * The initial mode used.
     */
    defaultMode: PropTypes.string,
    /**
     * The key in the local storage used to store current color scheme.
     */
    modeStorageKey: PropTypes.string,
    /**
     * CSS variable prefix.
     */
    prefix: PropTypes.string,
    /**
     * The calculated theme object that will be passed through context.
     */
    theme: PropTypes.object,
  };

  return { CssVarsProvider, useColorScheme, getInitColorSchemeScript };
}
<commit_msg>[system] Don't transition when re-appearing (#30108)<commit_after>import * as React from 'react';
import PropTypes from 'prop-types';
import MuiError from '@mui/utils/macros/MuiError.macro';
import { GlobalStyles } from '@mui/styled-engine';
import { deepmerge } from '@mui/utils';
import createSpacing from '../createTheme/createSpacing';
import createBreakpoints from '../createTheme/createBreakpoints';
import cssVarsParser from './cssVarsParser';
import ThemeProvider from '../ThemeProvider';
import getInitColorSchemeScript, {
  DEFAULT_ATTRIBUTE,
  DEFAULT_MODE_STORAGE_KEY,
} from './getInitColorSchemeScript';
import useCurrentColorScheme from './useCurrentColorScheme';

export const DISABLE_CSS_TRANSITION =
  '*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}';

export default function createCssVarsProvider(options) {
  const {
    theme: baseTheme = {},
    defaultMode: desisgnSystemMode = 'light',
    defaultColorScheme: designSystemColorScheme,
    disableTransitionOnChange = false,
    enableColorScheme = true,
    prefix: designSystemPrefix = '',
    shouldSkipGeneratingVar,
  } = options;

  const systemSpacing = createSpacing(baseTheme.spacing);
  const systemBreakpoints = createBreakpoints(baseTheme.breakpoints ?? {});

  if (
    !baseTheme.colorSchemes ||
    (typeof designSystemColorScheme === 'string' &&
      !baseTheme.colorSchemes[designSystemColorScheme]) ||
    (typeof designSystemColorScheme === 'object' &&
      !baseTheme.colorSchemes[designSystemColorScheme?.light]) ||
    (typeof designSystemColorScheme === 'object' &&
      !baseTheme.colorSchemes[designSystemColorScheme?.dark])
  ) {
    console.error(`MUI: \`${designSystemColorScheme}\` does not exist in \`theme.colorSchemes\`.`);
  }
  const ColorSchemeContext = React.createContext(undefined);

  const useColorScheme = () => {
    const value = React.useContext(ColorSchemeContext);
    if (!value) {
      throw new MuiError('MUI: `useColorScheme` must be called under <CssVarsProvider />');
    }
    return value;
  };

  function CssVarsProvider({
    children,
    theme: themeProp = {},
    prefix = designSystemPrefix,
    modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
    attribute = DEFAULT_ATTRIBUTE,
    defaultMode = desisgnSystemMode,
    defaultColorScheme = designSystemColorScheme,
  }) {
    // make sure that baseTheme is always independent of each <CssVarsProvider /> call.
    // JSON.parse(JSON.stringify(...)) is okay to be used as long as the baseTheme is a plain object.
    const clonedBaseTheme = React.useMemo(() => JSON.parse(JSON.stringify(baseTheme)), []);

    const { colorSchemes: baseColorSchemes = {}, ...restBaseTheme } = clonedBaseTheme;
    const { colorSchemes: colorSchemesProp = {}, ...restThemeProp } = themeProp;
    const hasMounted = React.useRef(false);

    // eslint-disable-next-line prefer-const
    let { components = {}, ...mergedTheme } = deepmerge(restBaseTheme, restThemeProp);
    const colorSchemes = deepmerge(baseColorSchemes, colorSchemesProp);

    const allColorSchemes = Object.keys(colorSchemes);

    const defaultLightColorScheme =
      typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.light;
    const defaultDarkColorScheme =
      typeof defaultColorScheme === 'string' ? defaultColorScheme : defaultColorScheme.dark;
    const {
      mode,
      setMode,
      systemMode,
      lightColorScheme,
      darkColorScheme,
      colorScheme,
      setColorScheme,
    } = useCurrentColorScheme({
      supportedColorSchemes: allColorSchemes,
      defaultLightColorScheme,
      defaultDarkColorScheme,
      modeStorageKey,
      defaultMode,
    });
    const resolvedColorScheme = (() => {
      if (!colorScheme) {
        // This scope occurs on the server
        if (defaultMode === 'dark') {
          return defaultDarkColorScheme;
        }
        // use light color scheme, if default mode is 'light' | 'auto'
        return defaultLightColorScheme;
      }
      return colorScheme;
    })();

    const { css: rootCss, vars: rootVars } = cssVarsParser(mergedTheme, {
      prefix,
      basePrefix: designSystemPrefix,
      shouldSkipGeneratingVar,
    });

    mergedTheme = {
      ...mergedTheme,
      ...colorSchemes[resolvedColorScheme],
      components,
      colorSchemes,
      vars: rootVars,
      spacing: themeProp.spacing ? createSpacing(themeProp.spacing) : systemSpacing,
      breakpoints: themeProp.breakpoints
        ? createBreakpoints(themeProp.breakpoints)
        : systemBreakpoints,
    };

    const styleSheet = {};

    Object.entries(colorSchemes).forEach(([key, scheme]) => {
      const { css, vars } = cssVarsParser(scheme, {
        prefix,
        basePrefix: designSystemPrefix,
        shouldSkipGeneratingVar,
      });
      mergedTheme.vars = deepmerge(mergedTheme.vars, vars);
      const resolvedDefaultColorScheme = (() => {
        if (typeof defaultColorScheme === 'string') {
          return defaultColorScheme;
        }
        if (defaultMode === 'dark') {
          return defaultColorScheme.dark;
        }
        return defaultColorScheme.light;
      })();
      if (key === resolvedDefaultColorScheme) {
        styleSheet[':root'] = css;
      } else {
        styleSheet[`[${attribute}="${key}"]`] = css;
      }
    });

    React.useEffect(() => {
      if (colorScheme) {
        // attaches attribute to <html> because the css variables are attached to :root (html)
        document.documentElement.setAttribute(attribute, colorScheme);
      }
    }, [colorScheme, attribute]);

    React.useEffect(() => {
      if (!mode || !enableColorScheme) {
        return undefined;
      }
      const priorColorScheme = document.documentElement.style.getPropertyValue('color-scheme');
      // `color-scheme` tells browser to render built-in elements according to its value: `light` or `dark`
      if (mode === 'system') {
        document.documentElement.style.setProperty('color-scheme', systemMode);
      } else {
        document.documentElement.style.setProperty('color-scheme', mode);
      }

      return () => {
        document.documentElement.style.setProperty('color-scheme', priorColorScheme);
      };
    }, [mode, systemMode]);

    React.useEffect(() => {
      let timer;
      if (disableTransitionOnChange && hasMounted.current) {
        // credit: https://github.com/pacocoursey/next-themes/blob/b5c2bad50de2d61ad7b52a9c5cdc801a78507d7a/index.tsx#L313
        const css = document.createElement('style');
        css.appendChild(document.createTextNode(DISABLE_CSS_TRANSITION));
        document.head.appendChild(css);

        // Force browser repaint
        (() => window.getComputedStyle(document.body))();

        timer = setTimeout(() => {
          document.head.removeChild(css);
        }, 1);
      }
      return () => {
        clearTimeout(timer);
      };
    }, [colorScheme]);

    React.useEffect(() => {
      hasMounted.current = true;
      return () => {
        hasMounted.current = false;
      };
    }, []);

    return (
      <ColorSchemeContext.Provider
        value={{
          mode,
          setMode,
          lightColorScheme,
          darkColorScheme,
          colorScheme,
          setColorScheme,
          allColorSchemes,
        }}
      >
        <GlobalStyles styles={{ ':root': rootCss }} />
        <GlobalStyles styles={styleSheet} />
        <ThemeProvider theme={mergedTheme}>{children}</ThemeProvider>
      </ColorSchemeContext.Provider>
    );
  }

  CssVarsProvider.propTypes = {
    /**
     * The body attribute name to attach colorScheme.
     */
    attribute: PropTypes.string,
    /**
     * The component tree.
     */
    children: PropTypes.node,
    /**
     * The initial color scheme used.
     */
    defaultColorScheme: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    /**
     * The initial mode used.
     */
    defaultMode: PropTypes.string,
    /**
     * The key in the local storage used to store current color scheme.
     */
    modeStorageKey: PropTypes.string,
    /**
     * CSS variable prefix.
     */
    prefix: PropTypes.string,
    /**
     * The calculated theme object that will be passed through context.
     */
    theme: PropTypes.object,
  };

  return { CssVarsProvider, useColorScheme, getInitColorSchemeScript };
}
<|endoftext|>


<commit_before>var purely = {
    throwAssertionError: function(msg) {
        // throws TypeError as there isn't a built-in assertion error type
        throw TypeError('AssertionError: ' + msg);

        /*
            // Safer alternative?
            throw {
                name: 'TypeError',
                message: 'AssertionError: ' + x.toString() + ' === ' + y.toString()
            };
        */
    },

    contains: function(item, arr) {
        var found = false;

        for (var i = 0; i < arr.length; i++) {
            if (arr[i] == item) {
                found = true;
                break;
            }
        }

        return found;
    },

    assertEqual: function(x, y) {
        if (!(x === y)) {
            purely.throwAssertionError(x.toString() + ' === ' + y.toString());
        }
    },

    assertNotEqual: function(x, y) {
        if (!(x !== y)) {
            purely.throwAssertionError(x.toString() + ' !== ' + y.toString());
        }
    },

    assertGreater: function(x, y) {
        if (!(x > y)) {
            purely.throwAssertionError(x.toString() + ' > ' + y.toString());
        }
    },

    assertGreaterEqual: function(x, y) {
        if (!(x >= y)) {
            purely.throwAssertionError(x.toString() + ' >= ' + y.toString());
        }
    },

    assertLess: function(x, y) {
        if (!(x < y)) {
            purely.throwAssertionError(x.toString() + ' < ' + y.toString());
        }
    },

    assertLessEqual: function(x, y) {
        if (!(x <= y)) {
            purely.throwAssertionError(x.toString() + ' <= ' + y.toString());
        }
    },

    assertIn: function(item, arr) {
        var found = purely.contains(item, arr);

        if (!found) {
            purely.throwAssertionError(item.toString() + ' not in ' + arr.toString());
        }
    },

    assertNotIn: function(item, arr) {
        var found = purely.contains(item, arr);

        if (found) {
            purely.throwAssertionError(item.toString() + ' in ' + arr.toString());
        }
    }
}
<commit_msg>add missing semicolon<commit_after>var purely = {
    throwAssertionError: function(msg) {
        // throws TypeError as there isn't a built-in assertion error type
        throw TypeError('AssertionError: ' + msg);

        /*
            // Safer alternative?
            throw {
                name: 'TypeError',
                message: 'AssertionError: ' + x.toString() + ' === ' + y.toString()
            };
        */
    },

    contains: function(item, arr) {
        var found = false;

        for (var i = 0; i < arr.length; i++) {
            if (arr[i] == item) {
                found = true;
                break;
            }
        }

        return found;
    },

    assertEqual: function(x, y) {
        if (!(x === y)) {
            purely.throwAssertionError(x.toString() + ' === ' + y.toString());
        }
    },

    assertNotEqual: function(x, y) {
        if (!(x !== y)) {
            purely.throwAssertionError(x.toString() + ' !== ' + y.toString());
        }
    },

    assertGreater: function(x, y) {
        if (!(x > y)) {
            purely.throwAssertionError(x.toString() + ' > ' + y.toString());
        }
    },

    assertGreaterEqual: function(x, y) {
        if (!(x >= y)) {
            purely.throwAssertionError(x.toString() + ' >= ' + y.toString());
        }
    },

    assertLess: function(x, y) {
        if (!(x < y)) {
            purely.throwAssertionError(x.toString() + ' < ' + y.toString());
        }
    },

    assertLessEqual: function(x, y) {
        if (!(x <= y)) {
            purely.throwAssertionError(x.toString() + ' <= ' + y.toString());
        }
    },

    assertIn: function(item, arr) {
        var found = purely.contains(item, arr);

        if (!found) {
            purely.throwAssertionError(item.toString() + ' not in ' + arr.toString());
        }
    },

    assertNotIn: function(item, arr) {
        var found = purely.contains(item, arr);

        if (found) {
            purely.throwAssertionError(item.toString() + ' in ' + arr.toString());
        }
    }
};
<|endoftext|>


<commit_before>import React from 'react-native'
import Button from '../_lib/button/'
import style from './style'

const {View, TextInput, NativeModules, TouchableOpacity, Text} = React

export default class Draft extends React.Component {
  componentWillMount() {
    this.setState({title: ''})
  }

  render() {
    return <View style={style.container}>
      <View style={style.toolbar}>
        <TouchableOpacity onPress={this._onCancel.bind(this)} >
          <View style={style.button}>
            <Text style={style.buttonText}>
              ✖
            </Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._onAccept.bind(this)} >
          <View style={style.button}>
            <Text style={style.buttonText}>
              ✔
            </Text>
          </View>
        </TouchableOpacity>
      </View>
      <View style={style.form}>
        <TextInput
          style={style.title}
          onChangeText={(title) => this.setState({title})}
          value={this.state.title}
          placeholder={'Title'}
        />
      </View>
    </View>
  }

  _onAccept() {
    const {title} = this.state
    NativeModules.Microphone.processTitle(title, (text) => {
      this.props.createRecord({
        title: text,
        filename: this.props.filename
      })
      this.props.navigateToUser()
    })
  }

  _onCancel() {
    this.props.navigateToUser()
  }
}
<commit_msg>Remove legacy import<commit_after>import React from 'react-native'
import style from './style'

const {View, TextInput, NativeModules, TouchableOpacity, Text} = React

export default class Draft extends React.Component {
  componentWillMount() {
    this.setState({title: ''})
  }

  render() {
    return <View style={style.container}>
      <View style={style.toolbar}>
        <TouchableOpacity onPress={this._onCancel.bind(this)} >
          <View style={style.button}>
            <Text style={style.buttonText}>
              ✖
            </Text>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={this._onAccept.bind(this)} >
          <View style={style.button}>
            <Text style={style.buttonText}>
              ✔
            </Text>
          </View>
        </TouchableOpacity>
      </View>
      <View style={style.form}>
        <TextInput
          style={style.title}
          onChangeText={(title) => this.setState({title})}
          value={this.state.title}
          placeholder={'Title'}
        />
      </View>
    </View>
  }

  _onAccept() {
    const {title} = this.state
    NativeModules.Microphone.processTitle(title, (text) => {
      this.props.createRecord({
        title: text,
        filename: this.props.filename
      })
      this.props.navigateToUser()
    })
  }

  _onCancel() {
    this.props.navigateToUser()
  }
}
<|endoftext|>


<commit_before>'use strict';

const metricsService = require('../metrics');

describe('Metrics', () => {
  test('sendDidInviteUser', async () => {
    const send = jest.fn(() => Promise.resolve());
    const countUsers = jest.fn(() => Promise.resolve(2));
    const countRoles = jest.fn(() => Promise.resolve(3));
    global.strapi = {
      telemetry: { send },
      admin: {
        services: {
          user: { count: countUsers },
          role: { count: countRoles },
        },
      },
    };

    await metricsService.sendDidInviteUser();

    expect(send).toHaveBeenCalledWith('didInviteUser', { numberOfRoles: 3, numberOfUsers: 2 });
  });
});
<commit_msg>enrich test<commit_after>'use strict';

const metricsService = require('../metrics');

describe('Metrics', () => {
  test('sendDidInviteUser', async () => {
    const send = jest.fn(() => Promise.resolve());
    const countUsers = jest.fn(() => Promise.resolve(2));
    const countRoles = jest.fn(() => Promise.resolve(3));
    global.strapi = {
      telemetry: { send },
      admin: {
        services: {
          user: { count: countUsers },
          role: { count: countRoles },
        },
      },
    };

    await metricsService.sendDidInviteUser();

    expect(send).toHaveBeenCalledWith('didInviteUser', { numberOfRoles: 3, numberOfUsers: 2 });
    expect(countUsers).toHaveBeenCalledWith();
    expect(countRoles).toHaveBeenCalledWith();
  });
});
<|endoftext|>


<commit_before>angular.module('cpitt.promisePoller', [])

  .factory('PollerFactory',
    [        '$interval', '$q',
    function( $interval,   $q ){
      var Poller = function (pollerFunction, freq, callback){
        this.pollerFunction = pollerFunction;
        this.freq = freq;
        this.callback = callback;
        //wrap the function or promise in a new promise
        this.pollerPromise = $q.when(pollerFunction);
      }

      Poller.prototype.start = function() {
        var self = this,
            run  = true;
        var tick = function(){
          if(run){
              run = false
              self.pollerPromise.then(function(result){
                run = true;
                self.callback(result);
                self.pollerPromise = $q.when(self.pollerFunction()); //reset the promise
              })
          }
        }
        this.intervalPromise = $interval(tick, this.freq);
      }

      Poller.prototype.stop = function(){
        if(angular.isDefined(this.intervalPromise)){
          $interval.cancel(this.intervalPromise);
          this.interval = undefined;
        }
      }

      Poller.prototype.restart = function(){
        this.stop();
        this.start();
      }

      return {
         newPoller: function(pollerFunction, freq, callback){return new Poller(pollerFunction, freq, callback)}
      }
    }]
  )

  .service('PollerService',
    [        'PollerFactory',
    function( PollerFactory ){
      this.pollers = [];

      this.create = function(pollerFunction, freq, callback){
        poller = PollerFactory.newPoller(pollerFunction, freq, callback)
        this.pollers.push(poller)
        poller.start()
        return poller;
      }

      this.restartAll = function(){
        angular.forEach(this.pollers, function(poller){
          poller.restart();
        })
      }

      this.stopAll = function(){
        angular.forEach(this.pollers, function(poller){
          poller.stop();
        })
      }
    }]
  )
<commit_msg>better typecasting<commit_after>angular.module('cpitt.promisePoller', [])

  .factory('PollerFactory',
    [        '$interval', '$q',
    function( $interval,   $q ){
      var Poller = function (pollerFunction, freq, callback){
        this.pollerFunction = pollerFunction;
        this.freq = freq;
        this.callback = callback;

        this.createPollerPromise = function(){
          return typeof pollerFunction === 'function' ? $q.when(pollerFunction()) : $q.when(pollerFunction);
        }

        this.pollerPromise = this.createPollerPromise();
      }

      Poller.prototype.start = function() {
        var self = this,
            run  = true;
        var tick = function(){
          if(run){
              run = false
              self.pollerPromise.then(function(result){
                run = true;
                self.callback(result);
                self.pollerPromise = self.createPollerPromise();
              })
          }
        }
        this.intervalPromise = $interval(tick, this.freq);
      }

      Poller.prototype.stop = function(){
        if(angular.isDefined(this.intervalPromise)){
          $interval.cancel(this.intervalPromise);
          this.interval = undefined;
        }
      }

      Poller.prototype.restart = function(){
        this.stop();
        this.start();
      }

      return {
         newPoller: function(pollerFunction, freq, callback){return new Poller(pollerFunction, freq, callback)}
      }
    }]
  )

  .service('PollerService',
    [        'PollerFactory',
    function( PollerFactory ){
      this.pollers = [];

      this.create = function(pollerFunction, freq, callback){
        poller = PollerFactory.newPoller(pollerFunction, freq, callback)
        this.pollers.push(poller)
        poller.start()
        return poller;
      }

      this.restartAll = function(){
        angular.forEach(this.pollers, function(poller){
          poller.restart();
        })
      }

      this.stopAll = function(){
        angular.forEach(this.pollers, function(poller){
          poller.stop();
        })
      }
    }]
  )
<|endoftext|>


<commit_before>var TestCase = require("mocha/lib/test.js");
var Suite = require("mocha/lib/suite.js");
var Deployer = require("truffle-migrate-legacy/node_modules/truffle-deployer");
var find_contracts = require("truffle-contract-sources");
var compile = require("truffle-migrate-legacy/node_modules/truffle-compile");
var series = require("async").series;
var path = require("path");
var SolidityCoder = require("truffle-migrate-legacy/node_modules/web3/lib/solidity/coder.js");
//const semver = require("semver"); <--- for use when BYOC enabled

let SafeSend;

var SolidityTest = {
  define: function(abstraction, dependency_paths, runner, mocha) {
    var self = this;

    var suite = new Suite(abstraction.contract_name, {});
    suite.timeout(runner.BEFORE_TIMEOUT);

    // Set up our runner's needs first.
    suite.beforeAll("prepare suite", function(done) {
      series(
        [
          runner.initialize.bind(runner),
          self.compileNewAbstractInterface.bind(this, runner),
          self.deployTestDependencies.bind(
            this,
            abstraction,
            dependency_paths,
            runner
          )
        ],
        done
      );
    });

    suite.beforeEach("before test", function(done) {
      runner.startTest(this, done);
    });

    // Function that decodes raw logs from unlinked third party assertion
    // libraries and returns usable TestEvent logs
    function decodeTestEvents(result) {
      if (result.logs.length) return result.logs;

      var logs = [];
      var signature = web3.sha3("TestEvent(bool,string)");

      result.receipt.logs.forEach(function(log) {
        if (log.topics.length === 2 && log.topics[0] === signature) {
          var decoded = {
            event: "TestEvent",
            args: {
              result: SolidityCoder.decodeParams(
                ["bool"],
                log.topics[1].replace("0x", "")
              )[0],
              message: SolidityCoder.decodeParams(
                ["string"],
                log.data.replace("0x", "")
              )[0]
            }
          };
          logs.push(decoded);
        }
      });
      return logs;
    }

    // Function that checks transaction logs to see if a test failed.
    function processResult(result) {
      result.logs = decodeTestEvents(result);

      result.logs.forEach(function(log) {
        if (log.event == "TestEvent" && log.args.result == false) {
          throw new Error(log.args.message);
        }
      });
    }

    // Add functions from test file.
    abstraction.abi.forEach(function(item) {
      if (item.type != "function") return;

      ["beforeAll", "beforeEach", "afterAll", "afterEach"].forEach(function(
        fn_type
      ) {
        if (item.name.indexOf(fn_type) == 0) {
          suite[fn_type](item.name, function() {
            return abstraction
              .deployed()
              .then(function(deployed) {
                return deployed[item.name]();
              })
              .then(processResult);
          });
        }
      });

      if (item.name.indexOf("test") == 0) {
        var test = new TestCase(item.name, function() {
          return abstraction
            .deployed()
            .then(function(deployed) {
              return deployed[item.name]();
            })
            .then(processResult);
        });

        test.timeout(runner.TEST_TIMEOUT);
        suite.addTest(test);
      }
    });

    suite.afterEach("after test", function(done) {
      runner.endTest(this, done);
    });

    mocha.suite.addSuite(suite);
  },

  compileNewAbstractInterface: function(runner, callback) {
    find_contracts(runner.config.contracts_directory, function(err) {
      if (err) return callback(err);

      // TODO (make legacy testing work w/ BYOC, compilerSupplier, solc ^0.5.0
      SafeSend = "OldSafeSend.sol";
      /*
        const config = runner.config;
        if (!config.compilers.solc.version) SafeSend = "NewSafeSend.sol";
        else if (semver.lt(semver.coerce(config.compilers.solc.version), "0.5.0"))
        SafeSend = "OldSafeSend.sol";
        else SafeSend = "NewSafeSend.sol";
      */

      compile.with_dependencies(
        runner.config.with({
          paths: [
            path.join(__dirname, "Assert.sol"),
            path.join(__dirname, "AssertAddress.sol"),
            path.join(__dirname, "AssertAddressArray.sol"),
            // path.join(__dirname, "AssertAddressPayableArray.sol"), only compatible w/ ^0.5.0
            path.join(__dirname, "AssertBalance.sol"),
            path.join(__dirname, "AssertBool.sol"),
            path.join(__dirname, "AssertBytes32.sol"),
            path.join(__dirname, "AssertBytes32Array.sol"),
            path.join(__dirname, "AssertGeneral.sol"),
            path.join(__dirname, "AssertInt.sol"),
            path.join(__dirname, "AssertIntArray.sol"),
            path.join(__dirname, "AssertString.sol"),
            path.join(__dirname, "AssertUint.sol"),
            path.join(__dirname, "AssertUintArray.sol"),
            "truffle/DeployedAddresses.sol", // generated by deployed.js
            path.join(__dirname, SafeSend)
          ],
          quiet: true
        }),
        function(err, contracts) {
          if (err) return callback(err);

          // Set network values.
          Object.keys(contracts).forEach(function(name) {
            contracts[name].network_id = runner.config.network_id;
            contracts[name].default_network = runner.config.default_network;
          });

          runner.config.artifactor
            .saveAll(contracts, runner.config.contracts_build_directory)
            .then(function() {
              callback();
            })
            .catch(callback);
        }
      );
    });
  },

  deployTestDependencies: function(
    abstraction,
    dependency_paths,
    runner,
    callback
  ) {
    var deployer = new Deployer(
      runner.config.with({
        logger: { log: function() {} }
      })
    );

    const assertLibraries = [
      "Assert",
      "AssertAddress",
      "AssertAddressArray",
      //      "AssertAddressPayableArray", only compatible w/ ^0.5.0
      "AssertBalance",
      "AssertBool",
      "AssertBytes32",
      "AssertBytes32Array",
      "AssertGeneral",
      "AssertInt",
      "AssertIntArray",
      "AssertString",
      "AssertUint",
      "AssertUintArray"
    ];

    const assertAbstractions = assertLibraries.map(name =>
      runner.config.resolver.require(`truffle/${name}.sol`)
    );

    const DeployedAddresses = runner.config.resolver.require(
      "truffle/DeployedAddresses.sol"
    );
    SafeSend = runner.config.resolver.require(SafeSend);

    for (const abstraction of assertAbstractions) {
      deployer.deploy(abstraction);
    }
    deployer.deploy(DeployedAddresses).then(() => {
      return dependency_paths.forEach(dependency_path => {
        const dependency = runner.config.resolver.require(dependency_path);

        if (dependency.isDeployed()) deployer.link(dependency, abstraction);
      });
    });

    let deployed;
    deployer
      .deploy(abstraction)
      .then(function() {
        return abstraction.deployed();
      })
      .then(function(instance) {
        deployed = instance;
        if (deployed.initialBalance) {
          return deployed.initialBalance.call();
        } else {
          return 0;
        }
      })
      .then(function(balance) {
        if (balance != 0) {
          return deployer
            .deploy(SafeSend, deployed.address, {
              value: balance
            })
            .then(function() {
              return SafeSend.deployed();
            })
            .then(function(safesend) {
              return safesend.deliver();
            });
        }
      });

    deployer
      .start()
      .then(function() {
        callback();
      })
      .catch(callback);
  }
};

module.exports = SolidityTest;
<commit_msg>update soli testing for BYOC<commit_after>var TestCase = require("mocha/lib/test.js");
var Suite = require("mocha/lib/suite.js");
var Deployer = require("truffle-migrate-legacy/node_modules/truffle-deployer");
var find_contracts = require("truffle-contract-sources");
var compile = require("truffle-compile-legacy");
var series = require("async").series;
var path = require("path");
var SolidityCoder = require("truffle-migrate-legacy/node_modules/web3/lib/solidity/coder.js");
const semver = require("semver");

let SafeSend;

var SolidityTest = {
  define: function(abstraction, dependency_paths, runner, mocha) {
    var self = this;

    var suite = new Suite(abstraction.contract_name, {});
    suite.timeout(runner.BEFORE_TIMEOUT);

    // Set up our runner's needs first.
    suite.beforeAll("prepare suite", function(done) {
      series(
        [
          runner.initialize.bind(runner),
          self.compileNewAbstractInterface.bind(this, runner),
          self.deployTestDependencies.bind(
            this,
            abstraction,
            dependency_paths,
            runner
          )
        ],
        done
      );
    });

    suite.beforeEach("before test", function(done) {
      runner.startTest(this, done);
    });

    // Function that decodes raw logs from unlinked third party assertion
    // libraries and returns usable TestEvent logs
    function decodeTestEvents(result) {
      if (result.logs.length) return result.logs;

      var logs = [];
      var signature = web3.sha3("TestEvent(bool,string)");

      result.receipt.logs.forEach(function(log) {
        if (log.topics.length === 2 && log.topics[0] === signature) {
          var decoded = {
            event: "TestEvent",
            args: {
              result: SolidityCoder.decodeParams(
                ["bool"],
                log.topics[1].replace("0x", "")
              )[0],
              message: SolidityCoder.decodeParams(
                ["string"],
                log.data.replace("0x", "")
              )[0]
            }
          };
          logs.push(decoded);
        }
      });
      return logs;
    }

    // Function that checks transaction logs to see if a test failed.
    function processResult(result) {
      result.logs = decodeTestEvents(result);

      result.logs.forEach(function(log) {
        if (log.event == "TestEvent" && log.args.result == false) {
          throw new Error(log.args.message);
        }
      });
    }

    // Add functions from test file.
    abstraction.abi.forEach(function(item) {
      if (item.type != "function") return;

      ["beforeAll", "beforeEach", "afterAll", "afterEach"].forEach(function(
        fn_type
      ) {
        if (item.name.indexOf(fn_type) == 0) {
          suite[fn_type](item.name, function() {
            return abstraction
              .deployed()
              .then(function(deployed) {
                return deployed[item.name]();
              })
              .then(processResult);
          });
        }
      });

      if (item.name.indexOf("test") == 0) {
        var test = new TestCase(item.name, function() {
          return abstraction
            .deployed()
            .then(function(deployed) {
              return deployed[item.name]();
            })
            .then(processResult);
        });

        test.timeout(runner.TEST_TIMEOUT);
        suite.addTest(test);
      }
    });

    suite.afterEach("after test", function(done) {
      runner.endTest(this, done);
    });

    mocha.suite.addSuite(suite);
  },

  compileNewAbstractInterface: function(runner, callback) {
    find_contracts(runner.config.contracts_directory, function(err) {
      if (err) return callback(err);

      const config = runner.config;
      if (!config.compilers.solc.version) SafeSend = "NewSafeSend.sol";
      else if (semver.lt(semver.coerce(config.compilers.solc.version), "0.5.0"))
        SafeSend = "OldSafeSend.sol";
      else SafeSend = "NewSafeSend.sol";

      compile.with_dependencies(
        runner.config.with({
          paths: [
            path.join(__dirname, "Assert.sol"),
            path.join(__dirname, "AssertAddress.sol"),
            path.join(__dirname, "AssertAddressArray.sol"),
            // path.join(__dirname, "AssertAddressPayableArray.sol"), only compatible w/ ^0.5.0
            path.join(__dirname, "AssertBalance.sol"),
            path.join(__dirname, "AssertBool.sol"),
            path.join(__dirname, "AssertBytes32.sol"),
            path.join(__dirname, "AssertBytes32Array.sol"),
            path.join(__dirname, "AssertGeneral.sol"),
            path.join(__dirname, "AssertInt.sol"),
            path.join(__dirname, "AssertIntArray.sol"),
            path.join(__dirname, "AssertString.sol"),
            path.join(__dirname, "AssertUint.sol"),
            path.join(__dirname, "AssertUintArray.sol"),
            "truffle/DeployedAddresses.sol", // generated by deployed.js
            path.join(__dirname, SafeSend)
          ],
          quiet: true
        }),
        function(err, contracts) {
          if (err) return callback(err);

          // Set network values.
          Object.keys(contracts).forEach(function(name) {
            contracts[name].network_id = runner.config.network_id;
            contracts[name].default_network = runner.config.default_network;
          });

          runner.config.artifactor
            .saveAll(contracts, runner.config.contracts_build_directory)
            .then(function() {
              callback();
            })
            .catch(callback);
        }
      );
    });
  },

  deployTestDependencies: function(
    abstraction,
    dependency_paths,
    runner,
    callback
  ) {
    var deployer = new Deployer(
      runner.config.with({
        logger: { log: function() {} }
      })
    );

    const assertLibraries = [
      "Assert",
      "AssertAddress",
      "AssertAddressArray",
      //      "AssertAddressPayableArray", only compatible w/ ^0.5.0
      "AssertBalance",
      "AssertBool",
      "AssertBytes32",
      "AssertBytes32Array",
      "AssertGeneral",
      "AssertInt",
      "AssertIntArray",
      "AssertString",
      "AssertUint",
      "AssertUintArray"
    ];

    const assertAbstractions = assertLibraries.map(name =>
      runner.config.resolver.require(`truffle/${name}.sol`)
    );

    const DeployedAddresses = runner.config.resolver.require(
      "truffle/DeployedAddresses.sol"
    );
    SafeSend = runner.config.resolver.require(SafeSend);

    for (const abstraction of assertAbstractions) {
      deployer.deploy(abstraction);
    }
    deployer.deploy(DeployedAddresses).then(() => {
      return dependency_paths.forEach(dependency_path => {
        const dependency = runner.config.resolver.require(dependency_path);

        if (dependency.isDeployed()) deployer.link(dependency, abstraction);
      });
    });

    let deployed;
    deployer
      .deploy(abstraction)
      .then(function() {
        return abstraction.deployed();
      })
      .then(function(instance) {
        deployed = instance;
        if (deployed.initialBalance) {
          return deployed.initialBalance.call();
        } else {
          return 0;
        }
      })
      .then(function(balance) {
        if (balance != 0) {
          return deployer
            .deploy(SafeSend, deployed.address, {
              value: balance
            })
            .then(function() {
              return SafeSend.deployed();
            })
            .then(function(safesend) {
              return safesend.deliver();
            });
        }
      });

    deployer
      .start()
      .then(function() {
        callback();
      })
      .catch(callback);
  }
};

module.exports = SolidityTest;
<|endoftext|>


<commit_before>// @flow

import assert from 'assert'

import { type BackupJob } from '../backups-ng'
import { type CallJob } from '../jobs'
import { type Schedule } from '../scheduling'

const createOr = (children: Array<any>): any =>
  children.length === 1 ? children[0] : { __or: children }

const methods = {
  'vm.deltaCopy': (
    job: CallJob,
    { _reportWhen: reportWhen, retention = 1, sr, vms },
    schedule: Schedule
  ) => ({
    mode: 'delta',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        copyRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    srs: { id: sr },
    userId: job.userId,
    vms,
  }),
  'vm.rollingDeltaBackup': (
    job: CallJob,
    { _reportWhen: reportWhen, depth = 1, retention = depth, remote, vms },
    schedule: Schedule
  ) => ({
    mode: 'delta',
    remotes: { id: remote },
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        exportRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
  'vm.rollingDrCopy': (
    job: CallJob,
    {
      _reportWhen: reportWhen,
      deleteOldBackupsFirst,
      depth = 1,
      retention = depth,
      sr,
      vms,
    },
    schedule: Schedule
  ) => ({
    mode: 'full',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        deleteFirst: deleteOldBackupsFirst,
        copyRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    srs: { id: sr },
    vms,
  }),
  'vm.rollingBackup': (
    job: CallJob,
    {
      _reportWhen: reportWhen,
      compress,
      depth = 1,
      retention = depth,
      remoteId,
      vms,
    },
    schedule: Schedule
  ) => ({
    compression: compress ? 'native' : undefined,
    mode: 'full',
    remotes: { id: remoteId },
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        exportRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
  'vm.rollingSnapshot': (
    job: CallJob,
    { _reportWhen: reportWhen, depth = 1, retention = depth, vms },
    schedule: Schedule
  ) => ({
    mode: 'full',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        snapshotRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
}

const parseParamsVector = (vector: any) => {
  assert.strictEqual(vector.type, 'crossProduct')
  const { items } = vector
  assert.strictEqual(items.length, 2)

  let vms, params
  if (items[1].type === 'map') {
    ;[params, vms] = items

    vms = vms.collection
    assert.strictEqual(vms.type, 'fetchObjects')
    vms = vms.pattern
  } else {
    ;[vms, params] = items

    assert.strictEqual(vms.type, 'set')
    vms = vms.values
    if (vms.length !== 0) {
      assert.deepStrictEqual(Object.keys(vms[0]), ['id'])
      vms = { id: createOr(vms.map(_ => _.id)) }
    }
  }

  assert.strictEqual(params.type, 'set')
  params = params.values
  assert.strictEqual(params.length, 1)
  params = params[0]

  return { ...params, vms }
}

export const translateLegacyJob = (
  job: CallJob,
  schedules: Schedule[]
): BackupJob => {
  const { id } = job
  let method, schedule
  if (
    job.type !== 'call' ||
    (method = methods[job.method]) === undefined ||
    (schedule = schedules.find(_ => _.jobId === id)) === undefined
  ) {
    throw new Error(`cannot convert job ${job.id}`)
  }
  const params = parseParamsVector(job.paramsVector)
  return {
    id,
    name: params.tag || job.name,
    type: 'backup',
    userId: job.userId,
    // $FlowFixMe `method` is initialized but Flow fails to see this
    ...method(job, params, schedule),
  }
}
<commit_msg>fix(xo-server/migrateLegacyBackupJob): dont migrate when ids contain `:`<commit_after>// @flow

import assert from 'assert'

import { type BackupJob } from '../backups-ng'
import { type CallJob } from '../jobs'
import { type Schedule } from '../scheduling'

const createOr = (children: Array<any>): any =>
  children.length === 1 ? children[0] : { __or: children }

const methods = {
  'vm.deltaCopy': (
    job: CallJob,
    { _reportWhen: reportWhen, retention = 1, sr, vms },
    schedule: Schedule
  ) => ({
    mode: 'delta',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        copyRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    srs: { id: sr },
    userId: job.userId,
    vms,
  }),
  'vm.rollingDeltaBackup': (
    job: CallJob,
    { _reportWhen: reportWhen, depth = 1, retention = depth, remote, vms },
    schedule: Schedule
  ) => ({
    mode: 'delta',
    remotes: { id: remote },
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        exportRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
  'vm.rollingDrCopy': (
    job: CallJob,
    {
      _reportWhen: reportWhen,
      deleteOldBackupsFirst,
      depth = 1,
      retention = depth,
      sr,
      vms,
    },
    schedule: Schedule
  ) => ({
    mode: 'full',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        deleteFirst: deleteOldBackupsFirst,
        copyRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    srs: { id: sr },
    vms,
  }),
  'vm.rollingBackup': (
    job: CallJob,
    {
      _reportWhen: reportWhen,
      compress,
      depth = 1,
      retention = depth,
      remoteId,
      vms,
    },
    schedule: Schedule
  ) => ({
    compression: compress ? 'native' : undefined,
    mode: 'full',
    remotes: { id: remoteId },
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        exportRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
  'vm.rollingSnapshot': (
    job: CallJob,
    { _reportWhen: reportWhen, depth = 1, retention = depth, vms },
    schedule: Schedule
  ) => ({
    mode: 'full',
    settings: {
      '': reportWhen === undefined ? undefined : { reportWhen },
      [schedule.id]: {
        snapshotRetention: retention,
        vmTimeout: job.timeout,
      },
    },
    vms,
  }),
}

const parseParamsVector = (vector: any) => {
  assert.strictEqual(vector.type, 'crossProduct')
  const { items } = vector
  assert.strictEqual(items.length, 2)

  let vms, params
  if (items[1].type === 'map') {
    ;[params, vms] = items

    vms = vms.collection
    assert.strictEqual(vms.type, 'fetchObjects')
    vms = vms.pattern
  } else {
    ;[vms, params] = items

    assert.strictEqual(vms.type, 'set')
    vms = vms.values
    if (vms.length !== 0) {
      assert.deepStrictEqual(Object.keys(vms[0]), ['id'])
      vms = { id: createOr(vms.map(_ => _.id)) }
    }
  }

  assert.strictEqual(params.type, 'set')
  params = params.values
  assert.strictEqual(params.length, 1)
  params = params[0]

  return { ...params, vms }
}

export const translateLegacyJob = (
  job: CallJob,
  schedules: Schedule[]
): BackupJob => {
  const { id } = job
  let method, schedule
  if (
    id.includes(':') ||
    job.type !== 'call' ||
    (method = methods[job.method]) === undefined ||
    (schedule = schedules.find(_ => _.jobId === id)) === undefined ||
    schedule.id.includes(':')
  ) {
    throw new Error(`cannot convert job ${job.id}`)
  }
  const params = parseParamsVector(job.paramsVector)
  return {
    id,
    name: params.tag || job.name,
    type: 'backup',
    userId: job.userId,
    // $FlowFixMe `method` is initialized but Flow fails to see this
    ...method(job, params, schedule),
  }
}
<|endoftext|>


<commit_before>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @namespace
 * Entry point for purchasing digital goods.
 *

 * API that permits BlackBerry device users to initiate the purchase of digital goods from within your application. For example, this API can be used to allow users to purchase additional levels in a gaming application, music from a radio application, or any other digital good registered on the Vendor Portal for BlackBerry App World. The digital good being purchased must be associated with the calling application in the Vendor Portal for BlackBerry App World.
 *

 * Purchases are initiated via the purchase method. The amount of time that elapses before a response is returned depends on how quickly the user completes the purchase process (which may include steps such as signing in to their BlackBerry ID account and setting up their preferred billing method, etc.). The purchase method dispatches a PaymentSuccessEvent on success, or dispatches a PaymentErrorEvent on failure.
 *

 * When calling the puchase method only the ID or SKU of the digital good to be purchased is required; it is not necessary to provide both, and all other arguments are optional. If both the ID and SKU are provided, then the ID takes precedence; the SKU is only used if the digital good could not be located on the Payment Service server based on the ID.
 *

 * If an application requires a list of its digital goods that have already been purchased by the user (e.g., to avoid offering for sale a digital good the user already owns), such a list can be obtained with the getExistingPurchases method. This method requires the same user interaction as the purchase method, so it can also be a long-running method.
 * @toc {Payment} Payment
 * @featureID blackberry.payment
 */
blackberry.payment = {

    /**
     * @function
     * @description Retrieves the previous successful purchases made by the user from within the calling application.
     * @param {Boolean} [refresh]  True if the BlackBerry should be allowed to refresh the list of purchases from the Payment Service server. False if the current list of cached purchases should be returned immediately.
     * @callback {function} callbackOnSuccess Function to be invoked on successful call.
     * @callback {Purchase[]} callbackOnSuccess.data An array of purchases is passed as a parameter in the form below.
     *
[{
     * "transactionID": "00000001",
     * "digitalGoodID": "123",
     * "date": "1234567891011",
     * "digitalGoodSKU": "SKU 1",
     * "licenseKey": null,
     * "metaData": ""
     * },
     * {
     * "transactionID": "00000002",
     * "digitalGoodID": "456",
     * "date": "1234567891011",
     * "digitalGoodSKU": "SKU 2",
     * "licenseKey": null,
     * "metaData": ""
     * }]

     * @callback {function} [callbackOnFailure] Function to be invoked when an error occurs.
     * @callback {Number} callbackOnFailure.error An error code will be passed in corresponding to the following codes
     *

     *
 User Cancelled = 1

     *
 Payment System Busy = 2

     *
 General Payment System Error  = 3

     *
 Digital Good not Found = 4

     *

     * @PB10
     */
    getExistingPurchases : function (refresh, callbackOnSuccess, callbackOnFailure) {
    },
    /**
     * @function
     * @description Initiates the purchase of a digital good.
     *

     * Only the ID or SKU of the digital good to be purchased is required; it is not necessary to provide both. If both the ID and SKU are provided, then the ID takes precedence; the SKU is only used if the digital good cannot be located by the Payment Service based on the ID.
     * @param {Object} args Contains an information that describes the purchase.
     * @callback {String} args.digitalGoodID ID of the digital good being purchased.
     * @callback {String} args.digitalGoodSKU SKU of the digital good being purchased.
     * @callback {String} args.digitalGoodName Name of the digital good being purchased.
     * @callback {String} args.metaData Metadata associated with the purchase being purchased.
     * @callback {String} args.purchaseAppName Name of the application requesting the purchase.
     * @callback {String} args.purchaseAppIcon Icon of the application requesting the purchase.
     * @callback {function} callbackOnSuccess Function to be called when the payment is successful.
     * @callback {Purchase} callbackOnSuccess.data An object representing a purchase is passed as a parameter in the form below.
     * @callback {function} [callbackOnFailure] Function to be called when an error occurs.
     * @callback {Number} callbackOnFailure.error An error code will be passed in corresponding to the following codes
     *

     *
 User Cancelled = 1

     *
 Payment System Busy = 2

     *
 General Payment System Error  = 3

     *
 Digital Good not Found = 4

     *

     * @PB10
     * @example
     * <script type="text/javascript">
     *   function pay() {
     *     try{
     *       blackberry.payment.purchase({
     *       "digitalGoodID":"123",
     *       "digitalGoodSKU":"someSKU",
     *       "digitalGoodName":"SomeName",
     *       "metaData":"metadata",
     *       "purchaseAppName":"WebWorks APP",
     *       "purchaseAppIcon":null},
     *       success,failure);
     *    }catch (e){
     *      alert ("Error" + e);
     *    }
     *  }
     *
     *  function success(purchase) {
     *    alert ("success called:"+ JSON.stringify(purchase));
     *   }
     *
     *  function failure(error) {
     *    alert ("failure called with error code:"+ error);
     *  }
     * </script>
     */
    purchase : function ( args, callbackOnSuccess, callbackOnFailure) {
    },
    /**
     * @type Boolean
     * @description Sets the development mode used in the application. If development mode is set to true, the application does not contact the Payment Service server for any transactions. For purchases, a simulated purchase screen is displayed, allowing the user to choose the result of the purchase. For retrieving existing purchases, only simulated successful purchases are returned. This mode is useful for testing how your application handles the possible results without requiring network connections or currency. THIS MODE SHOULD NOT BE USED IN PRODUCTION CODE. If development mode is set to false, purchases and retrievals of existing purchases proceed normally, contacting the Payment Service server as necessary. This is the default development mode, and applications in production should not modify it.
     * @PB10
     */
    developmentMode: false

};

/**
 * @class
 * @toc {Payment} Purchase
 */
Purchase = {

    /**
     * @type String
     * @description The ID corresponding to the purchase transaction.
     * @BB50+
     * @PB10
     */
    transactionID : null,

    /**
     * @type String
     * @description The ID corresponding to the digitalGood to be purchased.
     * @BB50+
     * @PB10
     */
    digitalGoodID : null,

    /**
     * @type String
     * @description The SKU corresponding to the digitalGood to be purchased.
     * @BB50+
     * @PB10
     */
    digitalGoodSKU : null,

    /**
     * @type String
     * @description Metadata offers the application developer a way to store information about each purchase on the Payment Service server, and to retrieve that data via net.rim.blackberry.api.payment.PaymentSystem.getExistingPurchases(boolean). For example, assume a book vendor offers many titles at a single price point, and represents them on the vendor portal as a single digital good. In this case, the ISBN of the book can be provided as metadata, which uniquely identifies the digital good that was purchased. The entire list of purchased books can then be retrieved at any time by obtaining previous purchases via the getExistingPurchases method, filtering on the book's digital good Content ID, and finally enumerating the ISBNs in the metadata of each purchase.
     * @BB50+
     * @PB10
     */
    metaData : null,

    /**
     * @type String
     * @description Represents the date this purchase was made.
     * @BB50+
     * @PB10
     */
    date : null,

    /**
     * @type String
     * @description Represents the license key for this purchase, or null if the purchased digital good does not have a license key.
     * @BB50+
     * @PB10
     */
    licenseKey : null

};<commit_msg>Updated description of metadata<commit_after>/*
* Copyright 2010-2011 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
 * @namespace
 * Entry point for purchasing digital goods.
 *

 * API that permits BlackBerry device users to initiate the purchase of digital goods from within your application. For example, this API can be used to allow users to purchase additional levels in a gaming application, music from a radio application, or any other digital good registered on the Vendor Portal for BlackBerry App World. The digital good being purchased must be associated with the calling application in the Vendor Portal for BlackBerry App World.
 *

 * Purchases are initiated via the purchase method. The amount of time that elapses before a response is returned depends on how quickly the user completes the purchase process (which may include steps such as signing in to their BlackBerry ID account and setting up their preferred billing method, etc.). The purchase method dispatches a PaymentSuccessEvent on success, or dispatches a PaymentErrorEvent on failure.
 *

 * When calling the puchase method only the ID or SKU of the digital good to be purchased is required; it is not necessary to provide both, and all other arguments are optional. If both the ID and SKU are provided, then the ID takes precedence; the SKU is only used if the digital good could not be located on the Payment Service server based on the ID.
 *

 * If an application requires a list of its digital goods that have already been purchased by the user (e.g., to avoid offering for sale a digital good the user already owns), such a list can be obtained with the getExistingPurchases method. This method requires the same user interaction as the purchase method, so it can also be a long-running method.
 * @toc {Payment} Payment
 * @featureID blackberry.payment
 */
blackberry.payment = {

    /**
     * @function
     * @description Retrieves the previous successful purchases made by the user from within the calling application.
     * @param {Boolean} [refresh]  True if the BlackBerry should be allowed to refresh the list of purchases from the Payment Service server. False if the current list of cached purchases should be returned immediately.
     * @callback {function} callbackOnSuccess Function to be invoked on successful call.
     * @callback {Purchase[]} callbackOnSuccess.data An array of purchases is passed as a parameter in the form below.
     *
[{
     * "transactionID": "00000001",
     * "digitalGoodID": "123",
     * "date": "1234567891011",
     * "digitalGoodSKU": "SKU 1",
     * "licenseKey": null,
     * "metaData": ""
     * },
     * {
     * "transactionID": "00000002",
     * "digitalGoodID": "456",
     * "date": "1234567891011",
     * "digitalGoodSKU": "SKU 2",
     * "licenseKey": null,
     * "metaData": ""
     * }]

     * @callback {function} [callbackOnFailure] Function to be invoked when an error occurs.
     * @callback {Number} callbackOnFailure.error An error code will be passed in corresponding to the following codes
     *

     *
 User Cancelled = 1

     *
 Payment System Busy = 2

     *
 General Payment System Error  = 3

     *
 Digital Good not Found = 4

     *

     * @PB10
     */
    getExistingPurchases : function (refresh, callbackOnSuccess, callbackOnFailure) {
    },
    /**
     * @function
     * @description Initiates the purchase of a digital good.
     *

     * Only the ID or SKU of the digital good to be purchased is required; it is not necessary to provide both. If both the ID and SKU are provided, then the ID takes precedence; the SKU is only used if the digital good cannot be located by the Payment Service based on the ID.
     * @param {Object} args Contains an information that describes the purchase.
     * @callback {String} args.digitalGoodID ID of the digital good being purchased.
     * @callback {String} args.digitalGoodSKU SKU of the digital good being purchased.
     * @callback {String} args.digitalGoodName Name of the digital good being purchased.
     * @callback {String} args.metaData Metadata associated with the digital good. Metadata offers the application developer a way to store information about each purchase on the Payment Service server, and to retrieve that data via blackberry.payment.getExistingPurchases method.
     * @callback {String} args.purchaseAppName Name of the application requesting the purchase.
     * @callback {String} args.purchaseAppIcon Icon of the application requesting the purchase.
     * @callback {function} callbackOnSuccess Function to be called when the payment is successful.
     * @callback {Purchase} callbackOnSuccess.data An object representing a purchase is passed as a parameter in the form below.
     * @callback {function} [callbackOnFailure] Function to be called when an error occurs.
     * @callback {Number} callbackOnFailure.error An error code will be passed in corresponding to the following codes
     *

     *
 User Cancelled = 1

     *
 Payment System Busy = 2

     *
 General Payment System Error  = 3

     *
 Digital Good not Found = 4

     *

     * @PB10
     * @example
     * <script type="text/javascript">
     *   function pay() {
     *     try{
     *       blackberry.payment.purchase({
     *       "digitalGoodID":"123",
     *       "digitalGoodSKU":"someSKU",
     *       "digitalGoodName":"SomeName",
     *       "metaData":"metadata",
     *       "purchaseAppName":"WebWorks APP",
     *       "purchaseAppIcon":null},
     *       success,failure);
     *    }catch (e){
     *      alert ("Error" + e);
     *    }
     *  }
     *
     *  function success(purchase) {
     *    alert ("success called:"+ JSON.stringify(purchase));
     *   }
     *
     *  function failure(error) {
     *    alert ("failure called with error code:"+ error);
     *  }
     * </script>
     */
    purchase : function (args, callbackOnSuccess, callbackOnFailure) {
    },
    /**
     * @type Boolean
     * @description Sets the development mode used in the application. If development mode is set to true, the application does not contact the Payment Service server for any transactions. For purchases, a simulated purchase screen is displayed, allowing the user to choose the result of the purchase. For retrieving existing purchases, only simulated successful purchases are returned. This mode is useful for testing how your application handles the possible results without requiring network connections or currency. THIS MODE SHOULD NOT BE USED IN PRODUCTION CODE. If development mode is set to false, purchases and retrievals of existing purchases proceed normally, contacting the Payment Service server as necessary. This is the default development mode, and applications in production should not modify it.
     * @PB10
     */
    developmentMode: false

};

/**
 * @class
 * @toc {Payment} Purchase
 */
Purchase = {

    /**
     * @type String
     * @description The transaction ID for this purchase.
     * @BB50+
     * @PB10
     */
    transactionID : null,

    /**
     * @type String
     * @description The ID of the purchased digital good.
     * @BB50+
     * @PB10
     */
    digitalGoodID : null,

    /**
     * @type String
     * @description The SKU of the purchased digital good.
     * @BB50+
     * @PB10
     */
    digitalGoodSKU : null,

    /**
     * @type String
     * @description The metadata for this purchase, or null if no metadata was included with the purchase.
     * @BB50+
     * @PB10
     */
    metaData : null,

    /**
     * @type String
     * @description Represents the date this purchase was made.
     * @BB50+
     * @PB10
     */
    date : null,

    /**
     * @type String
     * @description Represents the license key for this purchase, or null if the purchased digital good does not have a license key.
     * @BB50+
     * @PB10
     */
    licenseKey : null

};<|endoftext|>