<commit_before>'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = defaultSettings.title || 'vue Element Admin' // page title

// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following method:
// port = 9527 npm run dev OR npm run dev --port = 9527
const port = process.env.port || process.env.npm_config_port || 9527 // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    before: require('./mock/mock-server.js')
  },
  configureWebpack: {
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    }
  },
  chainWebpack(config) {
    // it can improve the speed of the first screen, it is recommended to turn on preload
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial'
      }
    ])

    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete('prefetch')

    // set svg-sprite-loader
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    // set preserveWhitespace
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true
        return options
      })
      .end()

    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
          config.optimization.runtimeChunk('single')
        }
      )
  }
}
<commit_msg>perf[chore]: remove preserveWhitespace config (#3280)<commit_after>'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = defaultSettings.title || 'vue Element Admin' // page title

// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following method:
// port = 9527 npm run dev OR npm run dev --port = 9527
const port = process.env.port || process.env.npm_config_port || 9527 // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    before: require('./mock/mock-server.js')
  },
  configureWebpack: {
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    resolve: {
      alias: {
        '@': resolve('src')
      }
    }
  },
  chainWebpack(config) {
    // it can improve the speed of the first screen, it is recommended to turn on preload
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial'
      }
    ])

    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete('prefetch')

    // set svg-sprite-loader
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
          config.optimization.runtimeChunk('single')
        }
      )
  }
}
<|endoftext|>


<commit_before>/* global beforeEach, describe, it, expect */

import { h, app, Router } from "../src"
import { expectHTMLToBe } from "./util"

Object.defineProperty(window.location, "pathname", {
  writable: true
})

beforeEach(() => {
  window.location.pathname = "/"
  document.body.innerHTML = ""
})

