From 4be1015faa64afc4c8b14822a42cc63cef8d043e Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 7 Jun 2020 23:55:14 +0200 Subject: [PATCH 1/5] socket added --- package-lock.json | 403 ++++++++++++++++++++++++++++- package.json | 3 + src/builds/builds.controller.ts | 23 +- src/builds/builds.module.ts | 3 +- src/builds/builds.service.ts | 39 ++- src/builds/dto/build.dto.ts | 80 ++++++ src/events/events.gateway.ts | 29 +++ src/test-runs/test-runs.module.ts | 3 +- src/test-runs/test-runs.service.ts | 11 +- 9 files changed, 563 insertions(+), 31 deletions(-) create mode 100644 src/builds/dto/build.dto.ts create mode 100644 src/events/events.gateway.ts diff --git a/package-lock.json b/package-lock.json index eb03a998..549b6ca7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vrt-backend", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1151,6 +1151,22 @@ "tslib": "1.11.1" } }, + "@nestjs/platform-socket.io": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-7.1.3.tgz", + "integrity": "sha512-pbAnnqhCXGX/65KAlBDeCXemac5OSiFGaghuGnC2B1hFXeHWks77LcM8urhTvu4AoQQRvo4wmbrPFAFb15gLng==", + "requires": { + "socket.io": "2.3.0", + "tslib": "2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, "@nestjs/schematics": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-7.0.0.tgz", @@ -1290,6 +1306,22 @@ "tslib": "1.11.1" } }, + "@nestjs/websockets": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-7.1.3.tgz", + "integrity": "sha512-khwbLqcxDLkUvZkRh3aADRXTfFRdx5OkbyaB+FpnJ9xIZgg5iv5WYOdU0A+8YxbOV0YFER0NOsWNYUveNvuXwQ==", + "requires": { + "iterare": "1.2.0", + "tslib": "2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.0.tgz", + "integrity": "sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g==" + } + } + }, "@nuxtjs/opencollective": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.2.2.tgz", @@ -1414,6 +1446,15 @@ "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==", "dev": true }, + "@types/engine.io": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.4.tgz", + "integrity": "sha512-98rXVukLD6/ozrQ2O80NAlWDGA4INg+tqsEReWJldqyi2fulC9V7Use/n28SWgROXKm6003ycWV4gZHoF8GA6w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1595,6 +1636,16 @@ "@types/mime": "*" } }, + "@types/socket.io": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.8.tgz", + "integrity": "sha512-NIQfh9WwJuJKlgmby4NgwMpoBOmNPCDgaRNPiLYZBtkbHkszK/9R52B5yGkd5a34rbVdAADuo8FhOS/5AZDemw==", + "dev": true, + "requires": { + "@types/engine.io": "*", + "@types/node": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -2027,6 +2078,11 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, "ajv": { "version": "6.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", @@ -2165,6 +2221,11 @@ "es-abstract": "^1.17.0-next.1" } }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -2236,6 +2297,11 @@ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2437,6 +2503,11 @@ "babel-preset-current-node-syntax": "^0.1.2" } }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2497,12 +2568,22 @@ } } }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, "base64-js": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", "dev": true }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -2517,6 +2598,14 @@ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -2539,6 +2628,11 @@ "file-uri-to-path": "1.0.0" } }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2825,6 +2919,11 @@ "unset-value": "^1.0.0" } }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3121,11 +3220,20 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, "concat-map": { "version": "0.0.1", @@ -3733,6 +3841,92 @@ "once": "^1.4.0" } }, + "engine.io": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", + "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "engine.io-client": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz", + "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "enhanced-resolve": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", @@ -5039,6 +5233,26 @@ "ansi-regex": "^2.0.0" } }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -5286,6 +5500,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -8089,6 +8308,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -8448,6 +8672,22 @@ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "dev": true }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -9671,6 +9911,145 @@ } } }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", + "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -10444,6 +10823,11 @@ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "dev": true }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -12000,8 +12384,7 @@ "ws": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==", - "dev": true + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" }, "xml-name-validator": { "version": "3.0.0", @@ -12015,6 +12398,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -12097,6 +12485,11 @@ "decamelize": "^1.2.0" } }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 2f4bc607..085d67a5 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,9 @@ "@nestjs/jwt": "^7.0.0", "@nestjs/passport": "^7.0.0", "@nestjs/platform-express": "^7.0.0", + "@nestjs/platform-socket.io": "^7.1.3", "@nestjs/swagger": "^4.5.1", + "@nestjs/websockets": "^7.1.3", "@prisma/client": "^2.0.0-beta.6", "bcryptjs": "^2.4.3", "class-transformer": "^0.2.3", @@ -59,6 +61,7 @@ "@types/passport-local": "^1.0.33", "@types/pixelmatch": "^5.1.0", "@types/pngjs": "^3.4.2", + "@types/socket.io": "^2.1.8", "@types/supertest": "^2.0.8", "@types/uuid-apikey": "^1.4.0", "@typescript-eslint/eslint-plugin": "^2.23.0", diff --git a/src/builds/builds.controller.ts b/src/builds/builds.controller.ts index e52c63ee..75e85ea9 100644 --- a/src/builds/builds.controller.ts +++ b/src/builds/builds.controller.ts @@ -1,31 +1,23 @@ -import { - Controller, - Get, - UseGuards, - Post, - Body, - Param, - ParseUUIDPipe, - Delete, - Query, -} from '@nestjs/common'; +import { Controller, Get, UseGuards, Post, Body, Param, ParseUUIDPipe, Delete, Query } from '@nestjs/common'; import { BuildsService } from './builds.service'; import { JwtAuthGuard } from '../auth/guards/auth.guard'; -import { ApiBearerAuth, ApiTags, ApiParam, ApiSecurity, ApiQuery } from '@nestjs/swagger'; +import { ApiBearerAuth, ApiTags, ApiParam, ApiSecurity, ApiQuery, ApiResponse } from '@nestjs/swagger'; import { CreateBuildDto } from './dto/build-create.dto'; import { ApiGuard } from '../auth/guards/api.guard'; import { Build } from '@prisma/client'; +import { BuildDto } from './dto/build.dto'; @Controller('builds') @ApiTags('builds') export class BuildsController { - constructor(private buildsService: BuildsService) { } + constructor(private buildsService: BuildsService) {} @Get() @ApiQuery({ name: 'projectId', required: true }) + @ApiResponse({ type: [BuildDto] }) @ApiBearerAuth() @UseGuards(JwtAuthGuard) - get(@Query('projectId', new ParseUUIDPipe()) projectId: string): Promise { + get(@Query('projectId', new ParseUUIDPipe()) projectId: string): Promise { return this.buildsService.findMany(projectId); } @@ -38,9 +30,10 @@ export class BuildsController { } @Post() + @ApiResponse({ type: BuildDto }) @ApiSecurity('api_key') @UseGuards(ApiGuard) - create(@Body() createBuildDto: CreateBuildDto): Promise { + create(@Body() createBuildDto: CreateBuildDto): Promise { return this.buildsService.create(createBuildDto); } } diff --git a/src/builds/builds.module.ts b/src/builds/builds.module.ts index 504805bd..b6eaf578 100644 --- a/src/builds/builds.module.ts +++ b/src/builds/builds.module.ts @@ -4,10 +4,11 @@ import { BuildsController } from './builds.controller'; import { UsersModule } from '../users/users.module'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsModule } from '../test-runs/test-runs.module'; +import { EventsGateway } from 'src/events/events.gateway'; @Module({ imports: [UsersModule, TestRunsModule], - providers: [BuildsService, PrismaService], + providers: [BuildsService, PrismaService, EventsGateway], controllers: [BuildsController], exports: [BuildsService], }) diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index d4c4eae1..32d43f5f 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -3,32 +3,57 @@ import { CreateBuildDto } from './dto/build-create.dto'; import { PrismaService } from '../prisma/prisma.service'; import { Build } from '@prisma/client'; import { TestRunsService } from '../test-runs/test-runs.service'; +import { EventsGateway } from 'src/events/events.gateway'; +import { BuildDto } from './dto/build.dto'; @Injectable() export class BuildsService { - constructor(private prismaService: PrismaService, private testRunsService: TestRunsService) {} + constructor( + private prismaService: PrismaService, + private testRunsService: TestRunsService, + private eventsGateway: EventsGateway + ) {} - async findMany(projectId: string): Promise { - return this.prismaService.build.findMany({ + async findOne(projectId: string): Promise { + const build = await this.prismaService.build.findOne({ + where: { id: projectId }, + include: { + testRuns: true, + }, + }); + + return new BuildDto(build); + } + + async findMany(projectId: string): Promise { + const buildList = await this.prismaService.build.findMany({ where: { projectId }, include: { testRuns: true, }, orderBy: { createdAt: 'desc' }, }); + + return buildList.map(build => new BuildDto(build)); } - async create(buildDto: CreateBuildDto): Promise { - return this.prismaService.build.create({ + async create(createBuildDto: CreateBuildDto): Promise { + const build = await this.prismaService.build.create({ data: { - branchName: buildDto.branchName, + branchName: createBuildDto.branchName, project: { connect: { - id: buildDto.projectId, + id: createBuildDto.projectId, }, }, }, + include: { + testRuns: true, + }, }); + const buildDto = new BuildDto(build) + this.eventsGateway.buildCreated(buildDto); + return buildDto; } async remove(id: string): Promise { diff --git a/src/builds/dto/build.dto.ts b/src/builds/dto/build.dto.ts new file mode 100644 index 00000000..57dd2a07 --- /dev/null +++ b/src/builds/dto/build.dto.ts @@ -0,0 +1,80 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Build, TestRun, TestStatus } from '@prisma/client'; + +export class BuildDto { + @ApiProperty() + id: string; + + @ApiProperty() + number: number | null; + + @ApiProperty() + branchName: string | null; + + @ApiProperty() + status: string | null; + + @ApiProperty() + projectId: string; + + @ApiProperty() + updatedAt: Date; + + @ApiProperty() + createdAt: Date; + + @ApiProperty() + userId: string | null; + + @ApiProperty() + passedCount: number; + @ApiProperty() + unresolvedCount: number; + @ApiProperty() + failedCount: number; + + constructor(build: Build & { testRuns: TestRun[] }) { + this.id = build.id; + this.number = build.number; + this.branchName = build.branchName; + this.status = build.status; + this.projectId = build.projectId; + this.updatedAt = build.updatedAt; + this.createdAt = build.createdAt; + + this.passedCount = 0; + this.unresolvedCount = 0; + this.failedCount = 0; + + build.testRuns.forEach(testRun => { + switch (testRun.status) { + case TestStatus.approved: + case TestStatus.ok: { + this.passedCount += 1; + break; + } + case TestStatus.unresolved: + case TestStatus.new: { + this.unresolvedCount += 1; + break; + } + case TestStatus.failed: { + this.failedCount += 1; + break; + } + } + }); + + if (build.testRuns.length === 0) { + this.status = 'new'; + } else { + this.status = 'passed'; + } + if (this.failedCount > 0) { + this.status = 'failed'; + } + if (this.unresolvedCount > 0) { + this.status = 'unresolved'; + } + } +} diff --git a/src/events/events.gateway.ts b/src/events/events.gateway.ts new file mode 100644 index 00000000..f990b2d3 --- /dev/null +++ b/src/events/events.gateway.ts @@ -0,0 +1,29 @@ +import { + SubscribeMessage, + WebSocketGateway, + MessageBody, + ConnectedSocket, + WebSocketServer, + WsResponse, +} from '@nestjs/websockets'; +import { Socket, Server } from 'socket.io'; +import { TestRun } from '@prisma/client'; +import { BuildDto } from 'src/builds/dto/build.dto'; + +@WebSocketGateway(4201) +export class EventsGateway { + @WebSocketServer() + server: Server; + + buildCreated(build: BuildDto) { + this.server.emit('build_created', build); + } + + buildUpdated(build: BuildDto) { + this.server.emit('build_updated', build); + } + + newTestRun(testRun: TestRun) { + this.server.emit('testRun_created', testRun); + } +} diff --git a/src/test-runs/test-runs.module.ts b/src/test-runs/test-runs.module.ts index 453b88b0..0cefc85d 100644 --- a/src/test-runs/test-runs.module.ts +++ b/src/test-runs/test-runs.module.ts @@ -3,10 +3,11 @@ import { TestRunsService } from './test-runs.service'; import { SharedModule } from '../shared/shared.module'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsController } from './test-runs.controller'; +import { EventsGateway } from 'src/events/events.gateway'; @Module({ imports: [SharedModule], - providers: [TestRunsService, PrismaService], + providers: [TestRunsService, PrismaService, EventsGateway], exports: [TestRunsService], controllers: [TestRunsController] }) diff --git a/src/test-runs/test-runs.service.ts b/src/test-runs/test-runs.service.ts index a8639371..d2093408 100644 --- a/src/test-runs/test-runs.service.ts +++ b/src/test-runs/test-runs.service.ts @@ -7,10 +7,15 @@ import { StaticService } from '../shared/static/static.service'; import { PrismaService } from '../prisma/prisma.service'; import { TestRun, TestStatus, TestVariation } from '@prisma/client'; import { DiffResult } from './diffResult'; +import { EventsGateway } from 'src/events/events.gateway'; @Injectable() export class TestRunsService { - constructor(private prismaService: PrismaService, private staticService: StaticService) {} + constructor( + private prismaService: PrismaService, + private staticService: StaticService, + private eventsGateway: EventsGateway + ) {} async findMany(buildId: string): Promise { return this.prismaService.testRun.findMany({ @@ -135,7 +140,9 @@ export class TestRunsService { testVariation.ignoreAreas ); - return this.saveDiffResult(testRun.id, diffResult); + const testRunWithResult = await this.saveDiffResult(testRun.id, diffResult); + this.eventsGateway.newTestRun(testRunWithResult); + return testRunWithResult; } async delete(id: string): Promise { From e8902ec567d811c51c0a56b8219bf3a727e49521 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Tue, 9 Jun 2020 23:35:57 +0200 Subject: [PATCH 2/5] remove not used --- src/events/events.gateway.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/events/events.gateway.ts b/src/events/events.gateway.ts index f990b2d3..79605aa9 100644 --- a/src/events/events.gateway.ts +++ b/src/events/events.gateway.ts @@ -19,10 +19,6 @@ export class EventsGateway { this.server.emit('build_created', build); } - buildUpdated(build: BuildDto) { - this.server.emit('build_updated', build); - } - newTestRun(testRun: TestRun) { this.server.emit('testRun_created', testRun); } From f6e0b34c40058e82f039c93ea65d0b3c5f863448 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Tue, 9 Jun 2020 23:51:40 +0200 Subject: [PATCH 3/5] tests are fixed --- src/builds/builds.module.ts | 2 +- src/builds/builds.service.spec.ts | 5 ++- src/builds/builds.service.ts | 15 ++------- src/events/events.gateway.ts | 13 ++------ src/test-runs/test-runs.module.ts | 2 +- src/test-runs/test-runs.service.spec.ts | 41 +++++++++++++++++++------ src/test-runs/test-runs.service.ts | 2 +- 7 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/builds/builds.module.ts b/src/builds/builds.module.ts index b6eaf578..a45fc86a 100644 --- a/src/builds/builds.module.ts +++ b/src/builds/builds.module.ts @@ -4,7 +4,7 @@ import { BuildsController } from './builds.controller'; import { UsersModule } from '../users/users.module'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsModule } from '../test-runs/test-runs.module'; -import { EventsGateway } from 'src/events/events.gateway'; +import { EventsGateway } from '../events/events.gateway'; @Module({ imports: [UsersModule, TestRunsModule], diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index e1ca7b8f..b8031844 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -2,15 +2,18 @@ import { Test, TestingModule } from '@nestjs/testing'; import { BuildsService } from './builds.service'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsService } from '../test-runs/test-runs.service'; +import { EventsGateway } from '../events/events.gateway'; describe('BuildsService', () => { let service: BuildsService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [BuildsService, + providers: [ + BuildsService, { provide: PrismaService, useValue: {} }, { provide: TestRunsService, useValue: {} }, + { provide: EventsGateway, useValue: {} }, ], }).compile(); diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index 32d43f5f..2b949b4b 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -3,7 +3,7 @@ import { CreateBuildDto } from './dto/build-create.dto'; import { PrismaService } from '../prisma/prisma.service'; import { Build } from '@prisma/client'; import { TestRunsService } from '../test-runs/test-runs.service'; -import { EventsGateway } from 'src/events/events.gateway'; +import { EventsGateway } from '../events/events.gateway'; import { BuildDto } from './dto/build.dto'; @Injectable() @@ -14,17 +14,6 @@ export class BuildsService { private eventsGateway: EventsGateway ) {} - async findOne(projectId: string): Promise { - const build = await this.prismaService.build.findOne({ - where: { id: projectId }, - include: { - testRuns: true, - }, - }); - - return new BuildDto(build); - } - async findMany(projectId: string): Promise { const buildList = await this.prismaService.build.findMany({ where: { projectId }, @@ -51,7 +40,7 @@ export class BuildsService { testRuns: true, }, }); - const buildDto = new BuildDto(build) + const buildDto = new BuildDto(build); this.eventsGateway.buildCreated(buildDto); return buildDto; } diff --git a/src/events/events.gateway.ts b/src/events/events.gateway.ts index 79605aa9..ec279d17 100644 --- a/src/events/events.gateway.ts +++ b/src/events/events.gateway.ts @@ -1,14 +1,7 @@ -import { - SubscribeMessage, - WebSocketGateway, - MessageBody, - ConnectedSocket, - WebSocketServer, - WsResponse, -} from '@nestjs/websockets'; -import { Socket, Server } from 'socket.io'; +import { WebSocketGateway, WebSocketServer } from '@nestjs/websockets'; +import { Server } from 'socket.io'; import { TestRun } from '@prisma/client'; -import { BuildDto } from 'src/builds/dto/build.dto'; +import { BuildDto } from '../builds/dto/build.dto'; @WebSocketGateway(4201) export class EventsGateway { diff --git a/src/test-runs/test-runs.module.ts b/src/test-runs/test-runs.module.ts index 0cefc85d..1d3c5204 100644 --- a/src/test-runs/test-runs.module.ts +++ b/src/test-runs/test-runs.module.ts @@ -3,7 +3,7 @@ import { TestRunsService } from './test-runs.service'; import { SharedModule } from '../shared/shared.module'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsController } from './test-runs.controller'; -import { EventsGateway } from 'src/events/events.gateway'; +import { EventsGateway } from '../events/events.gateway'; @Module({ imports: [SharedModule], diff --git a/src/test-runs/test-runs.service.spec.ts b/src/test-runs/test-runs.service.spec.ts index 6f01c64a..324089d2 100644 --- a/src/test-runs/test-runs.service.spec.ts +++ b/src/test-runs/test-runs.service.spec.ts @@ -4,11 +4,12 @@ import { TestRunsService } from './test-runs.service'; import { PrismaService } from '../prisma/prisma.service'; import { StaticService } from '../shared/static/static.service'; import { PNG } from 'pngjs'; -import { TestStatus, TestRun } from '@prisma/client'; +import { TestStatus } from '@prisma/client'; import Pixelmatch from 'pixelmatch'; -import { CreateTestRequestDto } from 'src/test/dto/create-test-request.dto'; +import { CreateTestRequestDto } from '../test/dto/create-test-request.dto'; import { DiffResult } from './diffResult'; -import { IgnoreAreaDto } from 'src/test/dto/ignore-area.dto'; +import { IgnoreAreaDto } from '../test/dto/ignore-area.dto'; +import { EventsGateway } from '../events/events.gateway'; jest.mock('pixelmatch'); @@ -21,6 +22,7 @@ const initService = async ({ getImageMock = jest.fn(), saveImageMock = jest.fn(), deleteImageMock = jest.fn(), + eventNewTestRunMock = jest.fn(), }) => { const module: TestingModule = await Test.createTestingModule({ providers: [ @@ -45,6 +47,12 @@ const initService = async ({ deleteImage: deleteImageMock, }, }, + { + provide: EventsGateway, + useValue: { + newTestRun: eventNewTestRunMock, + }, + }, ], }).compile(); @@ -159,6 +167,15 @@ describe('TestRunsService', () => { device: 'device', diffTollerancePercent: 1, }; + const testRunWithResult = { + id: 'id', + imageName: 'imageName', + baselineName: 'baselineName', + diffTollerancePercent: 1, + ignoreAreas: '[]', + diffName: 'diffName', + status: TestStatus.unresolved, + }; it('no baseline', async () => { const testRun = { @@ -200,13 +217,14 @@ describe('TestRunsService', () => { .fn() .mockReturnValueOnce(baseline) .mockReturnValueOnce(image); - service = await initService({ testRunCreateMock, saveImageMock, getImageMock }); + const eventNewTestRunMock = jest.fn(); + service = await initService({ testRunCreateMock, saveImageMock, getImageMock, eventNewTestRunMock }); const getDiffMock = jest.fn().mockReturnValueOnce(diffResult); service.getDiff = getDiffMock; - const saveDiffResultMock = jest.fn(); + const saveDiffResultMock = jest.fn().mockResolvedValueOnce(testRunWithResult); service.saveDiffResult = saveDiffResultMock; - await service.create(testVariation, createTestRequestDto); + const result = await service.create(testVariation, createTestRequestDto); expect(saveImageMock).toHaveBeenCalledWith('screenshot', Buffer.from(createTestRequestDto.imageBase64, 'base64')); expect(getImageMock).toHaveBeenNthCalledWith(1, testVariation.baselineName); @@ -240,6 +258,8 @@ describe('TestRunsService', () => { status: TestStatus.new, }, }); + expect(eventNewTestRunMock).toHaveBeenCalledWith(testRunWithResult); + expect(result).toBe(testRunWithResult); }); it('with baseline', async () => { @@ -274,7 +294,8 @@ describe('TestRunsService', () => { .fn() .mockReturnValueOnce(baseline) .mockReturnValueOnce(image); - service = await initService({ testRunCreateMock, saveImageMock, getImageMock }); + const eventNewTestRunMock = jest.fn(); + service = await initService({ testRunCreateMock, saveImageMock, getImageMock, eventNewTestRunMock }); const diffResult: DiffResult = { status: TestStatus.unresolved, diffName: 'diff image name', @@ -285,9 +306,9 @@ describe('TestRunsService', () => { const getDiffMock = jest.fn().mockReturnValueOnce(diffResult); service.getDiff = getDiffMock; const saveDiffResultMock = jest.fn(); - service.saveDiffResult = saveDiffResultMock; + service.saveDiffResult = saveDiffResultMock.mockResolvedValueOnce(testRunWithResult); - await service.create(testVariation, createTestRequestDto); + const result = await service.create(testVariation, createTestRequestDto); expect(saveImageMock).toHaveBeenCalledWith('screenshot', Buffer.from(createTestRequestDto.imageBase64, 'base64')); expect(service.getDiff).toHaveBeenCalledWith( @@ -324,6 +345,8 @@ describe('TestRunsService', () => { }); expect(getDiffMock).toHaveBeenCalledWith(baseline, image, testRun.diffTollerancePercent, testRun.ignoreAreas); expect(saveDiffResultMock).toHaveBeenCalledWith(testRun.id, diffResult); + expect(eventNewTestRunMock).toHaveBeenCalledWith(testRunWithResult); + expect(result).toBe(testRunWithResult); }); }); diff --git a/src/test-runs/test-runs.service.ts b/src/test-runs/test-runs.service.ts index d2093408..0fa8f263 100644 --- a/src/test-runs/test-runs.service.ts +++ b/src/test-runs/test-runs.service.ts @@ -7,7 +7,7 @@ import { StaticService } from '../shared/static/static.service'; import { PrismaService } from '../prisma/prisma.service'; import { TestRun, TestStatus, TestVariation } from '@prisma/client'; import { DiffResult } from './diffResult'; -import { EventsGateway } from 'src/events/events.gateway'; +import { EventsGateway } from '../events/events.gateway'; @Injectable() export class TestRunsService { From f1b9aba882dfc92fc0f624691b16df7779bb4389 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Tue, 9 Jun 2020 23:59:54 +0200 Subject: [PATCH 4/5] duplicated test removed --- src/test-runs/test-runs.service.spec.ts | 245 ++++++++---------------- 1 file changed, 79 insertions(+), 166 deletions(-) diff --git a/src/test-runs/test-runs.service.spec.ts b/src/test-runs/test-runs.service.spec.ts index 324089d2..20791b10 100644 --- a/src/test-runs/test-runs.service.spec.ts +++ b/src/test-runs/test-runs.service.spec.ts @@ -155,7 +155,7 @@ describe('TestRunsService', () => { }); }); - describe('create', () => { + it('create', async () => { const initCreateTestRequestDto: CreateTestRequestDto = { buildId: 'buildId', projectId: 'projectId', @@ -177,177 +177,90 @@ describe('TestRunsService', () => { status: TestStatus.unresolved, }; - it('no baseline', async () => { - const testRun = { - id: 'id', - imageName: 'imageName', - baselineName: null, - diffTollerancePercent: 1, - ignoreAreas: '[]', - diffName: null, - }; + const testRun = { + id: 'id', + imageName: 'imageName', + baselineName: 'baselineName', + diffTollerancePercent: 1, + ignoreAreas: '[]', + diffName: null, + }; + const testVariation = { + id: '123', + projectId: 'project Id', + name: 'Test name', + baselineName: 'baselineName', + os: 'OS', + browser: 'browser', + viewport: 'viewport', + device: 'device', + ignoreAreas: '[]', + createdAt: new Date(), + updatedAt: new Date(), + }; + const createTestRequestDto = initCreateTestRequestDto; + const testRunCreateMock = jest.fn().mockResolvedValueOnce(testRun); + const imageName = 'image name'; + const saveImageMock = jest.fn().mockReturnValueOnce(imageName); + const image = 'image'; + const baseline = 'baseline'; + const getImageMock = jest + .fn() + .mockReturnValueOnce(baseline) + .mockReturnValueOnce(image); + const eventNewTestRunMock = jest.fn(); + service = await initService({ testRunCreateMock, saveImageMock, getImageMock, eventNewTestRunMock }); + const diffResult: DiffResult = { + status: TestStatus.unresolved, + diffName: 'diff image name', + pixelMisMatchCount: 11, + diffPercent: 22, + isSameDimension: true, + }; + const getDiffMock = jest.fn().mockReturnValueOnce(diffResult); + service.getDiff = getDiffMock; + const saveDiffResultMock = jest.fn(); + service.saveDiffResult = saveDiffResultMock.mockResolvedValueOnce(testRunWithResult); - const testVariation = { - id: '123', - projectId: 'project Id', - name: 'Test name', - baselineName: null, - os: 'OS', - browser: 'browser', - viewport: 'viewport', - device: 'device', - ignoreAreas: '[]', - createdAt: new Date(), - updatedAt: new Date(), - }; - const diffResult: DiffResult = { - status: null, - diffName: null, - pixelMisMatchCount: null, - diffPercent: null, - isSameDimension: false, - }; - const createTestRequestDto = initCreateTestRequestDto; - const testRunCreateMock = jest.fn().mockResolvedValueOnce(testRun); - const imageName = 'image name'; - const saveImageMock = jest.fn().mockReturnValueOnce(imageName); - const image = 'image'; - const baseline = null; - const getImageMock = jest - .fn() - .mockReturnValueOnce(baseline) - .mockReturnValueOnce(image); - const eventNewTestRunMock = jest.fn(); - service = await initService({ testRunCreateMock, saveImageMock, getImageMock, eventNewTestRunMock }); - const getDiffMock = jest.fn().mockReturnValueOnce(diffResult); - service.getDiff = getDiffMock; - const saveDiffResultMock = jest.fn().mockResolvedValueOnce(testRunWithResult); - service.saveDiffResult = saveDiffResultMock; - - const result = await service.create(testVariation, createTestRequestDto); - - expect(saveImageMock).toHaveBeenCalledWith('screenshot', Buffer.from(createTestRequestDto.imageBase64, 'base64')); - expect(getImageMock).toHaveBeenNthCalledWith(1, testVariation.baselineName); - expect(getImageMock).toHaveBeenNthCalledWith(2, imageName); - expect(getDiffMock).toHaveBeenCalledWith(baseline, image, testRun.diffTollerancePercent, testRun.ignoreAreas); - expect(saveDiffResultMock).toHaveBeenCalledWith(testRun.id, diffResult); - expect(testRunCreateMock).toHaveBeenCalledWith({ - data: { - imageName, - testVariation: { - connect: { - id: testVariation.id, - }, - }, - build: { - connect: { - id: createTestRequestDto.buildId, - }, - }, - name: testVariation.name, - browser: testVariation.browser, - device: testVariation.device, - os: testVariation.os, - viewport: testVariation.viewport, - baselineName: testVariation.baselineName, - ignoreAreas: testVariation.ignoreAreas, - diffTollerancePercent: createTestRequestDto.diffTollerancePercent, - diffName: undefined, - pixelMisMatchCount: undefined, - diffPercent: undefined, - status: TestStatus.new, - }, - }); - expect(eventNewTestRunMock).toHaveBeenCalledWith(testRunWithResult); - expect(result).toBe(testRunWithResult); - }); + const result = await service.create(testVariation, createTestRequestDto); - it('with baseline', async () => { - const testRun = { - id: 'id', - imageName: 'imageName', - baselineName: 'baselineName', - diffTollerancePercent: 1, - ignoreAreas: '[]', - diffName: null, - }; - const testVariation = { - id: '123', - projectId: 'project Id', - name: 'Test name', - baselineName: 'baselineName', - os: 'OS', - browser: 'browser', - viewport: 'viewport', - device: 'device', - ignoreAreas: '[]', - createdAt: new Date(), - updatedAt: new Date(), - }; - const createTestRequestDto = initCreateTestRequestDto; - const testRunCreateMock = jest.fn().mockResolvedValueOnce(testRun); - const imageName = 'image name'; - const saveImageMock = jest.fn().mockReturnValueOnce(imageName); - const image = 'image'; - const baseline = 'baseline'; - const getImageMock = jest - .fn() - .mockReturnValueOnce(baseline) - .mockReturnValueOnce(image); - const eventNewTestRunMock = jest.fn(); - service = await initService({ testRunCreateMock, saveImageMock, getImageMock, eventNewTestRunMock }); - const diffResult: DiffResult = { - status: TestStatus.unresolved, - diffName: 'diff image name', - pixelMisMatchCount: 11, - diffPercent: 22, - isSameDimension: true, - }; - const getDiffMock = jest.fn().mockReturnValueOnce(diffResult); - service.getDiff = getDiffMock; - const saveDiffResultMock = jest.fn(); - service.saveDiffResult = saveDiffResultMock.mockResolvedValueOnce(testRunWithResult); - - const result = await service.create(testVariation, createTestRequestDto); - - expect(saveImageMock).toHaveBeenCalledWith('screenshot', Buffer.from(createTestRequestDto.imageBase64, 'base64')); - expect(service.getDiff).toHaveBeenCalledWith( - baseline, - image, - createTestRequestDto.diffTollerancePercent, - testVariation.ignoreAreas - ); - expect(getImageMock).toHaveBeenNthCalledWith(1, testVariation.baselineName); - expect(getImageMock).toHaveBeenNthCalledWith(2, imageName); - expect(testRunCreateMock).toHaveBeenCalledWith({ - data: { - imageName, - testVariation: { - connect: { - id: testVariation.id, - }, + expect(saveImageMock).toHaveBeenCalledWith('screenshot', Buffer.from(createTestRequestDto.imageBase64, 'base64')); + expect(service.getDiff).toHaveBeenCalledWith( + baseline, + image, + createTestRequestDto.diffTollerancePercent, + testVariation.ignoreAreas + ); + expect(getImageMock).toHaveBeenNthCalledWith(1, testVariation.baselineName); + expect(getImageMock).toHaveBeenNthCalledWith(2, imageName); + expect(testRunCreateMock).toHaveBeenCalledWith({ + data: { + imageName, + testVariation: { + connect: { + id: testVariation.id, }, - build: { - connect: { - id: createTestRequestDto.buildId, - }, + }, + build: { + connect: { + id: createTestRequestDto.buildId, }, - name: testVariation.name, - browser: testVariation.browser, - device: testVariation.device, - os: testVariation.os, - viewport: testVariation.viewport, - baselineName: testVariation.baselineName, - ignoreAreas: testVariation.ignoreAreas, - diffTollerancePercent: createTestRequestDto.diffTollerancePercent, - status: TestStatus.new, }, - }); - expect(getDiffMock).toHaveBeenCalledWith(baseline, image, testRun.diffTollerancePercent, testRun.ignoreAreas); - expect(saveDiffResultMock).toHaveBeenCalledWith(testRun.id, diffResult); - expect(eventNewTestRunMock).toHaveBeenCalledWith(testRunWithResult); - expect(result).toBe(testRunWithResult); + name: testVariation.name, + browser: testVariation.browser, + device: testVariation.device, + os: testVariation.os, + viewport: testVariation.viewport, + baselineName: testVariation.baselineName, + ignoreAreas: testVariation.ignoreAreas, + diffTollerancePercent: createTestRequestDto.diffTollerancePercent, + status: TestStatus.new, + }, }); + expect(getDiffMock).toHaveBeenCalledWith(baseline, image, testRun.diffTollerancePercent, testRun.ignoreAreas); + expect(saveDiffResultMock).toHaveBeenCalledWith(testRun.id, diffResult); + expect(eventNewTestRunMock).toHaveBeenCalledWith(testRunWithResult); + expect(result).toBe(testRunWithResult); }); describe('getDiff', () => { From a718abafabbd1cc59e7da0b5de0c02ba15f1f961 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Wed, 10 Jun 2020 00:04:12 +0200 Subject: [PATCH 5/5] hardcoded port removed --- src/events/events.gateway.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/events.gateway.ts b/src/events/events.gateway.ts index ec279d17..efb7f47f 100644 --- a/src/events/events.gateway.ts +++ b/src/events/events.gateway.ts @@ -3,7 +3,7 @@ import { Server } from 'socket.io'; import { TestRun } from '@prisma/client'; import { BuildDto } from '../builds/dto/build.dto'; -@WebSocketGateway(4201) +@WebSocketGateway() export class EventsGateway { @WebSocketServer() server: Server;