mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
Merge pull request #4116 from MetaMask/test-unit-ganache
Test - Move unit tests to ganache-core
This commit is contained in:
commit
2601aa594e
118
package-lock.json
generated
118
package-lock.json
generated
@ -4369,7 +4369,7 @@
|
||||
"requires": {
|
||||
"file-type": "5.2.0",
|
||||
"is-stream": "1.1.0",
|
||||
"tar-stream": "1.5.6"
|
||||
"tar-stream": "1.6.0"
|
||||
}
|
||||
},
|
||||
"decompress-tarbz2": {
|
||||
@ -5889,25 +5889,26 @@
|
||||
"resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.0.0.tgz",
|
||||
"integrity": "sha512-Ab6170AxlF4DK+HDImh52+AetwHPHstgg8uWtX4im26rqK7u4ziSfvUIUK2+/LK0pi0wbIFb8hZm5jPKAXDmBA==",
|
||||
"requires": {
|
||||
"eth-json-rpc-middleware": "1.5.0",
|
||||
"eth-json-rpc-middleware": "1.6.0",
|
||||
"json-rpc-engine": "3.6.1",
|
||||
"json-rpc-error": "2.0.0",
|
||||
"tape": "4.8.0"
|
||||
}
|
||||
},
|
||||
"eth-json-rpc-middleware": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.5.0.tgz",
|
||||
"integrity": "sha1-FrEFM4aqOAOxJXMqpt4H6t8Ghyk=",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz",
|
||||
"integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==",
|
||||
"requires": {
|
||||
"async": "2.6.0",
|
||||
"eth-query": "2.1.2",
|
||||
"eth-tx-summary": "3.1.2",
|
||||
"eth-tx-summary": "3.2.1",
|
||||
"ethereumjs-block": "1.7.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"ethereumjs-vm": "2.3.2",
|
||||
"fetch-ponyfill": "4.1.0",
|
||||
"json-rpc-engine": "3.6.1",
|
||||
"json-rpc-error": "2.0.0",
|
||||
"json-stable-stringify": "1.0.1",
|
||||
"promise-to-callback": "1.0.0",
|
||||
@ -5915,9 +5916,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereumjs-util": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
|
||||
"integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
|
||||
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
|
||||
"requires": {
|
||||
"bn.js": "4.11.8",
|
||||
"create-hash": "1.1.3",
|
||||
@ -6245,11 +6246,12 @@
|
||||
}
|
||||
},
|
||||
"eth-tx-summary": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.1.2.tgz",
|
||||
"integrity": "sha1-44g2/J+LVvFNdZUvD15XD4j7IiA=",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.1.tgz",
|
||||
"integrity": "sha512-mu8g5tDkQxlFah58ggFhTzolE4OnYTj6j8SVsnGsiWT7WxN722RwnEsk/bco2foy+PLSEF2Mnoiw+wCqKoY72A==",
|
||||
"requires": {
|
||||
"async": "2.6.0",
|
||||
"bn.js": "4.11.8",
|
||||
"clone": "2.1.1",
|
||||
"concat-stream": "1.6.0",
|
||||
"end-of-stream": "1.4.0",
|
||||
@ -6257,12 +6259,46 @@
|
||||
"ethereumjs-block": "1.7.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
|
||||
"ethereumjs-vm": "2.3.2",
|
||||
"ethereumjs-vm": "2.3.5",
|
||||
"through2": "2.0.3",
|
||||
"treeify": "1.1.0",
|
||||
"web3-provider-engine": "13.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereumjs-vm": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz",
|
||||
"integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==",
|
||||
"requires": {
|
||||
"async": "2.6.0",
|
||||
"async-eventemitter": "0.2.4",
|
||||
"ethereum-common": "0.2.0",
|
||||
"ethereumjs-account": "2.0.4",
|
||||
"ethereumjs-block": "1.7.0",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"fake-merkle-patricia-tree": "1.0.1",
|
||||
"functional-red-black-tree": "1.0.1",
|
||||
"merkle-patricia-tree": "2.3.0",
|
||||
"rustbn.js": "0.1.1",
|
||||
"safe-buffer": "5.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereumjs-util": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
|
||||
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
|
||||
"requires": {
|
||||
"bn.js": "4.11.8",
|
||||
"create-hash": "1.1.3",
|
||||
"ethjs-util": "0.1.4",
|
||||
"keccak": "1.4.0",
|
||||
"rlp": "2.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"secp256k1": "3.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"web3-provider-engine": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz",
|
||||
@ -6274,8 +6310,8 @@
|
||||
"eth-sig-util": "1.4.2",
|
||||
"ethereumjs-block": "1.7.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-vm": "2.3.2",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"ethereumjs-vm": "2.3.5",
|
||||
"fetch-ponyfill": "4.1.0",
|
||||
"json-rpc-error": "2.0.0",
|
||||
"json-stable-stringify": "1.0.1",
|
||||
@ -6290,9 +6326,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereumjs-util": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
|
||||
"integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
|
||||
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
|
||||
"requires": {
|
||||
"bn.js": "4.11.8",
|
||||
"create-hash": "1.1.3",
|
||||
@ -7809,6 +7845,11 @@
|
||||
"null-check": "1.0.0"
|
||||
}
|
||||
},
|
||||
"fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"fs-exists-sync": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
|
||||
@ -8890,7 +8931,7 @@
|
||||
"ethereumjs-account": "2.0.4",
|
||||
"ethereumjs-block": "1.2.2",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"ethereumjs-vm": "2.3.3",
|
||||
"ethereumjs-wallet": "0.6.0",
|
||||
"fake-merkle-patricia-tree": "1.0.1",
|
||||
@ -8911,7 +8952,7 @@
|
||||
"tmp": "0.0.31",
|
||||
"web3": "1.0.0-beta.34",
|
||||
"web3-provider-engine": "13.8.0",
|
||||
"websocket": "1.0.25",
|
||||
"websocket": "1.0.26",
|
||||
"yargs": "7.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -9011,9 +9052,9 @@
|
||||
}
|
||||
},
|
||||
"ethereumjs-util": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.1.5.tgz",
|
||||
"integrity": "sha512-xPaSEATYJpMTCGowIt0oMZwFP4R1bxd6QsWgkcDvFL0JtXsr39p32WEcD14RscCjfP41YXZPCVWA4yAg0nrJmw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz",
|
||||
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
|
||||
"requires": {
|
||||
"bn.js": "4.11.6",
|
||||
"create-hash": "1.1.3",
|
||||
@ -9034,7 +9075,7 @@
|
||||
"ethereum-common": "0.2.0",
|
||||
"ethereumjs-account": "2.0.4",
|
||||
"ethereumjs-block": "1.7.1",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"fake-merkle-patricia-tree": "1.0.1",
|
||||
"functional-red-black-tree": "1.0.1",
|
||||
"merkle-patricia-tree": "2.3.0",
|
||||
@ -9055,7 +9096,7 @@
|
||||
"async": "2.6.0",
|
||||
"ethereum-common": "0.2.0",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"merkle-patricia-tree": "2.3.0"
|
||||
}
|
||||
}
|
||||
@ -9193,7 +9234,7 @@
|
||||
"eth-sig-util": "1.4.2",
|
||||
"ethereumjs-block": "1.2.2",
|
||||
"ethereumjs-tx": "1.3.3",
|
||||
"ethereumjs-util": "5.1.5",
|
||||
"ethereumjs-util": "5.2.0",
|
||||
"ethereumjs-vm": "2.3.3",
|
||||
"fetch-ponyfill": "4.1.0",
|
||||
"json-rpc-error": "2.0.0",
|
||||
@ -24264,15 +24305,16 @@
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "1.5.6",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.6.tgz",
|
||||
"integrity": "sha512-tFG9xPbc4Y7CubEwriTss87tdcBQDsw81ejJyCbT4ALNYkNsdPqCfCD6Gkg3OpRkUkq6VO7qpNfwoQAuk/aeNQ==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz",
|
||||
"integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==",
|
||||
"requires": {
|
||||
"bl": "1.2.1",
|
||||
"buffer-alloc": "1.1.0",
|
||||
"end-of-stream": "1.4.0",
|
||||
"fs-constants": "1.0.0",
|
||||
"readable-stream": "2.3.3",
|
||||
"to-buffer": "1.1.0",
|
||||
"to-buffer": "1.1.1",
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
@ -24661,9 +24703,9 @@
|
||||
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
|
||||
},
|
||||
"to-buffer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.0.tgz",
|
||||
"integrity": "sha1-N1vAPtrlw1qPoLP+laHzmF2x3Po="
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
|
||||
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "1.0.3",
|
||||
@ -26343,7 +26385,7 @@
|
||||
"integrity": "sha512-uMYkEP6fga8CyNo8TMoA/7cxi6bL3V8pTvjKQikOi9iYl6/AO5xlfgniyAMElSiq2mmXz3lYa/9VYDMzt/J5aA==",
|
||||
"requires": {
|
||||
"cross-fetch": "2.1.0",
|
||||
"eth-json-rpc-middleware": "1.5.0",
|
||||
"eth-json-rpc-middleware": "1.6.0",
|
||||
"json-rpc-engine": "3.6.1",
|
||||
"json-rpc-error": "2.0.0",
|
||||
"tape": "4.8.0"
|
||||
@ -27043,9 +27085,9 @@
|
||||
}
|
||||
},
|
||||
"websocket": {
|
||||
"version": "1.0.25",
|
||||
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.25.tgz",
|
||||
"integrity": "sha512-M58njvi6ZxVb5k7kpnHh2BvNKuBWiwIYvsToErBzWhvBZYwlEiLcyLrG41T1jRcrY9ettqPYEqduLI7ul54CVQ==",
|
||||
"version": "1.0.26",
|
||||
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.26.tgz",
|
||||
"integrity": "sha512-fjcrYDPIQxpTnqFQ9JjxUQcdvR89MFAOjPBlF+vjOt49w/XW4fJknUoMz/mDIn2eK1AdslVojcaOxOqyZZV8rw==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"nan": "2.8.0",
|
||||
|
@ -217,9 +217,10 @@
|
||||
"eslint-plugin-json": "^1.2.0",
|
||||
"eslint-plugin-mocha": "^5.0.0",
|
||||
"eslint-plugin-react": "^7.4.0",
|
||||
"eth-json-rpc-middleware": "^1.2.7",
|
||||
"eth-json-rpc-middleware": "^1.6.0",
|
||||
"fs-promise": "^2.0.3",
|
||||
"ganache-cli": "^6.1.0",
|
||||
"ganache-core": "^2.1.0",
|
||||
"gifencoder": "^1.1.0",
|
||||
"gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed",
|
||||
"gulp-babel": "^7.0.0",
|
||||
|
@ -1,14 +1,28 @@
|
||||
const JsonRpcEngine = require('json-rpc-engine')
|
||||
const scaffoldMiddleware = require('eth-json-rpc-middleware/scaffold')
|
||||
const TestBlockchain = require('eth-block-tracker/test/util/testBlockMiddleware')
|
||||
const providerAsMiddleware = require('eth-json-rpc-middleware/providerAsMiddleware')
|
||||
const GanacheCore = require('ganache-core')
|
||||
|
||||
module.exports = {
|
||||
createEngineForTestData,
|
||||
providerFromEngine,
|
||||
scaffoldMiddleware,
|
||||
createTestProviderTools,
|
||||
getTestSeed,
|
||||
getTestAccounts,
|
||||
}
|
||||
|
||||
function getTestSeed () {
|
||||
return 'people carpet cluster attract ankle motor ozone mass dove original primary mask'
|
||||
}
|
||||
|
||||
function getTestAccounts () {
|
||||
return [
|
||||
{ address: '0x88bb7F89eB5e5b30D3e15a57C68DBe03C6aCCB21', key: Buffer.from('254A8D551474F35CCC816388B4ED4D20B945C96B7EB857A68064CB9E9FB2C092', 'hex') },
|
||||
{ address: '0x1fe9aAB565Be19629fF4e8541ca2102fb42D7724', key: Buffer.from('6BAB5A4F2A6911AF8EE2BD32C6C05F6643AC48EF6C939CDEAAAE6B1620805A9B', 'hex') },
|
||||
{ address: '0xbda5c89aa6bA1b352194291AD6822C92AbC87c7B', key: Buffer.from('9B11D7F833648F26CE94D544855558D7053ECD396E4F4563968C232C012879B0', 'hex') },
|
||||
]
|
||||
}
|
||||
|
||||
function createEngineForTestData () {
|
||||
return new JsonRpcEngine()
|
||||
@ -21,11 +35,13 @@ function providerFromEngine (engine) {
|
||||
|
||||
function createTestProviderTools (opts = {}) {
|
||||
const engine = createEngineForTestData()
|
||||
const testBlockchain = new TestBlockchain()
|
||||
// handle provided hooks
|
||||
engine.push(scaffoldMiddleware(opts.scaffold || {}))
|
||||
// handle block tracker methods
|
||||
engine.push(testBlockchain.createMiddleware())
|
||||
engine.push(providerAsMiddleware(GanacheCore.provider({
|
||||
mnemonic: getTestSeed(),
|
||||
})))
|
||||
// wrap in standard provider interface
|
||||
const provider = providerFromEngine(engine)
|
||||
return { provider, engine, testBlockchain }
|
||||
return { provider, engine }
|
||||
}
|
||||
|
@ -6,16 +6,15 @@ const ObservableStore = require('obs-store')
|
||||
const sinon = require('sinon')
|
||||
const TransactionController = require('../../app/scripts/controllers/transactions')
|
||||
const TxGasUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
|
||||
const { createTestProviderTools } = require('../stub/provider')
|
||||
const { createTestProviderTools, getTestAccounts } = require('../stub/provider')
|
||||
|
||||
const noop = () => true
|
||||
const currentNetworkId = 42
|
||||
const otherNetworkId = 36
|
||||
const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
|
||||
|
||||
|
||||
describe('Transaction Controller', function () {
|
||||
let txController, provider, providerResultStub, testBlockchain
|
||||
let txController, provider, providerResultStub, query, fromAccount
|
||||
|
||||
beforeEach(function () {
|
||||
providerResultStub = {
|
||||
@ -24,9 +23,9 @@ describe('Transaction Controller', function () {
|
||||
// by default, all accounts are external accounts (not contracts)
|
||||
eth_getCode: '0x',
|
||||
}
|
||||
const providerTools = createTestProviderTools({ scaffold: providerResultStub })
|
||||
provider = providerTools.provider
|
||||
testBlockchain = providerTools.testBlockchain
|
||||
provider = createTestProviderTools({ scaffold: providerResultStub }).provider
|
||||
query = new EthjsQuery(provider)
|
||||
fromAccount = getTestAccounts()[0]
|
||||
|
||||
txController = new TransactionController({
|
||||
provider,
|
||||
@ -34,7 +33,7 @@ describe('Transaction Controller', function () {
|
||||
txHistoryLimit: 10,
|
||||
blockTracker: { getCurrentBlock: noop, on: noop, once: noop },
|
||||
signTransaction: (ethTx) => new Promise((resolve) => {
|
||||
ethTx.sign(privKey)
|
||||
ethTx.sign(fromAccount.key)
|
||||
resolve()
|
||||
}),
|
||||
})
|
||||
@ -298,12 +297,12 @@ describe('Transaction Controller', function () {
|
||||
|
||||
describe('#updateAndApproveTransaction', function () {
|
||||
let txMeta
|
||||
beforeEach(function () {
|
||||
beforeEach(() => {
|
||||
txMeta = {
|
||||
id: 1,
|
||||
status: 'unapproved',
|
||||
txParams: {
|
||||
from: '0xc684832530fcbddae4b4230a47e991ddcec2831d',
|
||||
from: fromAccount.address,
|
||||
to: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||
gasPrice: '0x77359400',
|
||||
gas: '0x7b0d',
|
||||
@ -312,11 +311,12 @@ describe('Transaction Controller', function () {
|
||||
metamaskNetworkId: currentNetworkId,
|
||||
}
|
||||
})
|
||||
it('should update and approve transactions', function () {
|
||||
it('should update and approve transactions', async () => {
|
||||
txController.txStateManager.addTx(txMeta)
|
||||
txController.updateAndApproveTransaction(txMeta)
|
||||
const approvalPromise = txController.updateAndApproveTransaction(txMeta)
|
||||
const tx = txController.txStateManager.getTx(1)
|
||||
assert.equal(tx.status, 'approved')
|
||||
await approvalPromise
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -95,4 +95,4 @@ describe('txUtils', function () {
|
||||
txUtils.validateFrom(txParams)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user