describe("Router", () => {
  it("renders default route", () => {
    window.history.pushState = _ => _

    app({
      view: {
        "*": model => h("div", {}, "foo"),
      },
      plugins: [Router],
      subscriptions: [
        (_, actions) => {
          expectHTMLToBe(`

foo

					`)

          actions.router.go("/bar")
          expectHTMLToBe(`

foo

					`)

          actions.router.go("/baz")
          expectHTMLToBe(`

foo

					`)
        }
      ]
    })
  })

  it("renders the index route", () => {
    app({
      view: {
        "/": model => h("div", {}, "foo")
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foo

		`)
  })

  it("renders matched route", () => {
    window.location.pathname = "/foo/bar/baz"

    app({
      view: {
        "/foo/bar/baz": model => h("div", {}, "foo", "bar", "baz")
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foobarbaz

		`)
  })

  it("collects matched route keys", () => {
    window.location.pathname = "/FOO/BAR/BAZ"

    app({
      view: {
        "/:foo/:bar/:baz": model =>
          h("ul", {}, Object.keys(model.router.params).map(key =>
            h("li", {}, model.router.params[key])))
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

FOO

BAR

BAZ

		`)
  })

  it("collects matched route keys separated with dash", () => {
    window.location.pathname = "/FOO-BAR"

    app({
      view: {
        "/:foo-:bar": model =>
          h("ul", {}, Object.keys(model.router.params).map(key =>
            h("li", {}, model.router.params[key])))
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

FOO

BAR

		`)
  })

  it("collects matched route key with dash", () => {
    window.location.pathname = "/FOO-BAR"

    app({
      view: {
        "/:foo": model =>
          h("ul", {}, Object.keys(model.router.params).map(key =>
            h("li", {}, model.router.params[key])))
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

FOO-BAR

		`)
  })

  it("listens to popstate", () => {
    function firePopstate() {
      const event = document.createEvent("Event")
      event.initEvent("popstate", true, true)
      window.document.dispatchEvent(event)
    }

    app({
      view: {
        "/": model => "",
        "/foo": model => h("div", {}, "foo")
      },
      plugins: [Router]
    })

    window.location.pathname = "/foo"
    firePopstate()

    expectHTMLToBe(`

foo

		`)
  })

  describe("go", () => {
    it("navigates to the given route", () => {
      window.history.pushState = (_, __, data) =>
        expect(data).toMatch(/^\/(foo|bar|baz)$/)

      app({
        view: {
          "/": model => "",
          "/foo": model => h("div", {}, "foo"),
          "/bar": model => h("div", {}, "bar"),
          "/baz": model => h("div", {}, "baz")
        },
        plugins: [Router],
        subscriptions: [
          (_, actions) => {
            actions.router.go("/foo")
            expectHTMLToBe(`

foo

						`)

            actions.router.go("/bar")
            expectHTMLToBe(`

bar

						`)

            actions.router.go("/baz")
            expectHTMLToBe(`

baz

						`)
          }
        ]
      })
    })
  })
})
<commit_msg>Refactor router tests.<commit_after>/* global beforeEach, describe, it, expect */

import { h, app, Router } from "../src"
import { expectHTMLToBe } from "./util"

Object.defineProperty(window.location, "pathname", {
  writable: true
})

beforeEach(() => {
  window.location.pathname = "/"
  document.body.innerHTML = ""
})

describe("Router", () => {
  it("renders default route", () => {
    window.history.pushState = _ => _

    app({
      view: {
        "*": model => h("div", {}, "foo"),
      },
      plugins: [Router],
      subscriptions: [
        (_, actions) => {
          expectHTMLToBe(`

foo

					`)

          actions.router.go("/bar")
          expectHTMLToBe(`

foo

					`)

          actions.router.go("/baz")
          expectHTMLToBe(`

foo

					`)
        }
      ]
    })
  })

  it("renders the index route", () => {
    app({
      view: {
        "/": model => h("div", {}, "foo")
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foo

		`)
  })

  it("renders matched route", () => {
    window.location.pathname = "/foo/bar/baz"

    app({
      view: {
        "/foo/bar/baz": model => h("div", {}, "foo", "bar", "baz")
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foobarbaz

		`)
  })

  it("collects matched route keys", () => {
    window.location.pathname = "/beep/bop/boop"

    app({
      view: {
        "/:foo/:bar/:baz": model =>
          h("ul", {}, Object.keys(model.router.params).map(key =>
            h("li", {}, `${key}:${model.router.params[key]}`)))
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foo:beep

bar:bop

baz:boop

		`)
  })

  it("collects matched route keys separated with dash", () => {
    window.location.pathname = "/beep-bop-boop"

    app({
      view: {
        "/:foo-:bar-:baz": model =>
          h("ul", {}, Object.keys(model.router.params).map(key =>
            h("li", {}, `${key}:${model.router.params[key]}`)))
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

foo:beep

bar:bop

baz:boop

		`)
  })

  it("collects matched route key with dash", () => {
    window.location.pathname = "/beep-bop-boop"

    app({
      view: {
        "/:foo": model => h("div", {}, model.router.params.foo)
      },
      plugins: [Router]
    })

    expectHTMLToBe(`

          beep-bop-boop

		`)
  })

  it("listens to popstate", () => {
    function firePopstate() {
      const event = document.createEvent("Event")
      event.initEvent("popstate", true, true)
      window.document.dispatchEvent(event)
    }

    app({
      view: {
        "/": model => "",
        "/foo": model => h("div", {}, "foo")
      },
      plugins: [Router]
    })

    window.location.pathname = "/foo"

    firePopstate()

    expectHTMLToBe(`

foo

		`)
  })

  describe("go", () => {
    it("navigates to the given route", () => {
      window.history.pushState = (_, __, data) =>
        expect(data).toMatch(/^\/(foo|bar|baz)$/)

      app({
        view: {
          "/": model => "",
          "/foo": model => h("div", {}, "foo"),
          "/bar": model => h("div", {}, "bar"),
          "/baz": model => h("div", {}, "baz")
        },
        plugins: [Router],
        subscriptions: [
          (_, actions) => {
            actions.router.go("/foo")
            expectHTMLToBe(`

foo

						`)

            actions.router.go("/bar")
            expectHTMLToBe(`

bar

						`)

            actions.router.go("/baz")
            expectHTMLToBe(`

baz

						`)
          }
        ]
      })
    })
  })
})
<|endoftext|>


<commit_before>const imageminMozjpeg = require('imagemin-mozjpeg');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const webpack = require('webpack');
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJS = require('uglify-es');
const env_vars = require('./ENV_VARS');
const path = require('path');
const webpackConfig = {
  node: {
    process: true
  },
  devtool: 'source-map',
  devServer: {
    https: true,
    host: '0.0.0.0',
    hotOnly: true,
    port: 8080,
    writeToDisk: JSON.parse(env_vars.BUILD_TYPE) === 'mewcx',
    headers: {
      'Strict-Transport-Security':
        'max-age=63072000; includeSubdomains; preload',
      'Content-Security-Policy':
        "default-src 'self' blob:; frame-src 'self' connect.trezor.io:443; img-src 'self' data: blob:; script-src 'unsafe-eval' 'unsafe-inline' blob: https:; style-src 'self' 'unsafe-inline' https:; object-src 'none'; connect-src *;",
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
      'X-XSS-Protection': '1; mode=block',
      'Referrer-Policy': 'same-origin'
    }
  },
  plugins: [
    new webpack.DefinePlugin(env_vars),
    new webpack.NormalModuleReplacementPlugin(/^any-promise$/, 'bluebird'),
    new ImageminPlugin({
      disable: process.env.NODE_ENV !== 'production',
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: '100'
      },
      plugins: [
        imageminMozjpeg({
          quality: 100,
          progressive: true
        })
      ]
    }),
    new CopyWebpackPlugin([
      {
        from: 'src/builds/' + JSON.parse(env_vars.BUILD_TYPE) + '/public',
        transform: function(content, filePath) {
          if (filePath.split('.').pop() === ('js' || 'JS'))
            return UglifyJS.minify(content.toString()).code;
          if (
            filePath.replace(/^.*[\\\/]/, '') === 'manifest.json' &&
            JSON.parse(env_vars.BUILD_TYPE) === 'mewcx'
          ) {
            const version = require('./package.json').version;
            const json = JSON.parse(content);
            json.version = version;
            return JSON.stringify(json, null, 2);
          }
          return content;
        }
      }
    ])
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'initial'
        }
      }
    }
  }
};
if (process.env.NODE_ENV === 'production') {
  webpackConfig.plugins.push(
    new UnusedFilesWebpackPlugin({
      patterns: ['src/**/*.*'],
      failOnUnused: true,
      globOptions: {
        ignore: [
          // Are we using these
          'src/components/DropDownAddressSelector/DropDownAddressSelector.scss',
          'src/components/DropDownAddressSelector/index.js',
          // Unknown
          'src/contracts/contract-abi-etsc.json',
          'src/contracts/contract-abi-exp.json',
          'src/layouts/DevelopmentResources/DevelopmentResources.scss',
          'src/layouts/DevelopmentResources/DevelopmentResources.vue',
          'src/layouts/DevelopmentResources/index.js',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-desktop.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-mobile.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-tablet.scss',
          'src/tokens/tokens-etsc.json',
          'src/tokens/tokens-exp.json',
          // Informational
          'src/translations/README.md',
          'src/App.scss',
          // Helpers page
          'src/layouts/InformationPages/PrivacyPolicyLayout/index.js',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.scss',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.vue',
          'src/layouts/InformationPages/TermsAndConditionsLayout/index.js',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.scss',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.scss',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/index.js',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.scss',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.vue',
          'src/layouts/InformationPages/ExtensionsLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.scss',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.vue',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.scss',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.vue',
          'src/components/DropDownBidCurrencySelector/index.js',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.vue',
          'src/components/Notification/components/NotificationTypes/SwapNotification/index.js',
          'src/components/Notification/components/NotificationTypes/TransactionNotification/index.js',
          // Images
          'src/assets/images/icons/button-finney.png',
          'src/assets/images/background/bg-left.png',
          'src/assets/images/background/bg-right.png',
          'src/assets/images/currency/coins/AllImages/_icon-config.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.less',
          'src/assets/images/currency/coins/webfont/cryptocoins-colors.css',
          'src/assets/images/currency/coins/webfont/cryptocoins.css',
          'src/assets/images/flags/countries.json',
          'src/assets/images/icons/arrow-green-right.svg',
          'src/assets/images/icons/btc.png',
          'src/assets/images/icons/favicon.png',
          'src/assets/images/icons/github-black.png',
          'src/assets/images/icons/slack.png',
          'src/assets/images/mew-screen.png',
          'src/assets/images/networks/etsc.svg',
          'src/assets/images/networks/exp.svg',
          'src/assets/images/icons/up.svg',
          'src/assets/images/icons/button-json.svg',
          'src/assets/images/icons/button-mnemonic.svg',
          // Chrome Extension
          'src/builds/mewcx/app.vue',
          'src/builds/mewcx/public/img/icons/icon128.png',
          'src/builds/mewcx/public/img/icons/icon16.png',
          'src/builds/mewcx/public/img/icons/icon192.png',
          'src/builds/mewcx/public/img/icons/icon32.png',
          'src/builds/mewcx/public/img/icons/icon48.png',
          'src/builds/mewcx/public/manifest.json',
          'src/builds/mewcx/index.js',
          'src/builds/web/public/img/icons/android-chrome-192x192.png',
          'src/builds/web/public/img/icons/android-chrome-512x512.png',
          'src/builds/web/public/img/icons/apple-touch-icon-120x120.png',
          'src/builds/web/public/img/icons/apple-touch-icon-152x152.png',
          'src/builds/web/public/img/icons/apple-touch-icon-180x180.png',
          'src/builds/web/public/img/icons/apple-touch-icon-60x60.png',
          'src/builds/web/public/img/icons/apple-touch-icon-76x76.png',
          'src/builds/web/public/img/icons/apple-touch-icon.png',
          'src/builds/web/public/img/icons/favicon-16x16.png',
          'src/builds/web/public/img/icons/favicon-32x32.png',
          'src/builds/web/public/img/icons/msapplication-icon-144x144.png',
          'src/builds/web/public/img/icons/mstile-150x150.png',
          'src/builds/web/public/img/icons/safari-pinned-tab.svg',
          'src/builds/web/public/img/spaceman.png',
          'src/builds/web/public/manifest.json',
          'src/builds/web/public/robots.txt'
        ]
      }
    })
  );
}
const pwa = {
  name: 'MyEtherWallet',
  workboxOptions: {
    importWorkboxFrom: 'local',
    skipWaiting: true,
    clientsClaim: true,
    navigateFallback: '/index.html'
  }
};
const exportObj = {
  publicPath: process.env.ROUTER_MODE === 'history' ? '/' : './',
  configureWebpack: webpackConfig,
  lintOnSave: process.env.NODE_ENV === 'production' ? 'error' : true,
  integrity: process.env.WEBPACK_INTEGRITY === 'false' ? false : true,
  pwa: pwa,
  chainWebpack: config => {
    config.module
      .rule('replace')
      .test(/\.js$/)
      .include.add(
        path.resolve(__dirname, 'node_modules/@ensdomains/dnsprovejs')
      )
      .end()
      .use('string-replace-loader')
      .loader('string-replace-loader')
      .tap(options => {
        return {
          search:
            'https://dns.google.com/experimental?ct=application/dns-udpwireformat&dns=',
          replace:
            'https://cloudflare-dns.com/dns-query?ct=application/dns-udpwireformat&dns='
        };
      });
  }
};
module.exports = exportObj;
<commit_msg>Update config file<commit_after>const imageminMozjpeg = require('imagemin-mozjpeg');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const webpack = require('webpack');
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJS = require('uglify-es');
const env_vars = require('./ENV_VARS');
const path = require('path');
const webpackConfig = {
  node: {
    process: true
  },
  devtool: 'source-map',
  devServer: {
    https: true,
    host: 'localhost',
    hotOnly: true,
    port: 8080,
    writeToDisk: JSON.parse(env_vars.BUILD_TYPE) === 'mewcx',
    headers: {
      'Strict-Transport-Security':
        'max-age=63072000; includeSubdomains; preload',
      'Content-Security-Policy':
        "default-src 'self' blob:; frame-src 'self' connect.trezor.io:443; img-src 'self' data: blob:; script-src 'unsafe-eval' 'unsafe-inline' blob: https:; style-src 'self' 'unsafe-inline' https:; object-src 'none'; connect-src *;",
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
      'X-XSS-Protection': '1; mode=block',
      'Referrer-Policy': 'same-origin'
    }
  },
  plugins: [
    new webpack.DefinePlugin(env_vars),
    new webpack.NormalModuleReplacementPlugin(/^any-promise$/, 'bluebird'),
    new ImageminPlugin({
      disable: process.env.NODE_ENV !== 'production',
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: '100'
      },
      plugins: [
        imageminMozjpeg({
          quality: 100,
          progressive: true
        })
      ]
    }),
    new CopyWebpackPlugin([
      {
        from: 'src/builds/' + JSON.parse(env_vars.BUILD_TYPE) + '/public',
        transform: function(content, filePath) {
          if (filePath.split('.').pop() === ('js' || 'JS'))
            return UglifyJS.minify(content.toString()).code;
          if (
            filePath.replace(/^.*[\\\/]/, '') === 'manifest.json' &&
            JSON.parse(env_vars.BUILD_TYPE) === 'mewcx'
          ) {
            const version = require('./package.json').version;
            const json = JSON.parse(content);
            json.version = version;
            return JSON.stringify(json, null, 2);
          }
          return content;
        }
      }
    ])
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'initial'
        }
      }
    }
  }
};
if (process.env.NODE_ENV === 'production') {
  webpackConfig.plugins.push(
    new UnusedFilesWebpackPlugin({
      patterns: ['src/**/*.*'],
      failOnUnused: true,
      globOptions: {
        ignore: [
          // Are we using these
          'src/components/DropDownAddressSelector/DropDownAddressSelector.scss',
          'src/components/DropDownAddressSelector/index.js',
          // Unknown
          'src/contracts/contract-abi-etsc.json',
          'src/contracts/contract-abi-exp.json',
          'src/layouts/DevelopmentResources/DevelopmentResources.scss',
          'src/layouts/DevelopmentResources/DevelopmentResources.vue',
          'src/layouts/DevelopmentResources/index.js',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-desktop.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-mobile.scss',
          'src/layouts/InterfaceLayout/containers/SendCurrencyContainer/SendCurrencyContainer-tablet.scss',
          'src/tokens/tokens-etsc.json',
          'src/tokens/tokens-exp.json',
          // Informational
          'src/translations/README.md',
          'src/App.scss',
          // Helpers page
          'src/layouts/InformationPages/PrivacyPolicyLayout/index.js',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.scss',
          'src/layouts/InformationPages/PrivacyPolicyLayout/PrivacyPolicyLayout.vue',
          'src/layouts/InformationPages/TermsAndConditionsLayout/index.js',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.scss',
          'src/layouts/InformationPages/TermsAndConditionsLayout/TermsAndConditionsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.scss',
          'src/layouts/InformationPages/AdvancedToolsLayout/AdvancedToolsLayout.vue',
          'src/layouts/InformationPages/AdvancedToolsLayout/index.js',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.scss',
          'src/layouts/InformationPages/ExtensionsLayout/ExtensionsLayout.vue',
          'src/layouts/InformationPages/ExtensionsLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/index.js',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.scss',
          'src/layouts/InformationPages/MewGithubLayout/MewGithubLayout.vue',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.scss',
          'src/components/DropDownBidCurrencySelector/DropDownBidCurrencySelector.vue',
          'src/components/DropDownBidCurrencySelector/index.js',
          'src/components/DropDownAddressSelector/DropDownAddressSelector.vue',
          'src/components/Notification/components/NotificationTypes/SwapNotification/index.js',
          'src/components/Notification/components/NotificationTypes/TransactionNotification/index.js',
          // Images
          'src/assets/images/icons/button-finney.png',
          'src/assets/images/background/bg-left.png',
          'src/assets/images/background/bg-right.png',
          'src/assets/images/currency/coins/AllImages/_icon-config.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.json',
          'src/assets/images/currency/coins/asFont/cryptocoins.less',
          'src/assets/images/currency/coins/webfont/cryptocoins-colors.css',
          'src/assets/images/currency/coins/webfont/cryptocoins.css',
          'src/assets/images/flags/countries.json',
          'src/assets/images/icons/arrow-green-right.svg',
          'src/assets/images/icons/btc.png',
          'src/assets/images/icons/favicon.png',
          'src/assets/images/icons/github-black.png',
          'src/assets/images/icons/slack.png',
          'src/assets/images/mew-screen.png',
          'src/assets/images/networks/etsc.svg',
          'src/assets/images/networks/exp.svg',
          'src/assets/images/icons/up.svg',
          'src/assets/images/icons/button-json.svg',
          'src/assets/images/icons/button-mnemonic.svg',
          // Chrome Extension
          'src/builds/mewcx/app.vue',
          'src/builds/mewcx/public/img/icons/icon128.png',
          'src/builds/mewcx/public/img/icons/icon16.png',
          'src/builds/mewcx/public/img/icons/icon192.png',
          'src/builds/mewcx/public/img/icons/icon32.png',
          'src/builds/mewcx/public/img/icons/icon48.png',
          'src/builds/mewcx/public/manifest.json',
          'src/builds/mewcx/index.js',
          'src/builds/web/public/img/icons/android-chrome-192x192.png',
          'src/builds/web/public/img/icons/android-chrome-512x512.png',
          'src/builds/web/public/img/icons/apple-touch-icon-120x120.png',
          'src/builds/web/public/img/icons/apple-touch-icon-152x152.png',
          'src/builds/web/public/img/icons/apple-touch-icon-180x180.png',
          'src/builds/web/public/img/icons/apple-touch-icon-60x60.png',
          'src/builds/web/public/img/icons/apple-touch-icon-76x76.png',
          'src/builds/web/public/img/icons/apple-touch-icon.png',
          'src/builds/web/public/img/icons/favicon-16x16.png',
          'src/builds/web/public/img/icons/favicon-32x32.png',
          'src/builds/web/public/img/icons/msapplication-icon-144x144.png',
          'src/builds/web/public/img/icons/mstile-150x150.png',
          'src/builds/web/public/img/icons/safari-pinned-tab.svg',
          'src/builds/web/public/img/spaceman.png',
          'src/builds/web/public/manifest.json',
          'src/builds/web/public/robots.txt'
        ]
      }
    })
  );
}
const pwa = {
  name: 'MyEtherWallet',
  workboxOptions: {
    importWorkboxFrom: 'local',
    skipWaiting: true,
    clientsClaim: true,
    navigateFallback: '/index.html'
  }
};
const exportObj = {
  publicPath: process.env.ROUTER_MODE === 'history' ? '/' : './',
  configureWebpack: webpackConfig,
  lintOnSave: process.env.NODE_ENV === 'production' ? 'error' : true,
  integrity: process.env.WEBPACK_INTEGRITY === 'false' ? false : true,
  pwa: pwa,
  chainWebpack: config => {
    config.module
      .rule('replace')
      .test(/\.js$/)
      .include.add(
        path.resolve(__dirname, 'node_modules/@ensdomains/dnsprovejs')
      )
      .end()
      .use('string-replace-loader')
      .loader('string-replace-loader')
      .tap(options => {
        return {
          search:
            'https://dns.google.com/experimental?ct=application/dns-udpwireformat&dns=',
          replace:
            'https://cloudflare-dns.com/dns-query?ct=application/dns-udpwireformat&dns='
        };
      });
  }
};
module.exports = exportObj;
<|endoftext|>


<commit_before>const testWithServer = require('./helpers/test-with-server');

testWithServer('Request for Archive HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-110000316',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Archive HTML Page for a wrong id', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Archive HTML Page but receive bad request from es', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected t0 503');
    t.end();
  });
});

testWithServer('Request for Archivedoc HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/archivedoc',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-37959',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page for a wrong id', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page but get error 503', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected to 503');
    t.end();
  });
});

testWithServer('Request for Person HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-17351',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Person HTML Page who doesn\'t exists', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Person HTML Page but get error 503', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected to 503');
    t.end();
  });
});

testWithServer('Request for Archive JSON', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-110069402',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Archive JSON with error', (t, ctx) => {
  t.plan(4);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the archive is not found');
    t.ok(response.message, 'Not Found', 'the archive message is not found');
    t.end();
  });
});

testWithServer('Request for Archive JSON with no result', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Archive not found');
    t.end();
  });
});

testWithServer('Request for Archivedoc JSON', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/archivedoc',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Object JSON Page', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-37959',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Object JSON Page for a wrong id', (t, ctx) => {
  t.plan(4);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the object is not found');
    t.ok(response.message, 'Not Found', 'the object message is not found');
    t.end();
  });
});

testWithServer('Request for Object JSON Page, not found', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Object not found');
    t.end();
  });
});

testWithServer('Request for Person JSON Page', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-17351',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Person JSON Page for a wrong id', (t, ctx) => {
  t.plan(4);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the person is not found');
    t.ok(response.message, 'Not Found', 'the person message is not found');
    t.end();
  });
});

testWithServer('Request for Person JSON Page, no result', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    // {"errors":[{"title":"Not Found","status":404,"detail":"Person not found"}]}
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Person not found');
    t.end();
  });
});
<commit_msg>refactor aggs based on comments on #171<commit_after>const testWithServer = require('./helpers/test-with-server');

testWithServer('Request for Archive HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-110000316',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Archive HTML Page for a wrong id', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Archive HTML Page but receive bad request from es', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected t0 503');
    t.end();
  });
});

testWithServer('Request for Archivedoc HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/archivedoc',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-37959',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page for a wrong id', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Object HTML Page but get error 503', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected to 503');
    t.end();
  });
});

testWithServer('Request for Person HTML Page', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-17351',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Person HTML Page who doesn\'t exists', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-wrongid',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 404, 'Status code was as expected');
    t.end();
  });
});

testWithServer('Request for Person HTML Page but get error 503', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-badRequest',
    headers: {'Accept': 'text/html'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 503, 'Status code was as expected to 503');
    t.end();
  });
});

testWithServer('Request for Archive JSON', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-110069402',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Archive JSON with error', (t, ctx) => {
  t.plan(4);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the archive is not found');
    t.ok(response.message, 'Not Found', 'the archive message is not found');
    t.end();
  });
});

testWithServer('Request for Archive JSON with no result', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/documents/smga-documents-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Archive not found');
    t.end();
  });
});

testWithServer('Request for Archivedoc JSON', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/archivedoc',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Object JSON Page', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-37959',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Object JSON Page for a wrong id', (t, ctx) => {
  t.plan(4);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the object is not found');
    t.ok(response.message, 'Not Found', 'the object message is not found');
    t.end();
  });
});

testWithServer('Request for Object JSON Page, not found', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/objects/smgc-objects-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Object not found');
    t.end();
  });
});

testWithServer('Request for Person JSON Page', (t, ctx) => {
  t.plan(2);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-17351',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    t.equal(res.statusCode, 200, 'Status code was as expected');
    t.ok(res.headers['content-type'].indexOf('application/vnd.api+json') > -1, 'JSONAPI response header should be application/vnd.api+json');
    t.end();
  });
});

testWithServer('Request for Person JSON Page for a wrong id', (t, ctx) => {
  t.plan(3);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-wrongid',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    var response = JSON.parse(res.payload);
    t.ok(response.status, 404, 'status is 404');
    t.ok(response.displayName, 'NotFound', 'the person is not found');
    t.ok(response.message, 'Not Found', 'the person message is not found');
    t.end();
  });
});

testWithServer('Request for Person JSON Page, no result', (t, ctx) => {
  t.plan(1);

  const htmlRequest = {
    method: 'GET',
    url: '/people/smgc-people-noResult',
    headers: {'Accept': 'application/vnd.api+json'}
  };

  ctx.server.inject(htmlRequest, (res) => {
    // {"errors":[{"title":"Not Found","status":404,"detail":"Person not found"}]}
    var response = JSON.parse(res.payload);
    t.ok(response.errors[0].detail, 404, 'Person not found');
    t.end();
  });
});
<|endoftext|>


<commit_before>import makeConsoleMock from 'consolemock'
import execa from 'execa'

import getStagedFiles from '../src/getStagedFiles'
import runAll from '../src/runAll'
import { hasPartiallyStagedFiles, gitStashSave, gitStashPop, updateStash } from '../src/gitWorkflow'

jest.mock('../src/getStagedFiles')
jest.mock('../src/gitWorkflow')

getStagedFiles.mockImplementation(async () => [])

const globalConsoleTemp = global.console

describe('runAll', () => {
  beforeAll(() => {
    global.console = makeConsoleMock()
  })

  afterEach(() => {
    global.console.clearHistory()
    gitStashSave.mockClear()
    gitStashPop.mockClear()
    updateStash.mockClear()
  })

  afterAll(() => {
    global.console = globalConsoleTemp
  })

  it('should not throw when a valid config is provided', () => {
    expect(() => runAll({})).not.toThrow()
  })

  it('should return a promise', () => {
    expect(runAll({})).toBeInstanceOf(Promise)
  })

  it('should resolve the promise with no tasks', async () => {
    expect.assertions(1)
    const res = await runAll({ config: {} })

    expect(res).toEqual('No tasks to run.')
  })

  it('should resolve the promise with no files', async () => {
    expect.assertions(1)
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should use an injected logger', async () => {
    expect.assertions(1)
    const logger = makeConsoleMock()
    await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger)
    expect(logger.printHistory()).toMatchSnapshot()
  })

  it('should not skip tasks if there are files', async () => {
    expect.assertions(1)
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should not skip stashing and restoring if there are partially staged files', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(1)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip stashing and restoring if there are no partially staged files', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(gitStashSave).toHaveBeenCalledTimes(0)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(0)
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip updating stash if there are errors during linting', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    execa.mockImplementation(() =>
      Promise.resolve({
        stdout: '',
        stderr: 'Linter finished with error',
        code: 1,
        failed: true,
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
  })

  it('should warn if the argument length is longer than what the platform can handle', async () => {
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false))
    getStagedFiles.mockImplementationOnce(async () => new Array(100000).fill('sample.js'))

    try {
      await runAll({ config: { '*.js': () => 'echo "sample"' } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip linters and stash update but perform working copy restore if terminated', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    execa.mockImplementation(() =>
      Promise.resolve({
        stdout: '',
        stderr: '',
        code: 0,
        failed: false,
        killed: true,
        signal: 'SIGINT',
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
  })

  it('should reject promise when error during getStagedFiles', async () => {
    expect.assertions(1)
    getStagedFiles.mockImplementationOnce(async () => null)
    await expect(runAll({})).rejects.toThrowErrorMatchingSnapshot()
  })

  it('should skip stashing changes if no lint-staged files are changed', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.java'])
    execa.mockImplementationOnce(() =>
      Promise.resolve({
        stdout: '',
        stderr: 'Linter finished with error',
        code: 1,
        failed: true,
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(0)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(0)
  })
})
<commit_msg>test: mock resolveGitDir to fix runAll tests<commit_after>import makeConsoleMock from 'consolemock'
import execa from 'execa'
import normalize from 'normalize-path'

import resolveGitDir from '../src/resolveGitDir'
import getStagedFiles from '../src/getStagedFiles'
import runAll from '../src/runAll'
import { hasPartiallyStagedFiles, gitStashSave, gitStashPop, updateStash } from '../src/gitWorkflow'

jest.mock('../src/resolveGitDir')
jest.mock('../src/getStagedFiles')
jest.mock('../src/gitWorkflow')

resolveGitDir.mockImplementation(async () => normalize(process.cwd()))
getStagedFiles.mockImplementation(async () => [])

const globalConsoleTemp = console

describe('runAll', () => {
  beforeAll(() => {
    console = makeConsoleMock()
  })

  afterEach(() => {
    console.clearHistory()
    gitStashSave.mockClear()
    gitStashPop.mockClear()
    updateStash.mockClear()
  })

  afterAll(() => {
    console = globalConsoleTemp
  })

  it('should not throw when a valid config is provided', () => {
    expect(() => runAll({})).not.toThrow()
  })

  it('should return a promise', () => {
    expect(runAll({})).toBeInstanceOf(Promise)
  })

  it('should resolve the promise with no tasks', async () => {
    expect.assertions(1)
    const res = await runAll({ config: {} })

    expect(res).toEqual('No tasks to run.')
  })

  it('should resolve the promise with no files', async () => {
    expect.assertions(1)
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should use an injected logger', async () => {
    expect.assertions(1)
    const logger = makeConsoleMock()
    await runAll({ config: { '*.js': ['echo "sample"'] }, debug: true }, logger)
    expect(logger.printHistory()).toMatchSnapshot()
  })

  it('should not skip tasks if there are files', async () => {
    expect.assertions(1)
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should not skip stashing and restoring if there are partially staged files', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(1)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip stashing and restoring if there are no partially staged files', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    await runAll({ config: { '*.js': ['echo "sample"'] } })
    expect(gitStashSave).toHaveBeenCalledTimes(0)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(0)
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip updating stash if there are errors during linting', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    execa.mockImplementation(() =>
      Promise.resolve({
        stdout: '',
        stderr: 'Linter finished with error',
        code: 1,
        failed: true,
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
  })

  it('should warn if the argument length is longer than what the platform can handle', async () => {
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(false))
    getStagedFiles.mockImplementationOnce(async () => new Array(100000).fill('sample.js'))

    try {
      await runAll({ config: { '*.js': () => 'echo "sample"' } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
  })

  it('should skip linters and stash update but perform working copy restore if terminated', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.js'])
    execa.mockImplementation(() =>
      Promise.resolve({
        stdout: '',
        stderr: '',
        code: 0,
        failed: false,
        killed: true,
        signal: 'SIGINT',
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(1)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(1)
  })

  it('should reject promise when error during getStagedFiles', async () => {
    expect.assertions(1)
    getStagedFiles.mockImplementationOnce(async () => null)
    await expect(runAll({})).rejects.toThrowErrorMatchingSnapshot()
  })

  it('should skip stashing changes if no lint-staged files are changed', async () => {
    expect.assertions(4)
    hasPartiallyStagedFiles.mockImplementationOnce(() => Promise.resolve(true))
    getStagedFiles.mockImplementationOnce(async () => ['sample.java'])
    execa.mockImplementationOnce(() =>
      Promise.resolve({
        stdout: '',
        stderr: 'Linter finished with error',
        code: 1,
        failed: true,
        cmd: 'mock cmd'
      })
    )

    try {
      await runAll({ config: { '*.js': ['echo "sample"'] } })
    } catch (err) {
      console.log(err)
    }
    expect(console.printHistory()).toMatchSnapshot()
    expect(gitStashSave).toHaveBeenCalledTimes(0)
    expect(updateStash).toHaveBeenCalledTimes(0)
    expect(gitStashPop).toHaveBeenCalledTimes(0)
  })
})
<|endoftext|>


<commit_before>"use strict";

const Constants = require("../Constants");
const Events = Constants.Events;
const StatusTypes = Constants.StatusTypes;
const Utils = require("../core/Utils");
const BaseCollection = require("./BaseCollection");

const User = require("../models/User");

function updatePresence(guildId, userId, status, gameId) {
  if (userId === this._discordie._user.id) return;

  let previousPresence = {
    status: this._statuses[userId],
    gameId: this._games[userId]
  };

  let presencesForUser =
    (this._presencesForGuilds[userId] =
    this._presencesForGuilds[userId] || {});

  if (status === StatusTypes.OFFLINE) {
    delete presencesForUser[guildId];
    if (!Object.keys(presencesForUser).length) {
      delete this._presencesForGuilds[userId];
    }
    delete this._statuses[userId];
    delete this._games[userId];
  } else {
    presencesForUser[guildId] = {status, gameId};
    this._statuses[userId] = StatusTypes.IDLE;
    this._games[userId] = null;
    for (let guildId of Object.keys(this._presencesForGuilds[userId])) {
      const presence = this._presencesForGuilds[userId][guildId];
      if (presence.status === StatusTypes.ONLINE) {
        this._statuses[userId] = StatusTypes.ONLINE;
      }
      if (presence.gameId) {
        //this._games[userId] = Games.nameForId(presence.gameId);
        // ^ move to IUser.getGameName()
        this._games[userId] = presence.gameId;
        // todo: gamesLoader
      }
    }
  }

  this._previousPresences[userId] = previousPresence;
  if (!previousPresence.status) {
    delete this._previousPresences[userId];
  }
}

function handleConnectionOpen(data) {
  this._presencesForGuilds = {};
  this._statuses = {};
  this._games = {};
  data.guilds.forEach(guild => handleGuildCreate.call(this, guild));
}

function handleGuildCreate(guild) {
  guild.presences.forEach(presence => {
    updatePresence.call(this,
      guild.id,
      presence.user.id,
      presence.status,
      presence.gameId
    );
  });
}

function handleGuildDelete(guild) {
  for (let userId of Object.keys(this._presencesForGuilds)) {
    if (!this._presencesForGuilds[userId][guild.id]) continue;
    updatePresence.call(this, guild.id, userId, StatusTypes.OFFLINE, null);
  }
}

function handleGuildMemberRemove(member) {
  updatePresence.call(this,
    member.guild_id,
    member.user.id,
    StatusTypes.OFFLINE,
    null
  );
}

function handlePresenceUpdate(presence) {
  updatePresence.call(this,
    presence.guild_id,
    presence.user.id,
    presence.status,
    presence.game_id
  );
}

class PresenceCollection {
  constructor(discordie, gateway) {
    if (typeof gateway !== "function")
      throw new Error("Gateway parameter must be a function");

    discordie.Dispatcher.on(Events.GATEWAY_READY, e => {
      if (e.socket != gateway()) return;
      (handleConnectionOpen.bind(this))(e.data);
    });
    discordie.Dispatcher.on(Events.GATEWAY_DISPATCH, e => {
      if (e.socket != gateway()) return;

      Utils.bindGatewayEventHandlers(this, e, {
        GUILD_CREATE: handleGuildCreate,
        GUILD_DELETE: handleGuildDelete,
        GUILD_MEMBER_REMOVE: handleGuildMemberRemove,
        PRESENCE_UPDATE: handlePresenceUpdate
      });
    });

    this._presencesForGuilds = {};
    this._previousPresences = {};
    this._statuses = {};
    this._games = {};

    this._discordie = discordie;
    Utils.privatify(this);
  }
  getStatus(userId) {
    if (this._discordie._user && this._discordie._user.id == userId) {
      return this._discordie._user.status;
    }
    if (this._statuses.hasOwnProperty(userId)) {
      return this._statuses[userId];
    }
    return StatusTypes.OFFLINE;
  }
  getPreviousStatus(userId) {
    if (this._previousPresences.hasOwnProperty(userId)) {
      return this._previousPresences[userId].status;
    }
    return StatusTypes.OFFLINE;
  }
  getGame(userId) {
    if (this._discordie._user && this._discordie._user.id == userId) {
      return this._discordie._user.gameId;
    }
    if (this._games.hasOwnProperty(userId)) {
      return this._games[userId];
    }
    return null;
  }
  getPreviousGame(userId) {
    if (this._previousPresences.hasOwnProperty(userId)) {
      return this._previousPresences[userId].gameId;
    }
    return null;
  }
}

module.exports = PresenceCollection;
<commit_msg>Refactor cache initialization for presences<commit_after>"use strict";

const Constants = require("../Constants");
const Events = Constants.Events;
const StatusTypes = Constants.StatusTypes;
const Utils = require("../core/Utils");
const BaseCollection = require("./BaseCollection");

const User = require("../models/User");

function updatePresence(guildId, userId, status, gameId) {
  if (userId === this._discordie._user.id) return;

  let previousPresence = {
    status: this._statuses[userId],
    gameId: this._games[userId]
  };

  let presencesForUser =
    (this._presencesForGuilds[userId] =
    this._presencesForGuilds[userId] || {});

  if (status === StatusTypes.OFFLINE) {
    delete presencesForUser[guildId];
    if (!Object.keys(presencesForUser).length) {
      delete this._presencesForGuilds[userId];
    }
    delete this._statuses[userId];
    delete this._games[userId];
  } else {
    presencesForUser[guildId] = {status, gameId};
    this._statuses[userId] = StatusTypes.IDLE;
    this._games[userId] = null;
    for (let guildId of Object.keys(this._presencesForGuilds[userId])) {
      const presence = this._presencesForGuilds[userId][guildId];
      if (presence.status === StatusTypes.ONLINE) {
        this._statuses[userId] = StatusTypes.ONLINE;
      }
      if (presence.gameId) {
        //this._games[userId] = Games.nameForId(presence.gameId);
        // ^ move to IUser.getGameName()
        this._games[userId] = presence.gameId;
        // todo: gamesLoader
      }
    }
  }

  this._previousPresences[userId] = previousPresence;
  if (!previousPresence.status) {
    delete this._previousPresences[userId];
  }
}

function initializeCache() {
  this._presencesForGuilds = {};
  this._previousPresences = {};
  this._statuses = {};
  this._games = {};
}

function handleConnectionOpen(data) {
  initializeCache.call(this);
  data.guilds.forEach(guild => handleGuildCreate.call(this, guild));
}

function handleGuildCreate(guild) {
  guild.presences.forEach(presence => {
    updatePresence.call(this,
      guild.id,
      presence.user.id,
      presence.status,
      presence.gameId
    );
  });
}

function handleGuildDelete(guild) {
  for (let userId of Object.keys(this._presencesForGuilds)) {
    if (!this._presencesForGuilds[userId][guild.id]) continue;
    updatePresence.call(this, guild.id, userId, StatusTypes.OFFLINE, null);
  }
}

function handleGuildMemberRemove(member) {
  updatePresence.call(this,
    member.guild_id,
    member.user.id,
    StatusTypes.OFFLINE,
    null
  );
}

function handlePresenceUpdate(presence) {
  updatePresence.call(this,
    presence.guild_id,
    presence.user.id,
    presence.status,
    presence.game_id
  );
}

class PresenceCollection {
  constructor(discordie, gateway) {
    if (typeof gateway !== "function")
      throw new Error("Gateway parameter must be a function");

    discordie.Dispatcher.on(Events.GATEWAY_READY, e => {
      if (e.socket != gateway()) return;
      (handleConnectionOpen.bind(this))(e.data);
    });
    discordie.Dispatcher.on(Events.GATEWAY_DISPATCH, e => {
      if (e.socket != gateway()) return;

      Utils.bindGatewayEventHandlers(this, e, {
        GUILD_CREATE: handleGuildCreate,
        GUILD_DELETE: handleGuildDelete,
        GUILD_MEMBER_REMOVE: handleGuildMemberRemove,
        PRESENCE_UPDATE: handlePresenceUpdate
      });
    });

    initializeCache.call(this);

    this._discordie = discordie;
    Utils.privatify(this);
  }
  getStatus(userId) {
    if (this._discordie._user && this._discordie._user.id == userId) {
      return this._discordie._user.status;
    }
    if (this._statuses.hasOwnProperty(userId)) {
      return this._statuses[userId];
    }
    return StatusTypes.OFFLINE;
  }
  getPreviousStatus(userId) {
    if (this._previousPresences.hasOwnProperty(userId)) {
      return this._previousPresences[userId].status;
    }
    return StatusTypes.OFFLINE;
  }
  getGame(userId) {
    if (this._discordie._user && this._discordie._user.id == userId) {
      return this._discordie._user.gameId;
    }
    if (this._games.hasOwnProperty(userId)) {
      return this._games[userId];
    }
    return null;
  }
  getPreviousGame(userId) {
    if (this._previousPresences.hasOwnProperty(userId)) {
      return this._previousPresences[userId].gameId;
    }
    return null;
  }
}

module.exports = PresenceCollection;
<|endoftext|>


<commit_before>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const { set } = Ember;
const { run: { later } } = Ember;

moduleForComponent('ember-lxl', 'Integration | Component | ember lxl', {
  integration: true
});

test('it parses words into word and letter spans', function(assert) {
  assert.expect(2);

  this.render(hbs`{{ember-lxl text="Word, I have a word."}}`);

  assert.equal(this.$('.lxl-word').length, 5, 'it wraps words');
  assert.equal(this.$('.lxl-word:first .lxl-letter').length, 5, 'it wraps characters into spans');
});

test('tags are respected', function(assert) {
  assert.expect(7);

  this.render(hbs`{{ember-lxl text="Outside <span id='span'>inside <strong id='strong'>bold</strong></span>"}}`);

  assert.equal(this.$('.lxl-word').length, 3, 'it wraps words');

  const $span = this.$('#span');
  assert.equal($span.length, 1, 'span is present');
  assert.equal($span.text().trim(), 'inside  bold', 'span contains the right text');
  assert.ok($span.is('span'), 'span is correct element');

  const $strong = this.$('#strong');
  assert.equal($strong.length, 1, 'strong is present');
  assert.equal($strong.text().trim(), 'bold', 'strong contains the right text');
  assert.ok($strong.is('strong'), 'strong is correct element');
});

test('it gradually fades the characters in', function(assert) {
  assert.expect(5);

  const done = assert.async();

  this.render(hbs`{{ember-lxl text="Word." speed=100 rate=5}}`);

  assert.equal(this.$('.lxl-letter:first').css('opacity'), 0, 'first starts out 0');
  assert.equal(this.$('.lxl-letter:last').css('opacity'), 0, 'last starts out 0');

  later(() => {
    assert.ok(this.$('.lxl-letter:first').css('opacity') > this.$('.lxl-letter:last').css('opacity'), 'fades from first to last');
  }, 20);

  later(() => {
    assert.equal(this.$('.lxl-letter:first').css('opacity'), 1, 'first becomes 1');
    assert.equal(this.$('.lxl-letter:last').css('opacity'), 1, 'last becomes 1');

    done();
  }, 125);
});

test('it pauses once it reaches the bottom of the container', function(assert) {
  assert.expect(7);

  const done = assert.async();

  set(this, 'completed', () => {
    assert.ok(false, 'ran onComplete callback prematurely');
  });

  this.render(hbs`

      {{ember-lxl
        text="This is a really long sentance, but that's totally necessary!"
        speed=10000000000
        rate=0
        onComplete=(action completed)
      }}

  `);

  assert.equal(this.$('.lxl-word').length, 10, 'it immediately writes all words');
  assert.equal(this.$('.lxl-letter').length, 4, 'it starts with this many characters wrapped');

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 26, 'it continues wrapping characters');
  }, 250);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 26, 'it has stopped wrapping characters');

    this.$('.lxl-container').trigger('mouseup');

    set(this, 'completed', () => {
      assert.ok(true, 'ran onComplete callback at correct time');
    });
  }, 275);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 42, 'it has resumed wrapping characters');

    this.$('.lxl-container').trigger('mouseup');
  }, 450);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 52, 'it completes writing');

    this.$('.lxl-container').trigger('mouseup');

    done();
  }, 700);
});

test('text can be instawrote with a click', function(assert) {
  assert.expect(2);

  const done = assert.async();

  this.render(hbs`

      {{ember-lxl
        text="This is a really long sentance, but that's totally necessary!"
      }}

  `);

  assert.equal(this.$('.lxl-word:last').css('opacity'), 0, 'last word starts faded out');

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 25);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 50);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 75);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 100);

  later(() => {
    assert.equal(this.$('.lxl-word:last').css('opacity'), 1, 'last word faded in');

    done();
  }, 125);
});
<commit_msg>forever fixing travis<commit_after>import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

const { set } = Ember;
const { run: { later } } = Ember;

moduleForComponent('ember-lxl', 'Integration | Component | ember lxl', {
  integration: true
});

test('it parses words into word and letter spans', function(assert) {
  assert.expect(2);

  this.render(hbs`{{ember-lxl text="Word, I have a word."}}`);

  assert.equal(this.$('.lxl-word').length, 5, 'it wraps words');
  assert.equal(this.$('.lxl-word:first .lxl-letter').length, 5, 'it wraps characters into spans');
});

test('tags are respected', function(assert) {
  assert.expect(7);

  this.render(hbs`{{ember-lxl text="Outside <span id='span'>inside <strong id='strong'>bold</strong></span>"}}`);

  assert.equal(this.$('.lxl-word').length, 3, 'it wraps words');

  const $span = this.$('#span');
  assert.equal($span.length, 1, 'span is present');
  assert.equal($span.text().trim(), 'inside  bold', 'span contains the right text');
  assert.ok($span.is('span'), 'span is correct element');

  const $strong = this.$('#strong');
  assert.equal($strong.length, 1, 'strong is present');
  assert.equal($strong.text().trim(), 'bold', 'strong contains the right text');
  assert.ok($strong.is('strong'), 'strong is correct element');
});

test('it gradually fades the characters in', function(assert) {
  assert.expect(5);

  const done = assert.async();

  this.render(hbs`{{ember-lxl text="Word." speed=100 rate=5}}`);

  assert.equal(this.$('.lxl-letter:first').css('opacity'), 0, 'first starts out 0');
  assert.equal(this.$('.lxl-letter:last').css('opacity'), 0, 'last starts out 0');

  later(() => {
    assert.ok(this.$('.lxl-letter:first').css('opacity') > this.$('.lxl-letter:last').css('opacity'), 'fades from first to last');
  }, 20);

  later(() => {
    assert.equal(this.$('.lxl-letter:first').css('opacity'), 1, 'first becomes 1');
    assert.equal(this.$('.lxl-letter:last').css('opacity'), 1, 'last becomes 1');

    done();
  }, 125);
});

test('it pauses once it reaches the bottom of the container', function(assert) {
  assert.expect(7);

  const done = assert.async();

  set(this, 'completed', () => {
    assert.ok(false, 'ran onComplete callback prematurely');
  });

  this.render(hbs`

      {{ember-lxl
        text="This is a really long sentance, but that's totally necessary!"
        speed=10000000000
        rate=0
        onComplete=(action completed)
      }}

  `);

  assert.equal(this.$('.lxl-word').length, 10, 'it immediately writes all words');
  assert.equal(this.$('.lxl-letter').length, 4, 'it starts with this many characters wrapped');

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 26, 'it continues wrapping characters');
  }, 350);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 26, 'it has stopped wrapping characters');

    this.$('.lxl-container').trigger('mouseup');

    set(this, 'completed', () => {
      assert.ok(true, 'ran onComplete callback at correct time');
    });
  }, 400);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 42, 'it has resumed wrapping characters');

    this.$('.lxl-container').trigger('mouseup');
  }, 750);

  later(() => {
    assert.equal(this.$('.lxl-letter').length, 52, 'it completes writing');

    this.$('.lxl-container').trigger('mouseup');

    done();
  }, 1000);
});

test('text can be instawrote with a click', function(assert) {
  assert.expect(2);

  const done = assert.async();

  this.render(hbs`

      {{ember-lxl
        text="This is a really long sentance, but that's totally necessary!"
      }}

  `);

  assert.equal(this.$('.lxl-word:last').css('opacity'), 0, 'last word starts faded out');

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 25);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 50);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 75);

  later(() => {
    this.$('.lxl-container').trigger('mouseup');
  }, 100);

  later(() => {
    assert.equal(this.$('.lxl-word:last').css('opacity'), 1, 'last word faded in');

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


<commit_before>'use strict';

module.exports = function (dbName, dbType, Pouch) {
  describe(dbType + ' test suite 1', function () {
    this.timeout(100000);

    var context = {};

    beforeEach(function () {
      this.timeout(60000);
      context.db = new Pouch(dbName);
      return context.db;
    });
    afterEach(function () {
      this.timeout(60000);
      return context.db.destroy();
    });

    require('./test.callbacks')(dbType, context);
    require('./test.basic')(dbType, context);
    require('./test.basic2')(dbType, context);
    require('./test.basic3')(dbType, context);
    require('./test.ddoc')(dbType, context);
    require('./test.set-operations')(dbType, context);
    require('./test.limit')(dbType, context);
    require('./test.skip')(dbType, context);
    require('./test.limit-skip')(dbType, context);
    require('./test.sorting')(dbType, context);
    require('./test.fields')(dbType, context);
    require('./test.ltgt')(dbType, context);
    require('./test.eq')(dbType, context);
    require('./test.deep-fields')(dbType, context);
    require('./test.pick-fields')(dbType, context);
    require('./test.exists')(dbType, context);
    require('./test.type')(dbType, context);
    require('./test.ne')(dbType, context);
    require('./test.matching-indexes')(dbType, context);
    require('./test.errors')(dbType, context);
    require('./test.array')(dbType, context);
    require('./test.combinational')(dbType, context);
    require('./test.elem-match')(dbType, context);
    require('./test.mod')(dbType, context);
    require('./test.regex')(dbType, context);
    require('./test.not')(dbType, context);
    require('./test.issue66')(dbType, context);
    require('./test.and')(dbType, context);
    require('./test.default-index')(dbType, context);
  });
};
<commit_msg>Use individual dbs for tests (#197)<commit_after>'use strict';

module.exports = function (dbName, dbType, Pouch) {
  describe(dbType + ' test suite 1', function () {
    this.timeout(100000);

    var context = {};

    beforeEach(function () {
      this.timeout(60000);

      var  dbNameWithTimestamp = dbName;
      if (dbType === 'http') {
        dbNameWithTimestamp = dbName + (new Date()).getTime();
      }

      context.db = new Pouch(dbNameWithTimestamp);
      return context.db;
    });
    afterEach(function () {
      this.timeout(60000);
      return context.db.destroy();
    });

    require('./test.callbacks')(dbType, context);
    require('./test.basic')(dbType, context);
    require('./test.basic2')(dbType, context);
    require('./test.basic3')(dbType, context);
    require('./test.ddoc')(dbType, context);
    require('./test.set-operations')(dbType, context);
    require('./test.limit')(dbType, context);
    require('./test.skip')(dbType, context);
    require('./test.limit-skip')(dbType, context);
    require('./test.sorting')(dbType, context);
    require('./test.fields')(dbType, context);
    require('./test.ltgt')(dbType, context);
    require('./test.eq')(dbType, context);
    require('./test.deep-fields')(dbType, context);
    require('./test.pick-fields')(dbType, context);
    require('./test.exists')(dbType, context);
    require('./test.type')(dbType, context);
    require('./test.ne')(dbType, context);
    require('./test.matching-indexes')(dbType, context);
    require('./test.errors')(dbType, context);
    require('./test.array')(dbType, context);
    require('./test.combinational')(dbType, context);
    require('./test.elem-match')(dbType, context);
    require('./test.mod')(dbType, context);
    require('./test.regex')(dbType, context);
    require('./test.not')(dbType, context);
    require('./test.issue66')(dbType, context);
    require('./test.and')(dbType, context);
    require('./test.default-index')(dbType, context);
  });
};
<|endoftext|>


<commit_before>var Schema = require('../lib/schema');
var should = require('should');
var _      = require('lodash');
var util   = require('./testutil');
var faker  = require('faker');

describe("Schema: ", function () {
  describe('types',function(){
    it('should map schema types to Elasticsearch types',function(){
      Schema.types.String.should.eql('string');
      Schema.types[String].should.eql('string');
    })
  })

  describe('getIndexMappingJSON', function() {
    it('should map a schema definition to a valid Elasticsearch Index Mapping', function(){
      var schema = new Schema({
        name: String,
        description: {type: String, index_analyzer:"type"},
        count: {type: 'number'},
        max: Number,
        anotherField: Schema.types.String,
        anotherProperty: String
      });
      var map = schema.getIndexMappingJSON();
      map.should.be.ok;
      map.should.have.property('properties');
      _.each(map.properties, function (e) {
        e.should.have.property('type');
      });
    });
  });

  describe('validate document', function() {
    it('should pass validation', function() {
      var schema = new Schema({
        name: String,
        description: { type: String },
        count: Number
      });
      var err = schema.validateDoc({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number()
      });
      err.should.be.Array;
      err.length.should.be.eql(0);
    });
    it('should pass validation', function() {
      var schema = new Schema({
        name: String,
        description: { type: String },
        count: Number
      });
      var err = schema.validateDoc({
        name: faker.name.findName(),
        description: faker.lorem.sentences()
      });
      err.should.be.be.Array;
      err.length.should.eql(1);
    });
  });
  describe('apply schema', function() {
    var schema = new Schema({
      name: String,
      description: { type: String },
      count: Number
    });

    it('apply schema with correct doc', function() {
      var appliedSchema = schema.applySchema({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number()
      });
      appliedSchema.should.have.properties(['name', 'description', 'count']);
    });
    it('apply schema with correct doc', function() {
      var appliedSchema = schema.applySchema({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number(),
        blah: faker.lorem.words()
      });
      appliedSchema.should.have.properties(['name', 'description', 'count']);
      appliedSchema.should.not.have.property('dog');
    });
    it('apply schema should throw error', function() {
      util.shouldThrowError(function () {
        var appliedSchema = schema.applySchema({
          name: faker.nae.findName(),
          description: faker.lorem.sentences()
        });
      });
    });
  });
});
<commit_msg>formatting for schema test<commit_after>var Schema = require('../lib/schema');
var should = require('should');
var _      = require('lodash');
var util   = require('./testutil');
var faker  = require('faker');

describe("Schema: ", function () {
  describe('types',function(){
    it('should map schema types to Elasticsearch types',function(){
      Schema.types.String.should.eql('string');
      Schema.types[String].should.eql('string');
    });
  });

  describe('getIndexMappingJSON', function() {
    it('should map a schema definition to a valid Elasticsearch Index Mapping', function(){
      var schema = new Schema({
        name: String,
        description: {type: String, index_analyzer:"type"},
        count: {type: 'number'},
        max: Number,
        anotherField: Schema.types.String,
        anotherProperty: String
      });
      var map = schema.getIndexMappingJSON();
      map.should.be.ok;
      map.should.have.property('properties');
      _.each(map.properties, function (e) {
        e.should.have.property('type');
      });
    });
  });

  describe('validate document', function() {
    it('should pass validation', function() {
      var schema = new Schema({
        name: String,
        description: { type: String },
        count: Number
      });
      var err = schema.validateDoc({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number()
      });
      err.should.be.Array;
      err.length.should.be.eql(0);
    });

    it('should pass validation', function() {
      var schema = new Schema({
        name: String,
        description: { type: String },
        count: Number
      });
      var err = schema.validateDoc({
        name: faker.name.findName(),
        description: faker.lorem.sentences()
      });
      err.should.be.be.Array;
      err.length.should.eql(1);
    });
  });

  describe('apply schema', function() {
    var schema = new Schema({
      name: String,
      description: { type: String },
      count: Number
    });

    it('apply schema with correct doc', function() {
      var appliedSchema = schema.applySchema({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number()
      });
      appliedSchema.should.have.properties(['name', 'description', 'count']);
    });

    it('apply schema with correct doc', function() {
      var appliedSchema = schema.applySchema({
        name: faker.name.findName(),
        description: faker.lorem.sentences(),
        count: faker.random.number(),
        blah: faker.lorem.words()
      });
      appliedSchema.should.have.properties(['name', 'description', 'count']);
      appliedSchema.should.not.have.property('dog');
    });

    it('apply schema should throw error', function() {
      util.shouldThrowError(function () {
        var appliedSchema = schema.applySchema({
          name: faker.nae.findName(),
          description: faker.lorem.sentences()
        });
      });
    });
  });
});
<|endoftext|>