From e472eb0441dec9a433c6e2567276856c4b8ff2e4 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Fri, 30 Jun 2023 13:51:26 -0400 Subject: [PATCH 1/6] add mixpanel to core --- packages/core/package.json | 1 + yarn.lock | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/packages/core/package.json b/packages/core/package.json index aa3c4d4c775..b6a5fca8ff8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -73,6 +73,7 @@ "iter-tools": "^7.5.0", "js-interpreter": "2.2.0", "lodash": "^4.17.21", + "mixpanel": "0.17.0", "mocha": "10.1.0", "node-emoji": "^1.8.1", "original-require": "^1.0.1", diff --git a/yarn.lock b/yarn.lock index 58b670a7e61..0f92a4217a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16097,6 +16097,14 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== +https-proxy-agent@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + https-proxy-agent@^2.2.0: version "2.2.4" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" @@ -19590,6 +19598,13 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mixpanel@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.17.0.tgz#ec57b068598c620cf039a5e504fb37c97ebfe8ce" + integrity sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g== + dependencies: + https-proxy-agent "5.0.0" + mkdirp-infer-owner@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" From 0150fa18431f216f35751eff248581a6788a9099 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Fri, 30 Jun 2023 14:22:55 -0400 Subject: [PATCH 2/6] replace google analytics with mixpanel --- .../core/lib/services/analytics/google.js | 187 ------------------ packages/core/lib/services/analytics/main.js | 2 +- .../core/lib/services/analytics/mixpanel.js | 41 ++++ packages/core/package.json | 1 - yarn.lock | 15 +- 5 files changed, 45 insertions(+), 201 deletions(-) delete mode 100644 packages/core/lib/services/analytics/google.js create mode 100644 packages/core/lib/services/analytics/mixpanel.js diff --git a/packages/core/lib/services/analytics/google.js b/packages/core/lib/services/analytics/google.js deleted file mode 100644 index 37674281e45..00000000000 --- a/packages/core/lib/services/analytics/google.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @module googleAnalytics; - * @requires module:@truffle/config - * @requires module:universal-analytics - * @requires module:uuid - * @requires module:inquirer - * @requires module:../version - */ - -const Config = require("@truffle/config"); -const userConfig = Config.getUserConfig(); -const ua = require("universal-analytics"); -const { v4: uuid } = require("uuid"); - -const inquirer = require("inquirer"); - -const version = require("../../version").info(); - -//set truffleAnalyticsId depending on whether version is bundled -const truffleAnalyticsId = version.bundle ? "UA-83874933-6" : "UA-83874933-7"; - -const analyticsInquiry = [ - { - type: "list", - name: "analyticsInquiry", - message: - "Would you like to enable analytics for your Truffle projects? Doing so will allow us to make sure Truffle is working as expected and help us address any bugs more efficiently.", - choices: ["Yes, enable analytics", "No, do not enable analytics"] - } -]; -const analyticsDisable = [ - { - type: "confirm", - name: "analyticsDisable", - message: "Analytics are currently enabled. Would you like to disable them?", - default: false - } -]; -const analyticsEnable = [ - { - type: "confirm", - name: "analyticsEnable", - message: "Analytics are currently disabled. Would you like to enable them?", - default: false - } -]; - -const googleAnalytics = { - /** - * set user-level unique id - */ - setUserId: function () { - if (!userConfig.get("uniqueId")) { - let userId = uuid(); - userConfig.set({ uniqueId: userId }); - } - }, - /** - * get user-level options for analytics - * @param {Object} userConfig - * @returns {bool} - */ - getAnalytics: function () { - return userConfig.get("enableAnalytics"); - }, - /** - * set user-level options for analytics - * @param {bool} analyticsBool - * @param {Object} userConfig - */ - setAnalytics: function (analyticsBool) { - if (analyticsBool === true) { - this.setUserId(); - console.log("Analytics enabled"); - userConfig.set({ - enableAnalytics: true, - analyticsSet: true, - analyticsMessageDateTime: Date.now() - }); - } else if (analyticsBool === false) { - console.log("Analytics disabled"); - userConfig.set({ - enableAnalytics: false, - analyticsSet: true, - analyticsMessageDateTime: Date.now() - }); - } else { - const message = - `Error setting config option.` + - `\n> You must set the 'analytics' option to either 'true' ` + - `or 'false'. \n> The value you provided was ${analyticsBool}.`; - throw new Error(message); - } - return true; - }, - /** - * prompt user to determine values for user-level analytics config options - * @param {Object} userConfig - */ - setUserConfigViaPrompt: async function () { - if (!userConfig.get("analyticsSet") && process.stdin.isTTY === true) { - let answer = await inquirer.prompt(analyticsInquiry); - if (answer.analyticsInquiry === analyticsInquiry[0].choices[0]) { - this.setAnalytics(true); - } else { - this.setAnalytics(false); - } - } else if ( - userConfig.get("analyticsSet") && - userConfig.get("enableAnalytics") && - process.stdin.isTTY === true - ) { - let answer = await inquirer.prompt(analyticsDisable); - if (answer.analyticsDisable) { - this.setAnalytics(false); - } else { - this.setAnalytics(true); - } - } else if ( - userConfig.get("analyticsSet") && - !userConfig.get("enableAnalytics") && - process.stdin.isTTY === true - ) { - let answer = await inquirer.prompt(analyticsEnable); - if (answer.analyticsEnable) { - this.setAnalytics(true); - } else { - this.setAnalytics(false); - } - } - return true; - }, - /** - * check user-level config to see if user has enabled analytics - * @returns {bool} - */ - checkIfAnalyticsEnabled: function () { - if (userConfig.get("enableAnalytics")) { - return true; - } else { - return false; - } - }, - - /** - * set data that will be the same in future calls - * @returns {Object} visitor - */ - setPersistentAnalyticsData: function () { - if (this.checkIfAnalyticsEnabled() === true) { - let userId = userConfig.get("uniqueId"); - let visitor = ua(truffleAnalyticsId, { cid: userId }); - return visitor; - } - }, - - /** - * send event to Google Analytics - * @param {Object} - */ - // eslint-disable-next-line no-unused-vars - sendAnalyticsEvent: function (eventObject, callback) { - let visitor = this.setPersistentAnalyticsData(); - let sendObject = {}; - if (eventObject["command"]) { - sendObject["ec"] = eventObject["command"]; - sendObject["ea"] = JSON.stringify(eventObject["args"]); - sendObject["el"] = eventObject["version"]; - sendObject["dp"] = "/" + eventObject["command"]; - } else { - sendObject["ec"] = "Error"; - sendObject["ea"] = "nonzero exit code"; - sendObject["el"] = - eventObject["version"] + " " + eventObject["exception"]; - sendObject["dp"] = "/error"; - } - - if (visitor) { - // eslint-disable-next-line no-unused-vars - visitor.event(sendObject, function (err) {}); - } - - return true; - } -}; - -module.exports = googleAnalytics; diff --git a/packages/core/lib/services/analytics/main.js b/packages/core/lib/services/analytics/main.js index 54a58455bde..fa29a808dbe 100644 --- a/packages/core/lib/services/analytics/main.js +++ b/packages/core/lib/services/analytics/main.js @@ -1,5 +1,5 @@ require("source-map-support/register"); -const analytics = require("./google.js"); +const analytics = require("./mixpanel.js"); const PROCESS_TIMEOUT = 5000; // ms diff --git a/packages/core/lib/services/analytics/mixpanel.js b/packages/core/lib/services/analytics/mixpanel.js new file mode 100644 index 00000000000..3400d45a1bb --- /dev/null +++ b/packages/core/lib/services/analytics/mixpanel.js @@ -0,0 +1,41 @@ +const Config = require("@truffle/config"); +const userConfig = Config.getUserConfig(); +const version = require("../../version").info(); +const TRUFFLE_TOKEN = version.bundled + ? "1d07dcde31267402f4ad0740bcc0d797" + : "2247a338c6bbd7e9a65bb3923e5b10b8"; +const Mixpanel = require("mixpanel"); + +module.exports = { + sendAnalyticsEvent: function (eventObject) { + const { userId } = this.getUserId(); + const sendObject = {}; + const eventType = eventObject.command ? "command" : "error"; + if (eventObject.command) { + sendObject["ec"] = eventObject["command"]; + sendObject["ea"] = JSON.stringify(eventObject["args"]); + sendObject["el"] = eventObject["version"]; + sendObject["dp"] = "/" + eventObject["command"]; + } else { + sendObject["ec"] = "Error"; + sendObject["ea"] = "nonzero exit code"; + sendObject["el"] = + eventObject["version"] + " " + eventObject["exception"]; + sendObject["dp"] = "/error"; + } + + if (userId) { + // eslint-disable-next-line no-unused-vars + const mixpanel = Mixpanel.init(TRUFFLE_TOKEN, { + keepAlive: false + }); + mixpanel.track(eventType, eventObject); + } + + return true; + }, + + getUserId: function () { + return { userId: userConfig.get("uniqueId") }; + } +}; diff --git a/packages/core/package.json b/packages/core/package.json index b6a5fca8ff8..94032ede1fe 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -82,7 +82,6 @@ "source-map-support": "^0.5.19", "spawn-args": "0.2.0", "tmp": "^0.2.1", - "universal-analytics": "^0.4.17", "uuid": "^9.0.0", "web3": "1.10.0", "web3-utils": "1.10.0", diff --git a/yarn.lock b/yarn.lock index 0f92a4217a2..ebf5b42bf8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11894,7 +11894,7 @@ debug@4.3.3: dependencies: ms "2.1.2" -debug@^3.0.0, debug@^3.1.0, debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -22719,7 +22719,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.79.0, request@^2.85.0, request@^2.88.0, request@^2.88.2: +request@^2.79.0, request@^2.85.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -25303,15 +25303,6 @@ unique-slug@^3.0.0: dependencies: imurmurhash "^0.1.4" -universal-analytics@^0.4.17: - version "0.4.20" - resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.4.20.tgz#d6b64e5312bf74f7c368e3024a922135dbf24b03" - integrity sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw== - dependencies: - debug "^3.0.0" - request "^2.88.0" - uuid "^3.0.0" - universal-user-agent@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-2.1.0.tgz#5abfbcc036a1ba490cb941f8fd68c46d3669e8e4" @@ -25542,7 +25533,7 @@ uuid@8.3.2, uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^3.0.0, uuid@^3.3.2, uuid@^3.3.3: +uuid@^3.3.2, uuid@^3.3.3: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== From d590961a6afbde13e276b004b911fc4d51ba836f Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Fri, 30 Jun 2023 16:13:14 -0400 Subject: [PATCH 3/6] remove more google analytics stuff and re-arrange tests --- packages/core/lib/commands/config/run.js | 10 +- packages/core/lib/commands/config/utils.js | 122 ++++++++++++++++++ packages/core/package.json | 2 +- packages/core/test/lib/commands/config.js | 98 ++++++++++++++ .../services/analytics/google-analytics.js | 106 --------------- .../test/lib/services/analytics/mixpanel.js | 28 ++++ packages/core/test/user-config.js | 32 ----- 7 files changed, 254 insertions(+), 144 deletions(-) create mode 100644 packages/core/lib/commands/config/utils.js delete mode 100644 packages/core/test/lib/services/analytics/google-analytics.js create mode 100644 packages/core/test/lib/services/analytics/mixpanel.js delete mode 100644 packages/core/test/user-config.js diff --git a/packages/core/lib/commands/config/run.js b/packages/core/lib/commands/config/run.js index 5d3538a38b3..976ded88d81 100644 --- a/packages/core/lib/commands/config/run.js +++ b/packages/core/lib/commands/config/run.js @@ -1,10 +1,10 @@ +const analyticsUtils = require("./utils"); const userLevelSettings = ["analytics"]; /** * run config commands to get/set/list Truffle config options * @param {Object} options **/ module.exports = async function (options) { - const googleAnalytics = require("../../services/analytics/google.js"); const Config = require("@truffle/config"); const OS = require("os"); @@ -31,14 +31,14 @@ module.exports = async function (options) { } if (command === null) { - return await googleAnalytics.setUserConfigViaPrompt(); + return await analyticsUtils.setUserConfigViaPrompt(); } else if (command.userLevel) { switch (command.key) { case "analytics": { if (command.set) { - googleAnalytics.setAnalytics(command.value); + analyticsUtils.setAnalytics(command.value); } else { - log(googleAnalytics.getAnalytics()); + log(analyticsUtils.getAnalytics()); } break; } @@ -47,7 +47,7 @@ module.exports = async function (options) { return; } else if (command.list) { log("Truffle config values"); - log(`analytics = ${googleAnalytics.getAnalytics()}`); + log(`analytics = ${analyticsUtils.getAnalytics()}`); } else { const config = Config.detect(options); diff --git a/packages/core/lib/commands/config/utils.js b/packages/core/lib/commands/config/utils.js new file mode 100644 index 00000000000..808ba25b30e --- /dev/null +++ b/packages/core/lib/commands/config/utils.js @@ -0,0 +1,122 @@ +const Config = require("@truffle/config"); +const inquirer = require("inquirer"); +const { v4: uuid } = require("uuid"); + +const analyticsInquiry = [ + { + type: "list", + name: "analyticsInquiry", + message: + "Would you like to enable analytics for your Truffle projects? Doing so will allow us to make sure Truffle is working as expected and help us address any bugs more efficiently.", + choices: ["Yes, enable analytics", "No, do not enable analytics"] + } +]; +const analyticsDisable = [ + { + type: "confirm", + name: "analyticsDisable", + message: "Analytics are currently enabled. Would you like to disable them?", + default: false + } +]; +const analyticsEnable = [ + { + type: "confirm", + name: "analyticsEnable", + message: "Analytics are currently disabled. Would you like to enable them?", + default: false + } +]; + +module.exports = { + getUserConfig: function () { + return Config.getUserConfig(); + }, + /** + * set user-level unique id + */ + setUserId: function () { + if (!this.getUserConfig().get("uniqueId")) { + const userId = uuid(); + this.getUserConfig().set({ uniqueId: userId }); + } + }, + /** + * get user-level options for analytics + * @param {Object} userConfig + * @returns {bool} + */ + getAnalytics: function () { + return this.getUserConfig().get("enableAnalytics"); + }, + /** + * set user-level options for analytics + * @param {bool} analyticsBool + * @param {Object} userConfig + */ + setAnalytics: function (analyticsBool) { + if (analyticsBool === true) { + this.setUserId(); + console.log("Analytics enabled"); + this.getUserConfig().set({ + enableAnalytics: true, + analyticsSet: true, + analyticsMessageDateTime: Date.now() + }); + } else if (analyticsBool === false) { + console.log("Analytics disabled"); + this.getUserConfig().set({ + enableAnalytics: false, + analyticsSet: true, + analyticsMessageDateTime: Date.now() + }); + } else { + const message = + `Error setting config option.` + + `\n> You must set the 'analytics' option to either 'true' ` + + `or 'false'. \n> The value you provided was ${analyticsBool}.`; + throw new Error(message); + } + return true; + }, + /** + * prompt user to determine values for user-level analytics config options + * @param {Object} userConfig + */ + setUserConfigViaPrompt: async function () { + if ( + !this.getUserConfig().get("analyticsSet") && + process.stdin.isTTY === true + ) { + let answer = await inquirer.prompt(analyticsInquiry); + if (answer.analyticsInquiry === analyticsInquiry[0].choices[0]) { + this.setAnalytics(true); + } else { + this.setAnalytics(false); + } + } else if ( + this.getUserConfig().get("analyticsSet") && + this.getUserConfig().get("enableAnalytics") && + process.stdin.isTTY === true + ) { + let answer = await inquirer.prompt(analyticsDisable); + if (answer.analyticsDisable) { + this.setAnalytics(false); + } else { + this.setAnalytics(true); + } + } else if ( + this.getUserConfig().get("analyticsSet") && + !this.getUserConfig().get("enableAnalytics") && + process.stdin.isTTY === true + ) { + let answer = await inquirer.prompt(analyticsEnable); + if (answer.analyticsEnable) { + this.setAnalytics(true); + } else { + this.setAnalytics(false); + } + } + return true; + } +}; diff --git a/packages/core/package.json b/packages/core/package.json index 94032ede1fe..083aed6c27d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -19,7 +19,7 @@ }, "scripts": { "prepare": "exit 0", - "test": "mocha ./test/** ./test/**/*" + "test": "mocha ./test/** ./test/**/*.js ./test/**/**/*.js" }, "dependencies": { "@truffle/artifactor": "^4.0.194", diff --git a/packages/core/test/lib/commands/config.js b/packages/core/test/lib/commands/config.js index dbca78543a2..d59e24cf358 100644 --- a/packages/core/test/lib/commands/config.js +++ b/packages/core/test/lib/commands/config.js @@ -5,6 +5,10 @@ const path = require("path"); const fse = require("fs-extra"); const Config = require("@truffle/config"); const { createTestProject } = require("../../helpers"); +const sinon = require("sinon"); +const analyticsUtils = require("../../../lib/commands/config/utils"); +const inquirer = require("inquirer"); +let mockUserConfig; describe("config", function () { let config; @@ -53,4 +57,98 @@ describe("config", function () { const expected = path.join(config.working_directory, "./a-different-dir"); assert.equal(output, expected); }); + + describe("config", function () { + describe("#run", function () { + beforeEach(() => { + sinon.stub(inquirer, "prompt").returns({ then: () => 1 }); + sinon.stub(analyticsUtils, "setAnalytics").resolves(); + sinon.stub(analyticsUtils, "setUserConfigViaPrompt").resolves(); + }); + afterEach(() => { + inquirer.prompt.restore(); + analyticsUtils.setAnalytics.restore(); + analyticsUtils.setUserConfigViaPrompt.restore(); + sinon.restore(); + }); + it("calls analyticsUtils.setAnalytics() when provided with enableAnalytics option", function () { + command.run({ enableAnalytics: true, _: [] }, () => {}); + sinon.assert.calledOnce(analyticsUtils.setAnalytics); + }); + it("calls analyticsUtils.setAnalytics() when provided with disableAnalytics option", function () { + command.run({ disableAnalytics: true, _: [] }, () => {}); + sinon.assert.calledOnce(analyticsUtils.setAnalytics); + }); + it("calls analyticsUtils.setuserConfigViaPrompt() if not provided with options", function () { + command.run({ _: [] }); + sinon.assert.calledOnce(analyticsUtils.setUserConfigViaPrompt); + }); + }); + }); + + describe("analyticsUtils", function () { + describe("#setUserId", function () { + beforeEach(() => { + mockUserConfig = { + get: () => false, + set: sinon.spy() + }; + sinon.stub(inquirer, "prompt").returns({ then: () => 1 }); + sinon.stub(analyticsUtils, "getUserConfig").returns(mockUserConfig); + sinon.stub(analyticsUtils, "setUserConfigViaPrompt").resolves(); + }); + afterEach(() => { + inquirer.prompt.restore(); + analyticsUtils.getUserConfig.restore(); + analyticsUtils.setUserConfigViaPrompt.restore(); + }); + + it("sets a userId if one does not exist", function () { + analyticsUtils.setUserId(); + assert(mockUserConfig.set.calledOnce); + }); + }); + + describe("#setAnalytics", function () { + beforeEach(function () { + mockUserConfig = { + get: sinon.spy(), + set: sinon.spy() + }; + sinon.stub(analyticsUtils, "getUserConfig").returns(mockUserConfig); + }); + afterEach(function () { + analyticsUtils.getUserConfig.restore(); + }); + + it("sets user-level analytics preferences when passed enableAnalytics option", async function () { + sinon.stub(analyticsUtils, "setAnalytics").resolves(); + await command.run({ enableAnalytics: true }, () => {}); + let stubArg = analyticsUtils.setAnalytics.getCall(0).args[0]; + assert.equal(stubArg, true); + analyticsUtils.setAnalytics.restore(); + }); + it("sets user-level analytics preferences when passed disableAnalytics option", async function () { + sinon.stub(analyticsUtils, "setAnalytics").resolves(); + await command.run({ disableAnalytics: true }, () => {}); + let stubArg = analyticsUtils.setAnalytics.getCall(0).args[0]; + assert.equal(stubArg, false); + analyticsUtils.setAnalytics.restore(); + }); + it("sets user-level configuration of enableAnalytics to true if passed true", function () { + analyticsUtils.setAnalytics(true); + assert.equal( + mockUserConfig.set.getCall(1).args[0].enableAnalytics, + true + ); + }); + it("sets user-level configuration of enableAnalytics to false if passed false", function () { + analyticsUtils.setAnalytics(false); + assert.equal( + mockUserConfig.set.getCall(0).args[0].enableAnalytics, + false + ); + }); + }); + }); }); diff --git a/packages/core/test/lib/services/analytics/google-analytics.js b/packages/core/test/lib/services/analytics/google-analytics.js deleted file mode 100644 index 09a73c804f2..00000000000 --- a/packages/core/test/lib/services/analytics/google-analytics.js +++ /dev/null @@ -1,106 +0,0 @@ -const Config = require("@truffle/config"); -const ua = require("universal-analytics"); -const assert = require("chai").assert; -const sinon = require("sinon"); -const analytics = require("../../../../lib/services/analytics/google"); -const inquirer = require("inquirer"); -const configCommand = require("../../../../lib/commands/config"); -const Conf = require("conf"); - -describe("analytics", function() { - beforeEach(() => { - sinon.stub(inquirer, "prompt").returns({ then: () => 1 }); - sinon.stub(Config, "getUserConfig").returns(true); - sinon.stub(Conf.prototype, "get").returns(false); - sinon.stub(Conf.prototype, "set"); - sinon.stub(analytics, "setUserConfigViaPrompt").resolves(); - sinon.stub(ua.Visitor.prototype, "_enqueue"); - }); - afterEach(() => { - inquirer.prompt.restore(); - Config.getUserConfig.restore(); - Conf.prototype.get.restore(); - Conf.prototype.set.restore(); - analytics.setUserConfigViaPrompt.restore(); - ua.Visitor.prototype._enqueue.restore(); - sinon.restore(); - }); - describe("#setUserId", function() { - it("sets a userId if one does not exist", function() { - analytics.setUserId(); - sinon.assert.calledOnce(Conf.prototype.get); - sinon.assert.calledOnce(Conf.prototype.set); - }); - }); - describe("#setAnalytics", function() { - it("sets user-level analytics preferences when passed enableAnalytics option", function() { - let setAnalyticsStub = sinon.stub(analytics, "setAnalytics").resolves(); - configCommand.run({ enableAnalytics: true }, () => {}); - let stubArg = setAnalyticsStub.getCall(0).args[0]; - assert.equal(stubArg, true); - setAnalyticsStub.restore(); - }); - it("sets user-level analytics preferences when passed disableAnalytics option", function() { - let setAnalyticsStub = sinon.stub(analytics, "setAnalytics").resolves(); - configCommand.run({ disableAnalytics: true }, () => {}); - let stubArg = setAnalyticsStub.getCall(0).args[0]; - assert.equal(stubArg, false); - setAnalyticsStub.restore(); - }); - it("sets user-level configuration of enableAnalytics to true if passed true", function() { - analytics.setAnalytics(true); - sinon.assert.calledTwice(Conf.prototype.set); - let stubArg = Conf.prototype.set.getCall(1).args[0] - .enableAnalytics; - assert.equal(stubArg, true); - }); - it("sets user-level configuration of enableAnalytics to false if passed false", function() { - analytics.setAnalytics(false); - sinon.assert.calledOnce(Conf.prototype.set); - let stubArg = Conf.prototype.set.getCall(0).args[0] - .enableAnalytics; - assert.equal(stubArg, false); - }); - }); - describe("#setUserConfigViaPrompt", function() { - it("sets user-level configuration variables", function() { - configCommand.run({}, () => {}); - sinon.assert.calledOnce(analytics.setUserConfigViaPrompt); - }); - }); - describe("#checkIfAnalyticsEnabled", function() { - it("checks the user-level config to see if analytics are enabled", function() { - analytics.checkIfAnalyticsEnabled(); - sinon.assert.calledOnce(Conf.prototype.get); - }); - }); - describe("#setPersistentAnalyticsData", function() { - it("checks that analytics are enabled before proceeding", function() { - let checkAnalyticsStub = sinon - .stub(analytics, "checkIfAnalyticsEnabled") - .returns(true); - analytics.setPersistentAnalyticsData(); - sinon.assert.calledOnce(checkAnalyticsStub); - checkAnalyticsStub.restore(); - }); - it("sets and returns a visitor object for google analytics", function() { - let checkAnalyticsStub = sinon - .stub(analytics, "checkIfAnalyticsEnabled") - .returns(true); - let visitor = analytics.setPersistentAnalyticsData(); - assert.exists(visitor); - assert.isObject(visitor); - checkAnalyticsStub.restore(); - }); - }); - describe("#sendAnalyticsEvent", function() { - it("sends an event object to google analytics", function() { - sinon.stub(analytics, "checkIfAnalyticsEnabled").returns(true); - analytics.sendAnalyticsEvent({ - ec: "initialization", - ea: "truffle unbox" - }); - sinon.assert.calledOnce(ua.Visitor.prototype._enqueue); - }); - }); -}); diff --git a/packages/core/test/lib/services/analytics/mixpanel.js b/packages/core/test/lib/services/analytics/mixpanel.js new file mode 100644 index 00000000000..1ddb16aa0f1 --- /dev/null +++ b/packages/core/test/lib/services/analytics/mixpanel.js @@ -0,0 +1,28 @@ +const assert = require("chai").assert; +const sinon = require("sinon"); +const Mixpanel = require("mixpanel"); +const mixpanelUtility = require("../../../../lib/services/analytics/mixpanel"); + +describe("mixpanel", function () { + beforeEach(() => { + sinon.stub(Mixpanel, "init").returns({ + track: sinon.spy() + }); + sinon.stub(mixpanelUtility, "getUserId").returns("1234"); + }); + afterEach(() => { + Mixpanel.init.restore(); + mixpanelUtility.getUserId(); + }); + + describe("#sendAnalyticsEvent", function () { + it("sends an event object to google analytics", function () { + mixpanelUtility.sendAnalyticsEvent({ + ec: "initialization", + ea: "truffle unbox" + }); + assert(mixpanelUtility.getUserId.calledOnce); + assert(Mixpanel.init.calledOnce); + }); + }); +}); diff --git a/packages/core/test/user-config.js b/packages/core/test/user-config.js deleted file mode 100644 index 6f28fd6c29c..00000000000 --- a/packages/core/test/user-config.js +++ /dev/null @@ -1,32 +0,0 @@ -const sinon = require("sinon"); -const analytics = require("../lib/services/analytics/google"); -const configCommand = require("../lib/commands/config"); -const inquirer = require("inquirer"); - -describe("config", function() { - describe("#run", function() { - beforeEach(() => { - sinon.stub(inquirer, "prompt").returns({ then: () => 1 }); - sinon.stub(analytics, "setAnalytics").resolves(); - sinon.stub(analytics, "setUserConfigViaPrompt").resolves(); - }); - afterEach(() => { - inquirer.prompt.restore(); - analytics.setAnalytics.restore(); - analytics.setUserConfigViaPrompt.restore(); - sinon.restore(); - }); - it("calls analytics.setAnalytics() when provided with enableAnalytics option", function() { - configCommand.run({ enableAnalytics: true }, () => {}); - sinon.assert.calledOnce(analytics.setAnalytics); - }); - it("calls analytics.setAnalytics() when provided with disableAnalytics option", function() { - configCommand.run({ disableAnalytics: true }, () => {}); - sinon.assert.calledOnce(analytics.setAnalytics); - }); - it("calls analytics.setuserConfigViaPrompt() if not provided with options", function() { - configCommand.run({ _: [] }); - sinon.assert.calledOnce(analytics.setUserConfigViaPrompt); - }); - }); -}); From d6b30b6a3838d43075a6e50beb43e47f438338cb Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Fri, 30 Jun 2023 16:18:07 -0400 Subject: [PATCH 4/6] get rid of eslint line --- packages/core/lib/services/analytics/mixpanel.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/lib/services/analytics/mixpanel.js b/packages/core/lib/services/analytics/mixpanel.js index 3400d45a1bb..22602809a56 100644 --- a/packages/core/lib/services/analytics/mixpanel.js +++ b/packages/core/lib/services/analytics/mixpanel.js @@ -25,7 +25,6 @@ module.exports = { } if (userId) { - // eslint-disable-next-line no-unused-vars const mixpanel = Mixpanel.init(TRUFFLE_TOKEN, { keepAlive: false }); From 3ec7148e6b9722b1ff9861013d80797618cfe7a2 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Wed, 5 Jul 2023 10:57:26 -0400 Subject: [PATCH 5/6] add caret to mixpanel version in core --- packages/core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/package.json b/packages/core/package.json index 083aed6c27d..e09139b012b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -73,7 +73,7 @@ "iter-tools": "^7.5.0", "js-interpreter": "2.2.0", "lodash": "^4.17.21", - "mixpanel": "0.17.0", + "mixpanel": "^0.17.0", "mocha": "10.1.0", "node-emoji": "^1.8.1", "original-require": "^1.0.1", From 9a4007c69441e0e3d6a07ad68fe6c1cd00ad7ff6 Mon Sep 17 00:00:00 2001 From: eggplantzzz Date: Wed, 5 Jul 2023 15:26:05 -0400 Subject: [PATCH 6/6] update yarn.lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index ebf5b42bf8c..b9cbde6e4b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19598,7 +19598,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mixpanel@0.17.0: +mixpanel@^0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.17.0.tgz#ec57b068598c620cf039a5e504fb37c97ebfe8ce" integrity sha512-DY5WeOy/hmkPrNiiZugJpWR0iMuOwuj1a3u0bgwB2eUFRV6oIew/pIahhpawdbNjb+Bye4a8ID3gefeNPvL81g==