Skip to content

Conversation

@nchilada
Copy link

@nchilada nchilada commented Jun 12, 2020

What does this PR do?

Product changes

  • Don't attempt to interface with Optimizely Classic Web, since Classic is finally dead
  • Prepare to support Optimizely Edge, an alternative to Optimizely Web
  • Drop all references to customCampaignProperties. It seems to have been documented here but it couldn't possibly have worked.

Bug fixes

  • Don't try to track future inactive campaigns. The listener configured by registerFutureActiveCampaigns collects null campaign decisions in addition to active campaign decisions; until this PR, such campaigns were being passed to newActiveCampaign where they were throwing (asynchronous and thus inconsequential) errors.
  • If there is an effective referrer for the current page load, include it when tracking future campaigns and not just when tracking current campaigns.

Other refactoring

  • Stop using dependency injection (the referrerOverride, sendExperimentData, and sendCampaignData hooks on the left-hand side of the diff. It looks like that pattern was copy-and-pasted from here or here; in any case, it's confusing and unnecessary.
  • Define setRedirectInfo as a stateful method.
  • Test initWebIntegration as an isolated unit instead of invoking it as part of analytics.initialize. Ideally we'd do the same for sendWebDecisionToSegment`, but I ran out of energy.
  • Explicitly install lodash, sinon, and chai as devDependencies and use them throughout the tests. The preexisting tests used things like analytics.stub, analytics.called, and analytics.deepEqual but those are undocumented and seem to be less full-featured. As someone who doesn't have access to internal Segment documentation, those functions are very difficult to work with.

Are there breaking changes in this PR?

  • Technically yes, but effectively no, since the removed functionality is relevant to Optimizely products that haven't been supported in a long time.

Any background context you want to provide?

  • Our Classic Web product, the predecessor to X Web, is long gone.
  • We recently launched Optimizely Performance Edge, which may be implemented instead of Optimizely Web on any given page. We'll extend analytics.js-integrations to add support for it in a followup pull request.

Is there parity with the server-side/android/iOS integration components (if applicable)?

N/A

Does this require a new integration setting? If so, please explain how the new setting works

No. On the contrary, the "Custom Experiment Properties" setting described here is obsolete now that Optimizely Classic is gone (and was also incorrectly documented or implemented), and the "Custom Campaign Properties" setting can also be un-documented because it too was incorrectly implemented and is now being removed.

Links to helpful docs and other external resources

I've linked to some API docs from JSDoc comments!

* Don't attempt to interface with Optimizely Classic Web, since Classic is finally dead
* Prepare to support Optimizely Edge, an alternative to Optimizely Web
* Drop all references to customCampaignProperties. It seems to have been documented [here](https://segment.com/docs/connections/destinations/catalog/optimizely-web/#settings) but it couldn't possibly have worked.
* Generally refactor the code and tests.
@nchilada
Copy link
Author

@patrickshih-optimizely you may want to rebase #479 on top of this. I'll leave it up to you! One of us will definitely have merge conflicts 😆

// Segment added code: in case this is a redirect experiment
if (referrer) campaignState.experiment.referrer = referrer;
sendCampaignData(campaignState);
var registerFutureActiveCampaigns = function() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we talked a little bit about potentially bringing these out as private functions? It would make this suite much easier to test IMO. What are your thoughts?

If not, it feels a little questionable to declare these as functions and not really re-use them. Maybe we can unfurl them and supplement with comments? WDYT?

Copy link
Author

@nchilada nchilada Jun 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair points! Of the three remaining nested functions (see the latest commit) I think some are going to be easily reusable and some aren't.

Maybe we can extract the reusable ones?

What would we do with remaining ones - inline them? One could argue that single-use nested functions are helpful for documenting what each block of code does, but I think code comments might suffice too.

Copy link

@patrickshih-optimizely patrickshih-optimizely left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing all the cleanup code. I had a comment we can discuss!

Also, I'll rebase on top of yours... it'll makes my integration smoother

@nchilada nchilada marked this pull request as draft June 13, 2020 05:01
@nchilada nchilada marked this pull request as ready for review June 17, 2020 22:51

describe('after loading', function() {
beforeEach(function(done) {
analytics.once('ready', done);
Copy link
Author

@nchilada nchilada Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what analytics.once('ready', callback); does or whether it's relevant here. I removed it because it seemed to cause the test suite to hang and skip the tests in this describe; though maybe I'm wrong, maybe I was just misreading the test output.

beforeEach(function() {
analytics.initialize();
mockBothOptimizelyDataObjects();
analytics.page();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this was doing anything. There may be some value in testing an analytics.page call without the optional name argument, but I suspect this is not the correct place for that.


* Don't attempt to interface with Optimizely Classic Web, since Classic is finally dead
* Prepare to support Optimizely Edge, an alternative to Optimizely Web
* Drop all references to customCampaignProperties. It seems to have been documented [here](https://segment.com/docs/connections/destinations/catalog/optimizely-web/#settings) but it couldn't possibly have worked.
Copy link
Author

@nchilada nchilada Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond this update to the integration code, Custom Campaign Properties and Custom Experiment Properties should also be removed from the docs and from the Segment app. (I didn't highlight Custom Experiment Properties in HISTORY.md since it was specific to the Optimizely Classic Web product, whose code is being removed entirely.)

Full explanation of why this functionality is surely broken:

  • The docs indicate that Custom Experiment Properties and Custom Campaign Properties could be used to capture experiment- and campaign-specific properties like experiment_color and campaign_name in Classic Web and X Web respectively. This makes sense, kinda.
  • Unfortunately, the integration code indicates that for Classic Web, the Custom Experiment Properties are being read off of the top-level window.optimizely.data object, rather than off of an experiment object
  • And for X Web, the Custom Campaign Properties are being read off of a non-existent window.optimizely.newMockData property. This property is mocked in index.test.js but does not appear in actual X Web snippets.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the heads-up! I'll work on getting the documentation updated.

@tysonmote
Copy link

@nchilada Thanks for this! I'm going to work on releasing this shortly.

@tysonmote
Copy link

@nchilada It looks like this PR introduces some new lint warnings in our CI. Do you think you could fix these up? (Sorry that this isn't clear -- I'm not sure why our CircleCI setup isn't able to run successfully with external branches, yet.)

/workdir/integrations/optimizely/lib/index.js
--
  | 292:15  warning  'state' is already declared in the upper scope  no-shadow
  |  
  | /workdir/integrations/optimizely/test/index.test.js
  | 106:11  warning  for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array  no-restricted-syntax
  | 170:7   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  | 666:9   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  | 690:9   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  | 720:9   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  | 747:9   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  | 774:9   warning  'executeAsyncTest' was used before it was defined                                                                                                                      no-use-before-define
  |  
  | ✖ 8 problems (0 errors, 8 warnings)

@nchilada
Copy link
Author

@tysonmote @gpsamson thank you for the reviews and sorry for the late update! I've pushed some lint fixes; hopefully they help. I'm heading out of office through next week but @patrickshih-optimizely and I can check in to make sure you don't need anything to more for this PR.

BTW would you all be in charge of any necessary integration testing? I saw a link to this README but I don't have a lot of context (I've never directly used Segment myself).

@jenskene
Copy link

@patrickshih-optimizely and @nchilada — Thank you for your patience! We are planning to merge this PR and #483 on May 3, 2021. Let us know if anything has changed in the past (many) months.

@patrickshih-optimizely
Copy link

patrickshih-optimizely commented Apr 22, 2021

Hi @jenskene ! Thanks for getting back to us! @nchilada had since moved on from Optimizely, feel free to direct any questions about this PR to me.

I scanned this PR once again and this one looks good. Mainly, because most of the changes in this PR is removing old functionality that Optimizely does not support anymore (specifically, our Classic product and things w.r.t Classic)

@nchilada
Copy link
Author

@patrickshih-optimizely thanks very much for taking over! @jenskene yup I left Optimizely last year and stopped getting notifications. Sorry for not posting an update in either PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants