Merge pull request #96 from gnosis/prettier-code-format

prettier code formatting
This commit is contained in:
Mikhail Mikheev 2019-03-29 17:53:14 +04:00 committed by GitHub
commit 586acc16f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 1811 additions and 807 deletions

1502
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,8 @@
"start": "node scripts/start.js",
"storybook": "start-storybook -p 6006",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom"
"test-local": "NODE_ENV=test && node scripts/test.js --env=jsdom",
"format": "prettier-eslint \"src/**/*.js\" --write"
},
"pre-commit": [
"precommit"
@ -152,6 +153,7 @@
"postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^5.0.2",
"pre-commit": "^1.2.2",
"prettier-eslint-cli": "^4.7.1",
"run-with-testrpc": "^0.3.0",
"storybook-host": "^5.0.3",
"storybook-router": "^0.3.3",

View File

@ -7,7 +7,7 @@ import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
<div style={{ flex: '1' }} />
{ story() }
{story()}
</div>
)

View File

@ -8,11 +8,7 @@ import UserDetails from './ProviderDetails/UserDetails'
import ProviderDisconnected from './ProviderInfo/ProviderDisconnected'
import ConnectDetails from './ProviderDetails/ConnectDetails'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Components /Header', module)
.addDecorator(FrameDecorator)
@ -36,12 +32,7 @@ storiesOf('Components /Header', module)
const userAddress = '0x873faa4cddd5b157e8e5a57e7a5479afc5d30moe'
const network = 'RINKEBY'
const info = <ProviderAccesible provider={provider} network={network} userAddress={userAddress} connected={false} />
const details = (<UserDetails
provider={provider}
network={network}
userAddress={userAddress}
connected={false}
/>)
const details = <UserDetails provider={provider} network={network} userAddress={userAddress} connected={false} />
return <Layout providerInfo={info} providerDetails={details} />
})

View File

