prettier code formatting

This commit is contained in:
Mikhail Mikheev 2019-03-29 17:32:59 +04:00
parent 15cb482c86
commit 95d6316860
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", "start": "node scripts/start.js",
"storybook": "start-storybook -p 6006", "storybook": "start-storybook -p 6006",
"test": "NODE_ENV=test && node scripts/test.js --env=jsdom", "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": [ "pre-commit": [
"precommit" "precommit"
@ -152,6 +153,7 @@
"postcss-mixins": "^6.2.0", "postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^5.0.2", "postcss-simple-vars": "^5.0.2",
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"prettier-eslint-cli": "^4.7.1",
"run-with-testrpc": "^0.3.0", "run-with-testrpc": "^0.3.0",
"storybook-host": "^5.0.3", "storybook-host": "^5.0.3",
"storybook-router": "^0.3.3", "storybook-router": "^0.3.3",

View File

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

View File

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

View File

@ -1,6 +1,12 @@
// @flow // @flow
import { createStructuredSelector } from 'reselect' 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 = { export type SelectorProps = {
provider: string, provider: string,

View File

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

View File

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

View File

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

View File

@ -5,10 +5,12 @@ import { host } from 'storybook-host'
import Component from './index' import Component from './index'
storiesOf('Components', module) storiesOf('Components', module)
.addDecorator(host({ .addDecorator(
title: 'Hairline', host({
align: 'center', title: 'Hairline',
height: 5, align: 'center',
width: '100%', height: 5,
})) width: '100%',
}),
)
.add('Hairline', () => <Component />) .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)} className={cx(styles.paragraph, className, weight, { noMargin }, { dot }, size, color, transform, align)}
{...props} {...props}
> >
{ children } {children}
</p> </p>
) )
} }

View File

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

View File

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

View File

@ -16,4 +16,4 @@ export const shortVersionOf = (address: string, cut: number) => {
const final = 42 - cut const final = 42 - cut
return `${address.substring(0, initial)}...${address.substring(final)}` 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> => { export const getProviderInfo: Function = async (): Promise<ProviderProps> => {
if (typeof window.web3 === 'undefined') { if (typeof window.web3 === 'undefined') {
return { 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 } = provider
const walletRecord = makeProvider({ const walletRecord = makeProvider({
name, available, loaded, account, network, name,
available,
loaded,
account,
network,
}) })
dispatch(addProvider(walletRecord)) dispatch(addProvider(walletRecord))

View File

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

View File

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

View File

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

View File

@ -8,18 +8,13 @@ import { getProviderInfo } from '~/logic/wallets/getWeb3'
import { sleep } from '~/utils/timer' import { sleep } from '~/utils/timer'
import Component from './Layout' import Component from './Layout'
const FrameDecorator = story => ( const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
<div className={styles.frame}>
{ story() }
</div>
)
const store = new Store({ const store = new Store({
safeAddress: '', safeAddress: '',
safeTx: '', safeTx: '',
}) })
storiesOf('Routes /open', module) storiesOf('Routes /open', module)
.addDecorator(FrameDecorator) .addDecorator(FrameDecorator)
.add('Open safe with all props set', () => { .add('Open safe with all props set', () => {
@ -42,7 +37,19 @@ storiesOf('Routes /open', module)
store.set({ store.set({
safeAddress: '0x03db1a8b26d08df23337e9276a36b474510f0025', safeAddress: '0x03db1a8b26d08df23337e9276a36b474510f0025',
// eslint-disable-next-line // 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 getOwnerAddressBy = (index: number) => `owner${index}Address`
export const getNumOwnersFrom = (values: Object) => { 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 return accounts.length
} }

View File

@ -1,12 +1,16 @@
// @flow // @flow
export const getAccountsFrom = (values: Object): string[] => { 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) return accounts.map(account => values[account]).slice(0, values.owners)
} }
export const getNamesFrom = (values: Object): string[] => { 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) 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 { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
import Component from './component' import Component from './component'
const FrameDecorator = story => ( const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
<div className={styles.frame}>
{ story() }
</div>
)
storiesOf('Routes /opening', module) storiesOf('Routes /opening', module)
.addDecorator(FrameDecorator) .addDecorator(FrameDecorator)
@ -20,8 +16,4 @@ storiesOf('Routes /opening', module)
network={ETHEREUM_NETWORK.RINKEBY} network={ETHEREUM_NETWORK.RINKEBY}
/> />
)) ))
.add('Load this view without a tx', () => ( .add('Load this view without a tx', () => <Component network={ETHEREUM_NETWORK.UNKNOWN} />)
<Component
network={ETHEREUM_NETWORK.UNKNOWN}
/>
))

View File

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

View File

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

View File

@ -14,15 +14,15 @@ export const buildOwnersFrom = (names: Array<string>, addresses: Array<string>)
const addSafe = createAction( const addSafe = createAction(
ADD_SAFE, 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) const owners: List<Owner> = buildOwnersFrom(ownersName, ownersAddress)
return ({ return {
address, name, threshold, owners, address,
}) name,
threshold,
owners,
}
}, },
) )

View File

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

View File

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

View File

@ -58,7 +58,7 @@ export const confirmationsTransactionSelector: Selector<GlobalState, Transaction
return 0 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]) .withOwner(['Adol Metamask'], [ownerAddress])
.get() .get()
static twoOwnersSafe = (firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023', secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024') => aSafe() static twoOwnersSafe = (
firstOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0023',
secondOwner: string = '0x03db1a8b26d08df23337e9276a36b474510f0024',
) => aSafe()
.withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026') .withAddress('0x03db1a8b26d08df23337e9276a36b474510f0026')
.withName('Adol & Tobias Safe') .withName('Adol & Tobias Safe')
.withConfirmations(2) .withConfirmations(2)
.withOwner( .withOwner(['Adol Metamask', 'Tobias Metamask'], [firstOwner, secondOwner])
['Adol Metamask', 'Tobias Metamask'],
[firstOwner, secondOwner],
)
.get() .get()
} }