@ -1,6 +1,12 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { providerNameSelector, userAccountSelector, networkSelector, availableSelector, loadedSelector } from '~/logic/wallets/store/selectors'
import {
providerNameSelector,
userAccountSelector,
networkSelector,
availableSelector,
loadedSelector,
} from '~/logic/wallets/store/selectors'
export type SelectorProps = {
provider: string,

View File

@ -1,10 +1,12 @@
/* eslint-disable */
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.blockies = {})));
}(this, (function (exports) {
'use strict';
;(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? factory(exports)
: typeof define === 'function' && define.amd
? define(['exports'], factory)
: factory((global.blockies = {}))
})(this, function(exports) {
'use strict'
/**
* A handy class to calculate color values.
@ -17,207 +19,210 @@
*
*/
// helper functions for that ctx
function write(buffer, offs) {
for (var i = 2; i < arguments.length; i++) {
for (var j = 0; j < arguments[i].length; j++) {
buffer[offs++] = arguments[i].charAt(j);
buffer[offs++] = arguments[i].charAt(j)
}
}
}
function byte2(w) {
return String.fromCharCode((w >> 8) & 255, w & 255);
return String.fromCharCode((w >> 8) & 255, w & 255)
}
function byte4(w) {
return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255);
return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255)
}
function byte2lsb(w) {
return String.fromCharCode(w & 255, (w >> 8) & 255);
return String.fromCharCode(w & 255, (w >> 8) & 255)
}
var PNG = function (width, height, depth) {
this.width = width;
this.height = height;
this.depth = depth;
var PNG = function(width, height, depth) {
this.width = width
this.height = height
this.depth = depth
// pixel data and row filter identifier size
this.pix_size = height * (width + 1);
this.pix_size = height * (width + 1)
// deflate header, pix_size, block headers, adler32 checksum
this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4;
this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4
// offsets and sizes of Png chunks
this.ihdr_offs = 0; // IHDR offset and size
this.ihdr_size = 4 + 4 + 13 + 4;
this.plte_offs = this.ihdr_offs + this.ihdr_size; // PLTE offset and size
this.plte_size = 4 + 4 + 3 * depth + 4;
this.trns_offs = this.plte_offs + this.plte_size; // tRNS offset and size
this.trns_size = 4 + 4 + depth + 4;
this.idat_offs = this.trns_offs + this.trns_size; // IDAT offset and size
this.idat_size = 4 + 4 + this.data_size + 4;
this.iend_offs = this.idat_offs + this.idat_size; // IEND offset and size
this.iend_size = 4 + 4 + 4;
this.buffer_size = this.iend_offs + this.iend_size; // total PNG size
this.ihdr_offs = 0 // IHDR offset and size
this.ihdr_size = 4 + 4 + 13 + 4
this.plte_offs = this.ihdr_offs + this.ihdr_size // PLTE offset and size
this.plte_size = 4 + 4 + 3 * depth + 4
this.trns_offs = this.plte_offs + this.plte_size // tRNS offset and size
this.trns_size = 4 + 4 + depth + 4
this.idat_offs = this.trns_offs + this.trns_size // IDAT offset and size
this.idat_size = 4 + 4 + this.data_size + 4
this.iend_offs = this.idat_offs + this.idat_size // IEND offset and size
this.iend_size = 4 + 4 + 4
this.buffer_size = this.iend_offs + this.iend_size // total PNG size
this.buffer = new Array();
this.palette = new Object();
this.pindex = 0;
this.buffer = new Array()
this.palette = new Object()
this.pindex = 0
var _crc32 = new Array();
var _crc32 = new Array()
// initialize buffer with zero bytes
for (var i = 0; i < this.buffer_size; i++) {
this.buffer[i] = "\x00";
this.buffer[i] = '\x00'
}
// initialize non-zero elements
write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), "\x08\x03");
write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE');
write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS');
write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT');
write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND');
write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), '\x08\x03')
write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE')
write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS')
write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT')
write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND')
// initialize deflate header
var header = ((8 + (7 << 4)) << 8) | (3 << 6);
header += 31 - (header % 31);
var header = ((8 + (7 << 4)) << 8) | (3 << 6)
header += 31 - (header % 31)
write(this.buffer, this.idat_offs + 8, byte2(header));
write(this.buffer, this.idat_offs + 8, byte2(header))
// initialize deflate block headers
for (var i = 0; (i << 16) - 1 < this.pix_size; i++) {
var size, bits;
var size, bits
if (i + 0xffff < this.pix_size) {
size = 0xffff;
bits = "\x00";
size = 0xffff
bits = '\x00'
} else {
size = this.pix_size - (i << 16) - i;
bits = "\x01";
size = this.pix_size - (i << 16) - i
bits = '\x01'
}
write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size));
write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size))
}
/* Create crc32 lookup table */
for (var i = 0; i < 256; i++) {
var c = i;
var c = i
for (var j = 0; j < 8; j++) {
if (c & 1) {
c = -306674912 ^ ((c >> 1) & 0x7fffffff);
c = -306674912 ^ ((c >> 1) & 0x7fffffff)
} else {
c = (c >> 1) & 0x7fffffff;
c = (c >> 1) & 0x7fffffff
}
}
_crc32[i] = c;
_crc32[i] = c
}
// compute the index into a png for a given pixel
this.index = function (x, y) {
var i = y * (this.width + 1) + x + 1;
var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i;
return j;
};
this.index = function(x, y) {
var i = y * (this.width + 1) + x + 1
var j = this.idat_offs + 8 + 2 + 5 * Math.floor(i / 0xffff + 1) + i
return j
}
// convert a color and build up the palette
this.color = function (red, green, blue, alpha) {
this.color = function(red, green, blue, alpha) {
alpha = alpha >= 0 ? alpha : 255
var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue
alpha = alpha >= 0 ? alpha : 255;
var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue;
if (typeof this.palette[color] == 'undefined') {
if (this.pindex == this.depth) return '\x00'
if (typeof this.palette[color] == "undefined") {
if (this.pindex == this.depth) return "\x00";
var ndx = this.plte_offs + 8 + 3 * this.pindex
var ndx = this.plte_offs + 8 + 3 * this.pindex;
this.buffer[ndx + 0] = String.fromCharCode(red)
this.buffer[ndx + 1] = String.fromCharCode(green)
this.buffer[ndx + 2] = String.fromCharCode(blue)
this.buffer[this.trns_offs + 8 + this.pindex] = String.fromCharCode(alpha)
this.buffer[ndx + 0] = String.fromCharCode(red);
this.buffer[ndx + 1] = String.fromCharCode(green);
this.buffer[ndx + 2] = String.fromCharCode(blue);
this.buffer[this.trns_offs + 8 + this.pindex] = String.fromCharCode(alpha);
this.palette[color] = String.fromCharCode(this.pindex++);
this.palette[color] = String.fromCharCode(this.pindex++)
}
return this.palette[color];
};
return this.palette[color]
}
// output a PNG string, Base64 encoded
this.getBase64 = function () {
this.getBase64 = function() {
var s = this.getDump()
var s = this.getDump();
var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var c1, c2, c3, e1, e2, e3, e4;
var l = s.length;
var i = 0;
var r = "";
var ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
var c1, c2, c3, e1, e2, e3, e4
var l = s.length
var i = 0
var r = ''
do {
c1 = s.charCodeAt(i);
e1 = c1 >> 2;
c2 = s.charCodeAt(i + 1);
e2 = ((c1 & 3) << 4) | (c2 >> 4);
c3 = s.charCodeAt(i + 2);
if (l < i + 2) { e3 = 64; } else { e3 = ((c2 & 0xf) << 2) | (c3 >> 6); }
if (l < i + 3) { e4 = 64; } else { e4 = c3 & 0x3f; }
r += ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4);
} while ((i += 3) < l);
return r;
};
c1 = s.charCodeAt(i)
e1 = c1 >> 2
c2 = s.charCodeAt(i + 1)
e2 = ((c1 & 3) << 4) | (c2 >> 4)
c3 = s.charCodeAt(i + 2)
if (l < i + 2) {
e3 = 64
} else {
e3 = ((c2 & 0xf) << 2) | (c3 >> 6)
}
if (l < i + 3) {
e4 = 64
} else {
e4 = c3 & 0x3f
}
r += ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4)
} while ((i += 3) < l)
return r
}
// output a PNG string
this.getDump = function () {
this.getDump = function() {
// compute adler32 of output pixels + row filter bytes
var BASE = 65521; /* largest prime smaller than 65536 */
var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
var s1 = 1;
var s2 = 0;
var n = NMAX;
var BASE = 65521 /* largest prime smaller than 65536 */
var NMAX = 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
var s1 = 1
var s2 = 0
var n = NMAX
for (var y = 0; y < this.height; y++) {
for (var x = -1; x < this.width; x++) {
s1 += this.buffer[this.index(x, y)].charCodeAt(0);
s2 += s1;
s1 += this.buffer[this.index(x, y)].charCodeAt(0)
s2 += s1
if ((n -= 1) == 0) {
s1 %= BASE;
s2 %= BASE;
n = NMAX;
s1 %= BASE
s2 %= BASE
n = NMAX
}
}
}
s1 %= BASE;
s2 %= BASE;
write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1));
s1 %= BASE
s2 %= BASE
write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1))
// compute crc32 of the PNG chunks
function crc32(png, offs, size) {
var crc = -1;
var crc = -1
for (var i = 4; i < size - 4; i += 1) {
crc = _crc32[(crc ^ png[offs + i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff);
crc = _crc32[(crc ^ png[offs + i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff)
}
write(png, offs + size - 4, byte4(crc ^ -1));
write(png, offs + size - 4, byte4(crc ^ -1))
}
crc32(this.buffer, this.ihdr_offs, this.ihdr_size);
crc32(this.buffer, this.plte_offs, this.plte_size);
crc32(this.buffer, this.trns_offs, this.trns_size);
crc32(this.buffer, this.idat_offs, this.idat_size);
crc32(this.buffer, this.iend_offs, this.iend_size);
crc32(this.buffer, this.ihdr_offs, this.ihdr_size)
crc32(this.buffer, this.plte_offs, this.plte_size)
crc32(this.buffer, this.trns_offs, this.trns_size)
crc32(this.buffer, this.idat_offs, this.idat_size)
crc32(this.buffer, this.iend_offs, this.iend_size)
// convert PNG to string
return "\x89PNG\r\n\x1A\n" + this.buffer.join('');
};
return '\x89PNG\r\n\x1A\n' + this.buffer.join('')
}
this.fillRect = function (x, y, w, h, color) {
this.fillRect = function(x, y, w, h, color) {
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
this.buffer[this.index(x + i, y + j)] = color;
this.buffer[this.index(x + i, y + j)] = color
}
}
};
};
}
}
// https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
/**
@ -233,90 +238,90 @@
*/
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
if (t < 0) t += 1
if (t > 1) t -= 1
if (t < 1 / 6) return p + (q - p) * 6 * t
if (t < 1 / 2) return q
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6
return p
}
function hsl2rgb(h, s, l) {
var r, g, b;
var r, g, b
if (s == 0) {
r = g = b = l; // achromatic
r = g = b = l // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
var q = l < 0.5 ? l * (1 + s) : l + s - l * s
var p = 2 * l - q
r = hue2rgb(p, q, h + 1 / 3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1 / 3)
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255];
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255]
}
// The random number is a js implementation of the Xorshift PRNG
var randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values
var randseed = new Array(4) // Xorshift: [x, y, z, w] 32 bit values
function seedrand(seed) {
for (var i = 0; i < randseed.length; i++) {
randseed[i] = 0;
randseed[i] = 0
}
for (var i = 0; i < seed.length; i++) {
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i);
randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i)
}
}
function rand() {
// based on Java's String.hashCode(), expanded to 4 32bit values
var t = randseed[0] ^ (randseed[0] << 11);
var t = randseed[0] ^ (randseed[0] << 11)
randseed[0] = randseed[1];
randseed[1] = randseed[2];
randseed[2] = randseed[3];
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);
randseed[0] = randseed[1]
randseed[1] = randseed[2]
randseed[2] = randseed[3]
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8)
return (randseed[3] >>> 0) / (1 << 31 >>> 0);
return (randseed[3] >>> 0) / ((1 << 31) >>> 0)
}
function createColor() {
//saturation is the whole color spectrum
var h = Math.floor(rand() * 360);
var h = Math.floor(rand() * 360)
//saturation goes from 40 to 100, it avoids greyish colors
var s = rand() * 60 + 40;
var s = rand() * 60 + 40
//lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
var l = (rand() + rand() + rand() + rand()) * 25;
var l = (rand() + rand() + rand() + rand()) * 25
return [h / 360, s / 100, l / 100];
return [h / 360, s / 100, l / 100]
}
function createImageData(size) {
var width = size; // Only support square icons for now
var height = size;
var width = size // Only support square icons for now
var height = size
var dataWidth = Math.ceil(width / 2);
var mirrorWidth = width - dataWidth;
var dataWidth = Math.ceil(width / 2)
var mirrorWidth = width - dataWidth
var data = [];
var data = []
for (var y = 0; y < height; y++) {
var row = [];
var row = []
for (var x = 0; x < dataWidth; x++) {
// this makes foreground and background color to have a 43% (1/2.3) probability
// spot color has 13% chance
row[x] = Math.floor(rand() * 2.3);
row[x] = Math.floor(rand() * 2.3)
}
var r = row.slice(0, mirrorWidth);
r.reverse();
row = row.concat(r);
var r = row.slice(0, mirrorWidth)
r.reverse()
row = row.concat(r)
for (var i = 0; i < row.length; i++) {
data.push(row[i]);
data.push(row[i])
}
}
return data;
return data
}
function buildOpts(opts) {
@ -324,43 +329,45 @@
throw 'No seed provided'
}
seedrand(opts.seed);
seedrand(opts.seed)
return Object.assign({
size: 8,
scale: 16,
color: createColor(),
bgcolor: createColor(),
spotcolor: createColor(),
}, opts)
return Object.assign(
{
size: 8,
scale: 16,
color: createColor(),
bgcolor: createColor(),
spotcolor: createColor(),
},
opts,
)
}
function toDataUrl(address) {
const opts = buildOpts({ seed: address.toLowerCase() });
const opts = buildOpts({ seed: address.toLowerCase() })
const imageData = createImageData(opts.size);
const width = Math.sqrt(imageData.length);
const imageData = createImageData(opts.size)
const width = Math.sqrt(imageData.length)
const p = new PNG(opts.size * opts.scale, opts.size * opts.scale, 3);
const bgcolor = p.color(...hsl2rgb(...opts.bgcolor));
const color = p.color(...hsl2rgb(...opts.color));
const spotcolor = p.color(...hsl2rgb(...opts.spotcolor));
const p = new PNG(opts.size * opts.scale, opts.size * opts.scale, 3)
const bgcolor = p.color(...hsl2rgb(...opts.bgcolor))
const color = p.color(...hsl2rgb(...opts.color))
const spotcolor = p.color(...hsl2rgb(...opts.spotcolor))
for (var i = 0; i < imageData.length; i++) {
var row = Math.floor(i / width);
var col = i % width;
var row = Math.floor(i / width)
var col = i % width
// if data is 0, leave the background
if (imageData[i]) {
// if data is 2, choose spot color, if 1 choose foreground
const pngColor = imageData[i] == 1 ? color : spotcolor;
p.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale, pngColor);
const pngColor = imageData[i] == 1 ? color : spotcolor
p.fillRect(col * opts.scale, row * opts.scale, opts.scale, opts.scale, pngColor)
}
}
return `data:image/png;base64,${p.getBase64()}`;
return `data:image/png;base64,${p.getBase64()}`
}
exports.toDataUrl = toDataUrl;
exports.toDataUrl = toDataUrl
Object.defineProperty(exports, '__esModule', { value: true });
})));
Object.defineProperty(exports, '__esModule', { value: true })
})