View File

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

View File

@ -19,9 +19,7 @@ import { getGnosisSafeContract } from '~/wallets/safeContracts'
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
*/ */
describe('React DOM TESTS > Change threshold', () => { 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 { SafeFactory } from '~/routes/safe/store/test/builder/safe.builder'
import Component from './Layout' 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) storiesOf('Routes /safes', module)
.addDecorator(FrameDecorator) .addDecorator(FrameDecorator)
.add('Safe List whithout safes and connected', () => ( .add('Safe List whithout safes and connected', () => <Component provider="METAMASK" safes={List([])} />)
<Component provider="METAMASK" safes={List([])} /> .add('Safe List whithout safes and NOT connected', () => <Component provider="" safes={List([])} />)
))
.add('Safe List whithout safes and NOT connected', () => (
<Component provider="" safes={List([])} />
))
.add('Safe List whith 2 safes', () => { .add('Safe List whith 2 safes', () => {
const safes = List([SafeFactory.oneOwnerSafe(), SafeFactory.twoOwnersSafe()]) const safes = List([SafeFactory.oneOwnerSafe(), SafeFactory.twoOwnersSafe()])
return ( return <Component provider="METAMASK" safes={safes} />
<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( export const safesByOwnerSelector: Selector<GlobalState, {}, List<Safe>> = createSelector(
userAccountSelector, userAccountSelector,
safesListSelector, safesListSelector,
(userAddress: string, safes: List<Safe>): List<Safe> => (userAddress: string, safes: List<Safe>): List<Safe> => safes.filter(
safes.filter((safe: Safe) => (safe: Safe) => safe.owners.filter((owner: Owner) => sameAddress(owner.get('address'), userAddress)).count() > 0,
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 styles from '~/components/layout/PageFrame/index.scss'
import Component from './Layout' import Component from './Layout'
const FrameDecorator = story => ( const FrameDecorator = story => <div className={styles.frame}>{story()}</div>
<div className={styles.frame}>
{ story() }
</div>
)
storiesOf('Routes /welcome', module) storiesOf('Routes /welcome', module)
.addDecorator(FrameDecorator) .addDecorator(FrameDecorator)
.add('Welcome with Metamask connected', () => { .add('Welcome with Metamask connected', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'METAMASK') const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'METAMASK')
return ( return <Component provider={provider} fetchProvider={() => {}} />
<Component
provider={provider}
fetchProvider={() => { }}
/>
)
}) })
.add('Welcome with unknown wallet', () => { .add('Welcome with unknown wallet', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'UNKNOWN') const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'UNKNOWN')
return ( return <Component provider={provider} fetchProvider={() => {}} />
<Component
provider={provider}
fetchProvider={() => { }}
/>
)
}) })
.add('Welcome without wallet connected', () => { .add('Welcome without wallet connected', () => {
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], '') const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], '')
return ( return <Component provider={provider} fetchProvider={() => {}} />
<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) expect(hashParagraph).toContain(EMPTY_DATA)
} }
export const getListItemsFrom = (Transaction: React$Component<any, any>) => export const getListItemsFrom = (Transaction: React$Component<any, any>) => TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
TestUtils.scryRenderedComponentsWithType(Transaction, ListItemText)
export const expand = async (Transaction: React$Component<any, any>) => { export const expand = async (Transaction: React$Component<any, any>) => {
const listItems = getListItemsFrom(Transaction) const listItems = getListItemsFrom(Transaction)
@ -93,14 +92,12 @@ export const refreshTransactions = async (store: Store<GlobalState>, safeAddress
await sleep(1500) await sleep(1500)
} }
const createDom = (store: Store): React$Component<{}> => ( const createDom = (store: Store): React$Component<{}> => TestUtils.renderIntoDocument(
TestUtils.renderIntoDocument(( <Provider store={store}>
<Provider store={store}> <ConnectedRouter history={history}>
<ConnectedRouter history={history}> <AppRoutes />
<AppRoutes /> </ConnectedRouter>
</ConnectedRouter> </Provider>,
</Provider>
))
) )
export const travelToSafe = (store: Store, address: string): React$Component<{}> => { export const travelToSafe = (store: Store, address: string): React$Component<{}> => {

View File

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

View File

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

View File

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

View File

@ -2,12 +2,36 @@
import TestUtils from 'react-dom/test-utils' import TestUtils from 'react-dom/test-utils'
import { List } from 'immutable' import { List } from 'immutable'
import Transaction from '~/routes/safe/component/Transactions/Transaction' 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 { renderSafeInDom, type DomSafe } from '~/test/builder/safe.dom.builder'
import { sendMoveFundsForm, checkMinedMoveFundsTx, checkPendingMoveFundsTx } from '~/test/utils/transactions/moveFunds.helper' import {
import { sendAddOwnerForm, checkMinedAddOwnerTx, checkPendingAddOwnerTx } from '~/test/utils/transactions/addOwner.helper' sendMoveFundsForm,
import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx } from '~/test/utils/transactions/removeOwner.helper' checkMinedMoveFundsTx,
import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper' 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 { checkBalanceOf } from '~/test/utils/tokenMovements'
import { sleep } from '~/utils/timer' import { sleep } from '~/utils/timer'
import { processTransaction } from '~/logic/safe/safeFrontendOperations' import { processTransaction } from '~/logic/safe/safeFrontendOperations'
@ -35,7 +59,7 @@ describe('DOM > Feature > SAFE MULTISIG Transactions', () => {
checkMinedMoveFundsTx(transactions[0], 'Send 0.01 ETH to') checkMinedMoveFundsTx(transactions[0], 'Send 0.01 ETH to')
checkMinedAddOwnerTx(transactions[1], 'Add Owner Adol Metamask 2') 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 () => { 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 fetchSafe from '~/routes/safe/store/actions/fetchSafe'
import { testTransactionFrom, testSizeOfTransactions } from './utils/historyServiceHelper' import { testTransactionFrom, testSizeOfTransactions } from './utils/historyServiceHelper'
describe('Transactions Suite', () => { describe('Transactions Suite', () => {
let store: Store let store: Store
let safeAddress: string let safeAddress: string
@ -34,12 +33,28 @@ describe('Transactions Suite', () => {
const firstTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[1], 2).encodeABI() const firstTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[1], 2).encodeABI()
const executor = accounts[0] const executor = accounts[0]
const nonce = await gnosisSafe.nonce() 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'))) await store.dispatch(fetchSafe(safe.get('address')))
safe = getSafeFrom(store.getState(), safeAddress) safe = getSafeFrom(store.getState(), safeAddress)
const secondTxData = gnosisSafe.contract.methods.addOwnerWithThreshold(accounts[2], 2).encodeABI() 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'))) await store.dispatch(fetchSafe(safe.get('address')))
safe = getSafeFrom(store.getState(), safeAddress) safe = getSafeFrom(store.getState(), safeAddress)
@ -56,7 +71,17 @@ describe('Transactions Suite', () => {
hash: firstTxHash, 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([ const secondTxConfirmations = List([
makeConfirmation({ makeConfirmation({
@ -65,7 +90,17 @@ describe('Transactions Suite', () => {
hash: secondTxHash, 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() localStorage.clear()
@ -88,7 +123,17 @@ describe('Transactions Suite', () => {
hash: secondTxHash, 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 () => { 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' const sender = 'foZ'
// WHEN // WHEN
const result = '0x' + const result = '0x'
// eslint-disable-next-line // eslint-disable-next-line
'000000000000000000000000' + 'baR' + '000000000000000000000000000000000000000000000000000000000000000001' + + '000000000000000000000000' +
// eslint-disable-next-line 'baR'
'000000000000000000000000' + 'baz' + '000000000000000000000000000000000000000000000000000000000000000001' + + '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line // eslint-disable-next-line
'000000000000000000000000' + 'foZ' + '000000000000000000000000000000000000000000000000000000000000000001' + + '000000000000000000000000' +
// eslint-disable-next-line 'baz'
'000000000000000000000000' + 'foZa' + '000000000000000000000000000000000000000000000000000000000000000001' + '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line
+ '000000000000000000000000' +
'foZ'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// eslint-disable-next-line
+ '000000000000000000000000' +
'foZa'
+ '000000000000000000000000000000000000000000000000000000000000000001'
// THEN // THEN
expect(buildSignaturesFrom(List([userA, userB, userC]), sender)).toEqual(result) 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 store = aNewStore()
// const safeAddress = await aMinedSafe(store) // const safeAddress = await aMinedSafe(store)
// await store.dispatch(fetchTokensModule.fetchTokens(safeAddress)) // await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
// const TokensDom = await travelToTokens(store, safeAddress) // const TokensDom = await travelToTokens(store, safeAddress)
// await sleep(400) // await sleep(400)
// const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent) // const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent)
// expect(tokens.length).toBe(2) // expect(tokens.length).toBe(2)
// testToken(tokens[0].props.token, 'FTE', false) // testToken(tokens[0].props.token, 'FTE', false)
// testToken(tokens[1].props.token, 'ETH', true) // testToken(tokens[1].props.token, 'ETH', true)
// // WHEN // // WHEN
// await clickOnAddToken(TokensDom) // await clickOnAddToken(TokensDom)
// await fillAddress(TokensDom, secondErc20Token) // await fillAddress(TokensDom, secondErc20Token)
// await fillHumanReadableInfo(TokensDom) // await fillHumanReadableInfo(TokensDom)
// // THEN // // THEN
// const match: Match = buildMathPropsFrom(safeAddress) // const match: Match = buildMathPropsFrom(safeAddress)
// const tokenList = tokenListSelector(store.getState(), { match }) // const tokenList = tokenListSelector(store.getState(), { match })
// expect(tokenList.count()).toBe(3) // expect(tokenList.count()).toBe(3)
// testToken(tokenList.get(0), 'FTE', false) // testToken(tokenList.get(0), 'FTE', false)
// testToken(tokenList.get(1), 'ETH', true) // testToken(tokenList.get(1), 'ETH', true)
// testToken(tokenList.get(2), 'TKN', true) // testToken(tokenList.get(2), 'TKN', true)

View File

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

View File

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

View File

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

View File

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

View File

@ -31,7 +31,7 @@ export const addTknTo = async (safe: string, value: string, tokenContract?: any)
const web3 = getWeb3() const web3 = getWeb3()
const accounts = await web3.eth.getAccounts() 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) const nativeValue = toNative(value, 18)
await myToken.transfer(safe, nativeValue.valueOf(), { from: accounts[0], gas: '5000000' }) 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 SendToken from '~/routes/safe/component/SendToken'
import { whenExecuted } from '~/test/utils/logTransactions' import { whenExecuted } from '~/test/utils/logTransactions'
export const sendMoveFundsForm = async ( export const sendMoveFundsForm = async (
SafeDom: React$Component<any, any>, SafeDom: React$Component<any, any>,
expandBalance: 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)
TestUtils.Simulate.submit(form) TestUtils.Simulate.submit(form)
return whenExecuted(SafeDom, SendToken) return whenExecuted(SafeDom, SendToken)
} }

View File

@ -1,5 +1,7 @@
// @flow // @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' export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'

View File

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