View File

@ -4,11 +4,7 @@ import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Components', module)
.addDecorator(FrameDecorator)

View File

@ -9,7 +9,6 @@ export type SortRow<T> = T & Fixed
export const buildOrderFieldFrom = (attr: string) => `${attr}Order`
const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => {
const order = orderProp ? buildOrderFieldFrom(orderBy) : orderBy
@ -24,7 +23,7 @@ const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => {
}
// eslint-disable-next-line
export const stableSort = <SortRow>(array: Array<SortRow>, cmp: any, fixed: boolean): Array<SortRow> => {
export const stableSort = <SortRow>(array: Array<SortRow>, cmp: any, fixed: boolean): Array<SortRow> => {
const fixedElems: Array<SortRow> = fixed ? array.filter((elem: any) => elem.fixed) : []
const data: Array<SortRow> = fixed ? array.filter((elem: any) => !elem[FIXED]) : array
const stabilizedThis = data.map((el, index) => [el, index])
@ -45,5 +44,6 @@ export const stableSort = <SortRow>(array: Array<SortRow>, cmp: any, fixed: bool
export type Order = 'asc' | 'desc'
export const getSorting = (order: Order, orderBy: string, orderProp: boolean) =>
(order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy, orderProp) : (a: any, b: any) => -desc(a, b, orderBy, orderProp))
export const getSorting = (order: Order, orderBy: string, orderProp: boolean) => (order === 'desc'
? (a: any, b: any) => desc(a, b, orderBy, orderProp)
: (a: any, b: any) => -desc(a, b, orderBy, orderProp))

View File

@ -9,11 +9,7 @@ class Bold extends React.PureComponent<Props> {
render() {
const { children, ...props } = this.props
return (
<b {...props}>
{ children }
</b>
)
return <b {...props}>{children}</b>
}
}

View File

@ -7,8 +7,6 @@ const style = {
borderRight: `solid 1px ${border}`,
}
const Divider = () => (
<div style={style} />
)
const Divider = () => <div style={style} />
export default Divider

View File

@ -5,10 +5,12 @@ import { host } from 'storybook-host'
import Component from './index'
storiesOf('Components', module)
.addDecorator(host({
title: 'Hairline',
align: 'center',
height: 5,
width: '100%',
}))
.addDecorator(
host({
title: 'Hairline',
align: 'center',
height: 5,
width: '100%',
}),
)
.add('Hairline', () => <Component />)

View File

@ -28,7 +28,7 @@ class Paragraph extends React.PureComponent<Props> {
className={cx(styles.paragraph, className, weight, { noMargin }, { dot }, size, color, transform, align)}
{...props}
>
{ children }
{children}
</p>
)
}

View File

@ -18,8 +18,18 @@ const calculateBodyFrom = async (
type: TxServiceType,
) => {
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const contractTransactionHash =
await gnosisSafe.getTransactionHash(to, valueInWei, data, operation, 0, 0, 0, 0, 0, nonce)
const contractTransactionHash = await gnosisSafe.getTransactionHash(
to,
valueInWei,
data,
operation,
0,
0,
0,
0,
0,
nonce,
)
return JSON.stringify({
to: getWeb3().toChecksumAddress(to),

View File

@ -1,8 +1,10 @@
// @flow
import { List } from 'immutable'
const generateSignatureFrom = (account: string) =>
`000000000000000000000000${account.replace('0x', '')}000000000000000000000000000000000000000000000000000000000000000001`
const generateSignatureFrom = (account: string) => `000000000000000000000000${account.replace(
'0x',
'',
)}000000000000000000000000000000000000000000000000000000000000000001`
export const buildSignaturesFrom = (ownersWhoHasSigned: List<string>, sender: string) => {
const signatures = ownersWhoHasSigned.push(sender)

View File

@ -16,4 +16,4 @@ export const shortVersionOf = (address: string, cut: number) => {
const final = 42 - cut
return `${address.substring(0, initial)}...${address.substring(final)}`
}
}

View File

@ -61,7 +61,11 @@ const getNetworkIdFrom = async (web3Provider) => {
export const getProviderInfo: Function = async (): Promise<ProviderProps> => {
if (typeof window.web3 === 'undefined') {
return {
name: '', available: false, loaded: false, account: '', network: 0,
name: '',
available: false,
loaded: false,
account: '',
network: 0,
}
}

View File

@ -11,7 +11,11 @@ export const processProviderResponse = (dispatch: ReduxDispatch<*>, provider: Pr
} = provider
const walletRecord = makeProvider({
name, available, loaded, account, network,
name,
available,
loaded,
account,
network,
})
dispatch(addProvider(walletRecord))

View File

@ -7,7 +7,9 @@ export const PROVIDER_REDUCER_ID = 'providers'
export type State = Provider
export default handleActions({
[ADD_PROVIDER]: (state: State, { payload }: ActionType<typeof addProvider>) =>
makeProvider(payload),
}, makeProvider())
export default handleActions(
{
[ADD_PROVIDER]: (state: State, { payload }: ActionType<typeof addProvider>) => makeProvider(payload),
},
makeProvider(),
)

View File

@ -1,5 +1,7 @@
// @flow
import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import {
combineReducers, createStore, applyMiddleware, compose,
} from 'redux'
import thunk from 'redux-thunk'
import providerReducer, { PROVIDER_REDUCER_ID } from '~/logic/wallets/store/reducer/provider'
import type { ProviderProps } from '~/logic/wallets/store/model/provider'
@ -13,19 +15,19 @@ const providerReducerTests = () => {
const reducers = combineReducers({
[PROVIDER_REDUCER_ID]: providerReducer,
})
const middlewares = [
thunk,
]
const enhancers = [
applyMiddleware(...middlewares),
]
const middlewares = [thunk]
const enhancers = [applyMiddleware(...middlewares)]
store = createStore(reducers, compose(...enhancers))
})
it('reducer should return default Provider record when no Metamask is loaded', () => {
// GIVEN
const emptyResponse: ProviderProps = {
name: '', loaded: false, available: false, account: '', network: 0,
name: '',
loaded: false,
available: false,
account: '',
network: 0,
}
// WHEN
@ -39,7 +41,11 @@ const providerReducerTests = () => {
it('reducer should return avaiable with its default value when is loaded but not available', () => {
// GIVEN
const metamaskLoaded: ProviderProps = {
name: 'METAMASK', loaded: true, available: false, account: '', network: 0,
name: 'METAMASK',
loaded: true,
available: false,
account: '',
network: 0,
}
// WHEN
@ -53,7 +59,11 @@ const providerReducerTests = () => {
it('reducer should return metamask provider when it is loaded and available', () => {
// GIVEN
const metamask: ProviderProps = {
name: 'METAMASK', loaded: true, available: true, account: '', network: 0,
name: 'METAMASK',
loaded: true,
available: true,
account: '',
network: 0,
}
// WHEN

View File

@ -16,4 +16,3 @@ const structuredSelector: Selector<GlobalState, any, any> = createStructuredSele
})
export default structuredSelector

View File

@ -8,18 +8,13 @@ import { getProviderInfo } from '~/logic/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
const store = new Store({
safeAddress: '',
safeTx: '',
})
storiesOf('Routes /open', module)
.addDecorator(FrameDecorator)
.add('Open safe with all props set', () => {
@ -42,7 +37,19 @@ storiesOf('Routes /open', module)
store.set({
safeAddress: '0x03db1a8b26d08df23337e9276a36b474510f0025',
// eslint-disable-next-line
safeTx: {"transactionHash":"0x4603de1ab6a92b4ee1fd67189089f5c02f5df5d135bf85af84083c27808c0544","transactionIndex":0,"blockHash":"0x593ce7d85fef2a492e8f759f485c8b66ff803773e77182c68dd45c439b7a956d","blockNumber":19,"gasUsed":3034193,"cumulativeGasUsed":3034193,"contractAddress":"0xfddda33736fb95b587cbfecc1ff4a50f717adc00","logs":[],"status":"0x01","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
safeTx: {
transactionHash: '0x4603de1ab6a92b4ee1fd67189089f5c02f5df5d135bf85af84083c27808c0544',
transactionIndex: 0,
blockHash: '0x593ce7d85fef2a492e8f759f485c8b66ff803773e77182c68dd45c439b7a956d',
blockNumber: 19,
gasUsed: 3034193,
cumulativeGasUsed: 3034193,
contractAddress: '0xfddda33736fb95b587cbfecc1ff4a50f717adc00',
logs: [],
status: '0x01',
logsBloom:
'0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
},
})
}

View File

@ -7,7 +7,9 @@ export const getOwnerNameBy = (index: number) => `owner${index}Name`
export const getOwnerAddressBy = (index: number) => `owner${index}Address`
export const getNumOwnersFrom = (values: Object) => {
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Name$/.test(key))
const accounts = Object.keys(values)
.sort()
.filter(key => /^owner\d+Name$/.test(key))
return accounts.length
}

View File

@ -1,12 +1,16 @@
// @flow
export const getAccountsFrom = (values: Object): string[] => {
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Address$/.test(key))
const accounts = Object.keys(values)
.sort()
.filter(key => /^owner\d+Address$/.test(key))
return accounts.map(account => values[account]).slice(0, values.owners)
}
export const getNamesFrom = (values: Object): string[] => {
const accounts = Object.keys(values).sort().filter(key => /^owner\d+Name$/.test(key))
const accounts = Object.keys(values)
.sort()
.filter(key => /^owner\d+Name$/.test(key))
return accounts.map(account => values[account]).slice(0, values.owners)
}

View File

@ -5,11 +5,7 @@ import styles from '~/components/layout/PageFrame/index.scss'
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
import Component from './component'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Routes /opening', module)
.addDecorator(FrameDecorator)
@ -20,8 +16,4 @@ storiesOf('Routes /opening', module)
network={ETHEREUM_NETWORK.RINKEBY}
/>
))
.add('Load this view without a tx', () => (
<Component
network={ETHEREUM_NETWORK.UNKNOWN}
/>
))
.add('Load this view without a tx', () => <Component network={ETHEREUM_NETWORK.UNKNOWN} />)

View File

@ -5,30 +5,13 @@ import { List } from 'immutable'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Routes /safe:address', module)
.addDecorator(FrameDecorator)
.add('Safe undefined being connected', () => (
<Component
userAddress="foo"
safe={undefined}
provider="METAMASK"
activeTokens={List([])}
fetchBalance={() => {}}
/>
<Component userAddress="foo" safe={undefined} provider="METAMASK" activeTokens={List([])} fetchBalance={() => {}} />
))
.add('Safe undefined NOT connected', () => (
<Component
userAddress="foo"
safe={undefined}
provider=""
activeTokens={List([])}
fetchBalance={() => {}}
/>
<Component userAddress="foo" safe={undefined} provider="" activeTokens={List([])} fetchBalance={() => {}} />
))

View File

@ -4,14 +4,8 @@ import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './index.jsx'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('NoRights', () => (
<Component />
))
.add('NoRights', () => <Component />)

View File

@ -7,8 +7,7 @@ import { safeTransactionsSelector } from '~/routes/safe/store/selectors/index'
const pendingTransactionsSelector = createSelector(
safeTransactionsSelector,
(transactions: List<Transaction>) =>
transactions.findEntry((tx: Transaction) => tx.get('isExecuted')),
(transactions: List<Transaction>) => transactions.findEntry((tx: Transaction) => tx.get('isExecuted')),
)
export type SelectorProps = {

View File

@ -14,15 +14,15 @@ export const buildOwnersFrom = (names: Array<string>, addresses: Array<string>)
const addSafe = createAction(
ADD_SAFE,
(
name: string, address: string, threshold: number,
ownersName: string[], ownersAddress: string[],
): SafeProps => {
(name: string, address: string, threshold: number, ownersName: string[], ownersAddress: string[]): SafeProps => {
const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
return ({
address, name, threshold, owners,
})
return {
address,
name,
threshold,
owners,
}
},
)

View File

@ -9,12 +9,10 @@ import { getOwners, getSafeName } from '~/utils/localStorage'
import { getGnosisSafeContract } from '~/logic/contracts/safeContracts'
import { getWeb3 } from '~/logic/wallets/getWeb3'
const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>) => (
safeOwners.map((ownerAddress: string) => {
const ownerName = storedOwners.get(ownerAddress.toLowerCase()) || 'UNKNOWN'
return makeOwner({ name: ownerName, address: ownerAddress })
})
)
const buildOwnersFrom = (safeOwners: string[], storedOwners: Map<string, string>) => safeOwners.map((ownerAddress: string) => {
const ownerName = storedOwners.get(ownerAddress.toLowerCase()) || 'UNKNOWN'
return makeOwner({ name: ownerName, address: ownerAddress })
})
export const buildSafe = async (safeAddress: string, safeName: string) => {
const web3 = getWeb3()
@ -42,7 +40,7 @@ export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalSta
return dispatch(updateSafe(safeRecord))
} catch (err) {
// eslint-disable-next-line
console.error("Error while updating safe information: ", err)
console.error('Error while updating safe information: ', err)
return Promise.resolve()
}

View File

@ -8,7 +8,9 @@ export const TRANSACTIONS_REDUCER_ID = 'transactions'
export type State = Map<string, List<Transaction>>
export default handleActions<State, *>({
[ADD_TRANSACTIONS]: (state: State, action: ActionType<typeof addTransactions>): State =>
action.payload,
}, Map())
export default handleActions<State, *>(
{
[ADD_TRANSACTIONS]: (state: State, action: ActionType<typeof addTransactions>): State => action.payload,
},
Map(),
)

View File

@ -58,7 +58,7 @@ export const confirmationsTransactionSelector: Selector<GlobalState, Transaction
return 0
}
return confirmations.filter(((confirmation: Confirmation) => confirmation.get('type') === 'confirmation')).count()
return confirmations.filter((confirmation: Confirmation) => confirmation.get('type') === 'confirmation').count()
},
)

View File

@ -45,14 +45,14 @@ export class SafeFactory {
.withOwner(['Adol Metamask'], [ownerAddress])
.get()
static twoOwnersSafe = (firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023', secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024') => aSafe()
static twoOwnersSafe = (
firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023',
secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024',
) => aSafe()
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
.withName('Adol & Tobias Safe')
.withConfirmations(2)
.withOwner(
['Adol Metamask', 'Tobias Metamask'],
[firstOwner, secondOwner],
)
.withOwner(['Adol Metamask', 'Tobias Metamask'], [firstOwner, secondOwner])
.get()
}

View File

@ -1,5 +1,7 @@
// @flow
import { combineReducers, createStore, applyMiddleware, compose } from 'redux'
import {
combineReducers, createStore, applyMiddleware, compose,
} from 'redux'
import thunk from 'redux-thunk'
import safeReducer, { SAFE_REDUCER_ID } from '~/routes/safe/store/reducer/safe'
import addSafe from '~/routes/safe/store/actions/addSafe'
@ -11,12 +13,8 @@ const aStore = (initState) => {
const reducers = combineReducers({
[SAFE_REDUCER_ID]: safeReducer,
})
const middlewares = [
thunk,
]
const enhancers = [
applyMiddleware(...middlewares),
]
const middlewares = [thunk]
const enhancers = [applyMiddleware(...middlewares)]
return createStore(reducers, initState, compose(...enhancers))
}
@ -42,13 +40,15 @@ const providerReducerTests = () => {
// GIVEN in beforeEach method
// WHEN
store.dispatch(addSafe(
formValues[SafeFields.FIELD_NAME],
formValues.address,
formValues[SafeFields.FIELD_CONFIRMATIONS],
getNamesFrom(formValues),
getAccountsFrom(formValues),
))
store.dispatch(
addSafe(
formValues[SafeFields.FIELD_NAME],
formValues.address,
formValues[SafeFields.FIELD_CONFIRMATIONS],
getNamesFrom(formValues),
getAccountsFrom(formValues),
),
)
const safes = store.getState()[SAFE_REDUCER_ID]
// THEN

View File

@ -19,9 +19,7 @@ import { getGnosisSafeContract } from '~/wallets/safeContracts'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
*/
describe('React DOM TESTS > Change threshold', () => {
it('should update the threshold directly if safe has 1 threshold', async () => {
})
it('should update the threshold directly if safe has 1 threshold', async () => {})
})
/*

View File

@ -6,24 +6,13 @@ import styles from '~/components/layout/PageFrame/index.scss'
import { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Routes /safes', module)
.addDecorator(FrameDecorator)
.add('Safe List whithout safes and connected', () => (
<Component provider="METAMASK" safes={List([])} />
))
.add('Safe List whithout safes and NOT connected', () => (
<Component provider="" safes={List([])} />
))
.add('Safe List whithout safes and connected', () => <Component provider="METAMASK" safes={List([])} />)
.add('Safe List whithout safes and NOT connected', () => <Component provider="" safes={List([])} />)
.add('Safe List whith 2 safes', () => {
const safes = List([SafeFactory.oneOwnerSafe(), SafeFactory.twoOwnersSafe()])
return (
<Component provider="METAMASK" safes={safes} />
)
return <Component provider="METAMASK" safes={safes} />
})

View File

@ -17,7 +17,7 @@ const safesListSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
export const safesByOwnerSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
userAccountSelector,
safesListSelector,
(userAddress: string, safes: List<Safe>): List<Safe> =>
safes.filter((safe: Safe) =>
safe.owners.filter((owner: Owner) => sameAddress(owner.get('address'), userAddress)).count() > 0),
(userAddress: string, safes: List<Safe>): List<Safe> => safes.filter(
(safe: Safe) => safe.owners.filter((owner: Owner) => sameAddress(owner.get('address'), userAddress)).count() > 0,
),
)

View File

@ -5,39 +5,19 @@ import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
storiesOf('Routes /welcome', module)
.addDecorator(FrameDecorator)
.add('Welcome with Metamask connected', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'METAMASK')
return (
<Component
provider={provider}
fetchProvider={() => { }}
/>
)
return <Component provider={provider} fetchProvider={() => {}} />
})
.add('Welcome with unknown wallet', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'UNKNOWN')
return (
<Component
provider={provider}
fetchProvider={() => { }}
/>
)
return <Component provider={provider} fetchProvider={() => {}} />
})
.add('Welcome without wallet connected', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], '')
return (
<Component
provider={provider}
fetchProvider={() => { }}
/>
)
return <Component provider={provider} fetchProvider={() => {}} />
})

View File

@ -46,8 +46,7 @@ export const checkMinedTx = (Transaction: React$Component<any, any>, name: strin
expect(hashParagraph).toContain(EMPTY_DATA)
}
export const getListItemsFrom = (Transaction: React$Component<any, any>) =>
TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
export const getListItemsFrom = (Transaction: React$Component<any, any>) => TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
export const expand = async (Transaction: React$Component<any, any>) => {
const listItems = getListItemsFrom(Transaction)
@ -93,14 +92,12 @@ export const refreshTransactions = async (store: Store<GlobalState>, safeAddress
await sleep(1500)
}
const createDom = (store: Store): React$Component<{}> => (
TestUtils.renderIntoDocument((
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRoutes />
</ConnectedRouter>
</Provider>
))
const createDom = (store: Store): React$Component<{}> => TestUtils.renderIntoDocument(
<Provider store={store}>
<ConnectedRouter history={history}>
<AppRoutes />
</ConnectedRouter>
</Provider>,
)
export const travelToSafe = (store: Store, address: string): React$Component<{}> => {

View File

@ -1,7 +1,13 @@
// @flow
import { makeSafe, type Safe } from '~/routes/safe/store/model/safe'
import addSafe, { buildOwnersFrom } from '~/routes/safe/store/actions/addSafe'
import { FIELD_NAME, FIELD_CONFIRMATIONS, FIELD_OWNERS, getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
import {
FIELD_NAME,
FIELD_CONFIRMATIONS,
FIELD_OWNERS,
getOwnerNameBy,
getOwnerAddressBy,
} from '~/routes/open/components/fields'
import { getWeb3, getProviderInfo } from '~/logic/wallets/getWeb3'
import { createSafe, type OpenState } from '~/routes/open/container/Open'
import { type GlobalState } from '~/store/index'
@ -51,14 +57,14 @@ export class SafeFactory {
.withOwner(['Adol Metamask'], [ownerAddress])
.get()
static twoOwnersSafe = (firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023', secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024') => aSafe()
static twoOwnersSafe = (
firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023',
secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024',
) => aSafe()
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
.withName('Adol & Tobias Safe')
.withConfirmations(2)
.withOwner(
['Adol Metamask', 'Tobias Metamask'],
[firstOwner, secondOwner],
)
.withOwner(['Adol Metamask', 'Tobias Metamask'], [firstOwner, secondOwner])
.get()
}

View File

@ -20,14 +20,12 @@ const fillOpenSafeForm = async (localStore: Store<GlobalState>) => {
const walletRecord = makeProvider(provider)
localStore.dispatch(addProvider(walletRecord))
return (
TestUtils.renderIntoDocument((
<Provider store={localStore}>
<ConnectedRouter history={history}>
<Open />
</ConnectedRouter>
</Provider>
))
return TestUtils.renderIntoDocument(
<Provider store={localStore}>
<ConnectedRouter history={history}>
<Open />
</ConnectedRouter>
</Provider>,
)
}
@ -59,7 +57,7 @@ const deploySafe = async (safe: React$Component<{}>, threshold: number, numOwner
expect(ownerInputs.length).toBe(numOwners * 2)
for (let i = addedUpfront; i < numOwners; i += 1) {
const nameIndex = i * 2
const addressIndex = (i * 2) + 1
const addressIndex = i * 2 + 1
const ownerName = ownerInputs[nameIndex]
const account = ownerInputs[addressIndex]
@ -85,11 +83,7 @@ const deploySafe = async (safe: React$Component<{}>, threshold: number, numOwner
return whenSafeDeployed()
}
const aDeployedSafe = async (
specificStore: Store<GlobalState>,
threshold?: number = 1,
numOwners?: number = 1,
) => {
const aDeployedSafe = async (specificStore: Store<GlobalState>, threshold?: number = 1, numOwners?: number = 1) => {
const safe: React$Component<{}> = await fillOpenSafeForm(specificStore)
const safeAddress = await deploySafe(safe, threshold, numOwners)

View File

@ -18,14 +18,12 @@ const travelToLoadRoute = async (localStore: Store<GlobalState>) => {
const walletRecord = makeProvider(provider)
localStore.dispatch(addProvider(walletRecord))
return (
TestUtils.renderIntoDocument((
<Provider store={localStore}>
<ConnectedRouter history={history}>
<Load />
</ConnectedRouter>
</Provider>
))
return TestUtils.renderIntoDocument(
<Provider store={localStore}>
<ConnectedRouter history={history}>
<Load />
</ConnectedRouter>
</Provider>,
)
}
@ -53,7 +51,6 @@ describe('DOM > Feature > LOAD a safe', () => {
TestUtils.Simulate.submit(form)
await sleep(400)
const deployedAddress = await whenSafeDeployed()
expect(deployedAddress).toBe(address)
})

View File

@ -2,12 +2,36 @@
import TestUtils from 'react-dom/test-utils'
import { List } from 'immutable'
import Transaction from '~/routes/safe/component/Transactions/Transaction'
import { listTxsClickingOn, LIST_TXS_INDEX, ADD_OWNERS_INDEX, EXPAND_OWNERS_INDEX, EDIT_THRESHOLD_INDEX, refreshTransactions, EXPAND_BALANCE_INDEX } from '~/test/builder/safe.dom.utils'
import {
listTxsClickingOn,
LIST_TXS_INDEX,
ADD_OWNERS_INDEX,
EXPAND_OWNERS_INDEX,
EDIT_THRESHOLD_INDEX,
refreshTransactions,
EXPAND_BALANCE_INDEX,
} from '~/test/builder/safe.dom.utils'
import { renderSafeInDom, type DomSafe } from '~/test/builder/safe.dom.builder'
import { sendMoveFundsForm, checkMinedMoveFundsTx, checkPendingMoveFundsTx } from '~/test/utils/transactions/moveFunds.helper'
import { sendAddOwnerForm, checkMinedAddOwnerTx, checkPendingAddOwnerTx } from '~/test/utils/transactions/addOwner.helper'
import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx } from '~/test/utils/transactions/removeOwner.helper'
import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper'
import {
sendMoveFundsForm,
checkMinedMoveFundsTx,
checkPendingMoveFundsTx,
} from '~/test/utils/transactions/moveFunds.helper'
import {
sendAddOwnerForm,
checkMinedAddOwnerTx,
checkPendingAddOwnerTx,
} from '~/test/utils/transactions/addOwner.helper'
import {
sendRemoveOwnerForm,
checkMinedRemoveOwnerTx,
checkPendingRemoveOwnerTx,
} from '~/test/utils/transactions/removeOwner.helper'
import {
checkMinedThresholdTx,
sendChangeThresholdForm,
checkThresholdOf,
} from '~/test/utils/transactions/threshold.helper'
import { checkBalanceOf } from '~/test/utils/tokenMovements'
import { sleep } from '~/utils/timer'
import { processTransaction } from '~/logic/safe/safeFrontendOperations'
@ -35,7 +59,7 @@ describe('DOM > Feature > SAFE MULTISIG Transactions', () => {
checkMinedMoveFundsTx(transactions[0], 'Send 0.01 ETH to')
checkMinedAddOwnerTx(transactions[1], 'Add Owner Adol Metamask 2')
checkMinedThresholdTx(transactions[2], 'Change Safe\'s threshold')
checkMinedThresholdTx(transactions[2], "Change Safe's threshold")
})
it.only('mines withdraw process correctly all multisig txs in a 2 owner & 2 threshold safe', async () => {

View File

@ -13,7 +13,6 @@ import { safeTransactionsSelector } from '~/routes/safe/store/selectors'
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
import { testTransactionFrom, testSizeOfTransactions } from './utils/historyServiceHelper'
describe('Transactions Suite', () => {
let store: Store
let safeAddress: string
@ -34,12 +33,28 @@ describe('Transactions Suite', () => {
const firstTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[1], 2).encodeABI()
const executor = accounts[0]
const nonce = await gnosisSafe.nonce()
const firstTxHash = await createTransaction(safe, 'Add Owner Second account', safeAddress, '0', nonce, executor, firstTxData)
const firstTxHash = await createTransaction(
safe,
'Add Owner Second account',
safeAddress,
'0',
nonce,
executor,
firstTxData,
)
await store.dispatch(fetchSafe(safe.get('address')))
safe = getSafeFrom(store.getState(), safeAddress)
const secondTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[2], 2).encodeABI()
const secondTxHash = await createTransaction(safe, 'Add Owner Third account', safeAddress, '0', nonce + 100, executor, secondTxData)
const secondTxHash = await createTransaction(
safe,
'Add Owner Third account',
safeAddress,
'0',
nonce + 100,
executor,
secondTxData,
)
await store.dispatch(fetchSafe(safe.get('address')))
safe = getSafeFrom(store.getState(), safeAddress)
@ -56,7 +71,17 @@ describe('Transactions Suite', () => {
hash: firstTxHash,
}),
])
testTransactionFrom(transactions, 0, 'Add Owner Second account', nonce, 0, safeAddress, firstTxData, true, firstTxConfirmations)
testTransactionFrom(
transactions,
0,
'Add Owner Second account',
nonce,
0,
safeAddress,
firstTxData,
true,
firstTxConfirmations,
)
const secondTxConfirmations = List([
makeConfirmation({
@ -65,7 +90,17 @@ describe('Transactions Suite', () => {
hash: secondTxHash,
}),
])
testTransactionFrom(transactions, 1, 'Add Owner Third account', nonce + 100, 0, safeAddress, secondTxData, false, secondTxConfirmations)
testTransactionFrom(
transactions,
1,
'Add Owner Third account',
nonce + 100,
0,
safeAddress,
secondTxData,
false,
secondTxConfirmations,
)
localStorage.clear()
@ -88,7 +123,17 @@ describe('Transactions Suite', () => {
hash: secondTxHash,
}),
])
testTransactionFrom(transactions, 1, 'Unknown', nonce + 100, 0, safeAddress, secondTxData, false, secondTxConfWithoutStorage)
testTransactionFrom(
transactions,
1,
'Unknown',
nonce + 100,
0,
safeAddress,
secondTxData,
false,
secondTxConfWithoutStorage,
)
})
it('returns empty list of trnsactions when safe is not configured', async () => {
@ -130,4 +175,3 @@ describe('Transactions Suite', () => {
*/
})
})

View File

@ -11,15 +11,23 @@ describe('Signatures Blockchain Test', () => {
const sender = 'foZ'
// WHEN
const result = '0x' +
// eslint-disable-next-line
'000000000000000000000000' + 'baR' + '000000000000000000000000000000000000000000000000000000000000000001' +
// eslint-disable-next-line
'000000000000000000000000' + 'baz' + '000000000000000000000000000000000000000000000000000000000000000001' +
// eslint-disable-next-line
'000000000000000000000000' + 'foZ' + '000000000000000000000000000000000000000000000000000000000000000001' +
// eslint-disable-next-line
'000000000000000000000000' + 'foZa' + '000000000000000000000000000000000000000000000000000000000000000001'
const result = '0x'
// eslint-disable-next-line
+ '000000000000000000000000' +
'baR'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line
+ '000000000000000000000000' +
'baz'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line
+ '000000000000000000000000' +
'foZ'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line
+ '000000000000000000000000' +
'foZa'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// THEN
expect(buildSignaturesFrom(List([userA, userB, userC]), sender)).toEqual(result)

View File

@ -46,24 +46,20 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// const store = aNewStore()
// const safeAddress = await aMinedSafe(store)
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// const TokensDom = await travelToTokens(store, safeAddress)
// await sleep(400)
// const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent)
// expect(tokens.length).toBe(2)
// testToken(tokens[0].props.token, 'FTE', false)
// testToken(tokens[1].props.token, 'ETH', true)
// // WHEN
// await clickOnAddToken(TokensDom)
// await fillAddress(TokensDom, secondErc20Token)
// await fillHumanReadableInfo(TokensDom)
// // THEN
// const match: Match = buildMathPropsFrom(safeAddress)
// const tokenList = tokenListSelector(store.getState(), { match })
// expect(tokenList.count()).toBe(3)
// testToken(tokenList.get(0), 'FTE', false)
// testToken(tokenList.get(1), 'ETH', true)
// testToken(tokenList.get(2), 'TKN', true)

View File

@ -16,13 +16,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// let accounts
// let firstErc20Token
// let secondErc20Token
// beforeAll(async () => {
// web3 = getWeb3()
// accounts = await web3.eth.getAccounts()
// firstErc20Token = await getFirstTokenContract(web3, accounts[0])
// secondErc20Token = await getSecondTokenContract(web3, accounts[0])
// // $FlowFixMe
// enhancedFetchModule.enhancedFetch = jest.fn()
// enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
@ -37,13 +35,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// ],
// }))
// })
// it('remove custom ERC 20 tokens', async () => {
// // GIVEN
// const store = aNewStore()
// const safeAddress = await aMinedSafe(store)
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// const values = {
// [TOKEN_ADRESS_PARAM]: secondErc20Token.address,
// [TOKEN_NAME_PARAM]: 'Custom ERC20 Token',
@ -51,12 +47,10 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// [TOKEN_DECIMALS_PARAM]: '10',
// [TOKEN_LOGO_URL_PARAM]: 'https://example.com',
// }
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
// await addTokenFnc(values, customAddTokensFn, safeAddress)
// const TokensDom = travelToTokens(store, safeAddress)
// await sleep(400)
// // WHEN
// const buttons = TestUtils.scryRenderedDOMComponentsWithTag(TokensDom, 'button')
// expect(buttons.length).toBe(2)
@ -64,14 +58,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// expect(removeUserButton.getAttribute('aria-label')).toBe('Delete')
// TestUtils.Simulate.click(removeUserButton)
// await sleep(400)
// const form = TestUtils.findRenderedDOMComponentWithTag(TokensDom, 'form')
// // submit it
// TestUtils.Simulate.submit(form)
// TestUtils.Simulate.submit(form)
// await sleep(400)
// const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent)
// expect(tokens.length).toBe(2)
// testToken(tokens[0].props.token, 'FTE', false)

View File

@ -17,13 +17,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// let accounts
// let firstErc20Token
// let secondErc20Token
// beforeAll(async () => {
// web3 = getWeb3()
// accounts = await web3.eth.getAccounts()
// firstErc20Token = await getFirstTokenContract(web3, accounts[0])
// secondErc20Token = await getSecondTokenContract(web3, accounts[0])
// // $FlowFixMe
// enhancedFetchModule.enhancedFetch = jest.fn()
// enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
@ -38,13 +36,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// ],
// }))
// })
// it('persist added custom ERC 20 tokens as active when reloading the page', async () => {
// // GIVEN
// const store = aNewStore()
// const safeAddress = await aMinedSafe(store)
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// const values = {
// [TOKEN_ADRESS_PARAM]: secondErc20Token.address,
// [TOKEN_NAME_PARAM]: 'Custom ERC20 Token',
@ -52,21 +48,17 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// [TOKEN_DECIMALS_PARAM]: '10',
// [TOKEN_LOGO_URL_PARAM]: 'https://example.com',
// }
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
// await addTokenFnc(values, customAddTokensFn, safeAddress)
// travelToSafe(store, safeAddress)
// // WHEN
// const reloadedStore = aNewStore()
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// travelToSafe(reloadedStore, safeAddress) // reload
// // THEN
// const match: Match = buildMathPropsFrom(safeAddress)
// const activeTokenList = activeTokensSelector(reloadedStore.getState(), { match })
// expect(activeTokenList.count()).toBe(2)
// testToken(activeTokenList.get(0), 'CTS', true)
// testToken(activeTokenList.get(1), 'ETH', true)
// })

View File

@ -19,13 +19,11 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// let accounts
// let firstErc20Token
// let secondErc20Token
// beforeAll(async () => {
// web3 = getWeb3()
// accounts = await web3.eth.getAccounts()
// firstErc20Token = await getFirstTokenContract(web3, accounts[0])
// secondErc20Token = await getSecondTokenContract(web3, accounts[0])
// // $FlowFixMe
// enhancedFetchModule.enhancedFetch = jest.fn()
// enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
@ -40,25 +38,21 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// ],
// }))
// })
// const checkTokensOf = (store: Store, safeAddress: string) => {
// const match: Match = buildMathPropsFrom(safeAddress)
// const activeTokenList = activeTokensSelector(store.getState(), { match })
// expect(activeTokenList.count()).toBe(1)
// testToken(activeTokenList.get(0), 'ETH', true)
// const tokenList = tokenListSelector(store.getState(), { match })
// expect(tokenList.count()).toBe(2)
// testToken(tokenList.get(0), 'FTE', false)
// testToken(tokenList.get(1), 'ETH', true)
// }
// it('removes custom ERC 20 including page reload', async () => {
// // GIVEN
// const store = aNewStore()
// const safeAddress = await aMinedSafe(store)
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// const values = {
// [TOKEN_ADRESS_PARAM]: secondErc20Token.address,
// [TOKEN_NAME_PARAM]: 'Custom ERC20 Token',
@ -66,10 +60,8 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// [TOKEN_DECIMALS_PARAM]: '10',
// [TOKEN_LOGO_URL_PARAM]: 'https://example.com',
// }
// const customAddTokensFn: any = (...args) => store.dispatch(addToken(...args))
// await addTokenFnc(values, customAddTokensFn, safeAddress)
// const token = makeToken({
// address: secondErc20Token.address,
// name: 'Custom ERC20 Token',
@ -82,12 +74,10 @@ describe('DOM > Feature > Add new ERC 20 Tokens', () => {
// const customRemoveTokensFnc: any = (...args) => store.dispatch(removeTokenAction(...args))
// await removeToken(safeAddress, token, customRemoveTokensFnc)
// checkTokensOf(store, safeAddress)
// // WHEN
// const reloadedStore = aNewStore()
// await reloadedStore.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// travelToSafe(reloadedStore, safeAddress) // reload
// // THEN
// checkTokensOf(reloadedStore, safeAddress)
// })

View File

@ -11,21 +11,33 @@ export const testSizeOfSafesWith = (transactions: Map<string, List<Transaction>>
}
export const testSizeOfTransactions = (safeTxs: List<Transaction> | typeof undefined, size: number) => {
if (!safeTxs) { throw new Error() }
if (!safeTxs) {
throw new Error()
}
expect(safeTxs.count()).toBe(size)
expect(safeTxs.get(0)).not.toBe(undefined)
expect(safeTxs.get(0)).not.toBe(null)
}
export const testTransactionFrom = (
safeTxs: List<Transaction> | typeof undefined, pos: number,
name: string, nonce: number, value: number, destination: string,
data: string, isExecuted: boolean, confirmations: List<Confirmation>,
safeTxs: List<Transaction> | typeof undefined,
pos: number,
name: string,
nonce: number,
value: number,
destination: string,
data: string,
isExecuted: boolean,
confirmations: List<Confirmation>,
) => {
if (!safeTxs) { throw new Error() }
if (!safeTxs) {
throw new Error()
}
const tx: Transaction | typeof undefined = safeTxs.get(pos)
if (!tx) { throw new Error() }
if (!tx) {
throw new Error()
}
expect(tx.get('name')).toBe(name)
expect(tx.get('nonce')).toBe(nonce)
expect(tx.get('value')).toBe(value)

View File

@ -19,11 +19,13 @@ export const printOutApprove = async (
// eslint-disable-next-line
console.log(`EO transaction hash ${transactionHash}`)
await Promise.all(owners.map(async (owner, index) => {
const approved = await gnosisSafe.isApproved(transactionHash, owner)
// eslint-disable-next-line
console.log(`EO transaction approved by owner index ${index}: ${approved}`)
}))
await Promise.all(
owners.map(async (owner, index) => {
const approved = await gnosisSafe.isApproved(transactionHash, owner)
// eslint-disable-next-line
console.log(`EO transaction approved by owner index ${index}: ${approved}`)
}),
)
// eslint-disable-next-line
console.log(`EO transaction executed ${await gnosisSafe.isExecuted(transactionHash)}`)
}
@ -35,10 +37,7 @@ type FinsihedTx = {
finishedTransaction: boolean,
}
export const whenExecuted = (
SafeDom: React$Component<any, any>,
ParentComponent: React$ElementType,
): Promise<void> => new Promise((resolve, reject) => {
export const whenExecuted = (SafeDom: React$Component<any, any>, ParentComponent: React$ElementType): Promise<void> => new Promise((resolve, reject) => {
let times = 0
const interval = setInterval(() => {
if (times >= MAX_TIMES_EXECUTED) {
@ -48,20 +47,20 @@ export const whenExecuted = (
// $FlowFixMe
const SafeComponent = TestUtils.findRenderedComponentWithType(SafeDom, ParentComponent)
type GnoStepperType = React$Component<FinsihedTx, any>
// $FlowFixMe
const StepperComponent: GnoStepperType = TestUtils.findRenderedComponentWithType(SafeComponent, GnoStepper)
type GnoStepperType = React$Component<FinsihedTx, any>
// $FlowFixMe
const StepperComponent: GnoStepperType = TestUtils.findRenderedComponentWithType(SafeComponent, GnoStepper)
if (StepperComponent.props.finishedTransaction === true) {
clearInterval(interval)
resolve()
}
times += 1
if (StepperComponent.props.finishedTransaction === true) {
clearInterval(interval)
resolve()
}
times += 1
}, INTERVAL)
})
type MiddleStep = {
activeStep: number
activeStep: number,
}
export const whenOnNext = (
@ -78,13 +77,13 @@ export const whenOnNext = (
// $FlowFixMe
const SafeComponent = TestUtils.findRenderedComponentWithType(SafeDom, ParentComponent)
type StepperType = React$Component<MiddleStep, any>
// $FlowFixMe
const StepperComponent: StepperType = TestUtils.findRenderedComponentWithType(SafeComponent, Stepper)
if (StepperComponent.props.activeStep === position) {
clearInterval(interval)
resolve()
}
times += 1
type StepperType = React$Component<MiddleStep, any>
// $FlowFixMe
const StepperComponent: StepperType = TestUtils.findRenderedComponentWithType(SafeComponent, Stepper)
if (StepperComponent.props.activeStep === position) {
clearInterval(interval)
resolve()
}
times += 1
}, INTERVAL)
})

View File

@ -31,7 +31,7 @@ export const addTknTo = async (safe: string, value: string, tokenContract?: any)
const web3 = getWeb3()
const accounts = await web3.eth.getAccounts()
const myToken = tokenContract || await getFirstTokenContract(web3, accounts[0])
const myToken = tokenContract || (await getFirstTokenContract(web3, accounts[0]))
const nativeValue = toNative(value, 18)
await myToken.transfer(safe, nativeValue.valueOf(), { from: accounts[0], gas: '5000000' })

View File

@ -5,7 +5,6 @@ import { checkMinedTx, checkPendingTx } from '~/test/builder/safe.dom.utils'
import SendToken from '~/routes/safe/component/SendToken'
import { whenExecuted } from '~/test/utils/logTransactions'
export const sendMoveFundsForm = async (
SafeDom: React$Component<any, any>,
expandBalance: React$Component<any, any>,
@ -36,7 +35,6 @@ export const sendMoveFundsForm = async (
TestUtils.Simulate.submit(form)
TestUtils.Simulate.submit(form)
return whenExecuted(SafeDom, SendToken)
}

View File

@ -1,5 +1,7 @@
// @flow
import { xs, sm, md, lg, xl } from '~/theme/variables'
import {
xs, sm, md, lg, xl,
} from '~/theme/variables'
export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'

View File

@ -17,43 +17,46 @@ const xl = '32px'
const xxl = '40px'
const marginButtonImg = '12px'
module.exports = Object.assign({}, {
primary,
secondary,
tertiary,
disabled,
background,
fontColor,
fancy: fancyColor,
warning: warningColor,
connected: connectedColor,
xs,
sm,
md,
lg,
xl,
xxl,
border,
marginButtonImg,
fontSizeHeadingXs: 13,
fontSizeHeadingSm: 18,
fontSizeHeadingMd: 21,
fontSizeHeadingLg: 32,
buttonLargeFontSize: '12px',
lightFont: 300,
regularFont: 400,
bolderFont: 500,
boldFont: 700,
smallFontSize: '11px',
mediumFontSize: '13px',
largeFontSize: '15px',
extraLargeFontSize: '18px',
xxlFontSize: '32px',
screenXs: 480,
screenXsMax: 767,
screenSm: 768,
screenSmMax: 991,
screenMd: 992,
screenMdMax: 1199,
screenLg: 1200,
})
module.exports = Object.assign(
{},
{
primary,
secondary,
tertiary,
disabled,
background,
fontColor,
fancy: fancyColor,
warning: warningColor,
connected: connectedColor,
xs,
sm,
md,
lg,
xl,
xxl,
border,
marginButtonImg,
fontSizeHeadingXs: 13,
fontSizeHeadingSm: 18,
fontSizeHeadingMd: 21,
fontSizeHeadingLg: 32,
buttonLargeFontSize: '12px',
lightFont: 300,
regularFont: 400,
bolderFont: 500,
boldFont: 700,
smallFontSize: '11px',
mediumFontSize: '13px',
largeFontSize: '15px',
extraLargeFontSize: '18px',
xxlFontSize: '32px',
screenXs: 480,
screenXsMax: 767,
screenSm: 768,
screenSmMax: 991,
screenMd: 992,
screenMdMax: 1199,
screenLg: 1200,
},
)