Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rubicon project improvement/user sync #1549

Merged
merged 51 commits into from
Sep 18, 2017

Conversation

mkendall07
Copy link
Member

continued from here

grevory added 30 commits May 15, 2017 15:22
Copy link
Contributor

@dbemiller dbemiller left a comment

Choose a reason for hiding this comment

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

I think this is my last pass... things are looking really good now.

src/utils.js Outdated
let iframeHtml = this.createTrackPixelIframeHtml(url, encodeUri);
exports.insertUserSyncIframe = function(url) {
let iframeHtml = this.createTrackPixelIframeHtml(url, false);
iframeHtml = iframeHtml.replace('<iframe', '<iframe sandbox="allow-scripts"');
Copy link
Contributor

Choose a reason for hiding this comment

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

String parsing is very fragile... would suggest one of the following instead:

  • Change createTrackPixelIframeHtml so that it accepts a 'sandbox' option, and builds the right HTML from it
  • Create the div object first, and then set the sandbox attribute programatically

let logWarnStub;
let timeoutStub;
let shuffleStub;
let insertElementStub;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is unused/can be deleted.

src/userSync.js Outdated
import * as utils from 'src/utils';
import { config } from 'src/config';

export function newUserSync(userSyncConfig) {
Copy link
Contributor

@dbemiller dbemiller Aug 31, 2017

Choose a reason for hiding this comment

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

This looks really good... but there's one small tweak I'd like to propose:

import { config } from 'src/config';

export function newUserSync(userSyncDependencies) { ... }

const cookiesAreSupported = !utils.isSafariBrowser() && utils.cookiesAreEnabled();
export const userSync = newUserSync({
  config: config.getConfig('userSync'),
  cookiesAreSupported: cookiesAreSupported
});

It solves a testability problem you described in userSync_spec (see the comment there), and also makes this module fit into the larger Prebid architecture described in #1510.

});

// Since cookie support is only checked when the module is loaded this test will not work, but a test that covers
// this scenario is important and this should be revisited.
Copy link
Contributor

Choose a reason for hiding this comment

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

If you make the tweaks to userSync (see the comment in that file), this becomes testable very easily.

userSync = newUserSync({
  config: ...,
  cookiesAreSupported: false
})


beforeEach(() => {
bids = [];

server = sinon.fakeServer.create();
clock = sinon.useFakeTimers();
// monitor userSync registrations
sinon.spy(userSync, 'registerSync');
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this needs to be a stub?

Spies only observe things... so I think all the registerSync calls make real mutations to the real usersync global state.

Tests shouldn't have side effects like this.

src/userSync.js Outdated
* @private
*/
function fireSyncs() {
if (!userSyncConfig.syncEnabled || !cookiesAreSupported || hasFired) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If you're in a browser which doesn't support cookies, will the user syncs just build up inside the queue? Since this returns before calling queue = getDefaultQueue(). I'm not sure it's a big deal... but I suppose it could chew up memory if people run lots of auctions on the same page. Could probably wait for a secondary PR, though.

On that note... isn't this module basically a no-op if the browser doesn't support cookies? Again, perhaps a comment for a secondary PR, but... we could improve performance with something like:

export function newUserSync(userSyncDependencies) {
  if (!userSyncDependencies.cookiesAreSupported) {
    return {
      // Not pseudocode; these are literal no-ops
      registerSync: function() { }
      syncUsers: function() { }
      syncUsersOverride: function() { }
    }
  } else {
    // All the existing code & public API goes here
  }
}

@@ -334,7 +335,13 @@ $$PREBID_GLOBAL$$.removeAdUnit = function (adUnitCode) {

$$PREBID_GLOBAL$$.clearAuction = function() {
auctionRunning = false;
syncCookies(config.getConfig('cookieSyncDelay'));
// Only automatically sync if the publisher has not chosen to "enableOverride"
let userSyncConfig = config.getConfig('userSync') || {};
Copy link
Collaborator

Choose a reason for hiding this comment

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

A small improvement.
Since we have default value for userSync and there is not setter for userSync. It will always return an object so no need to keep a conditional check using ||
You have also kept a test case check to validate default config.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@jaiminpanchal27 userSync can be set with config.setConfig({userSync: null}); though I'm not sure why anyone would set it to null or another falsey value, unless maybe they thought it would turn it off.

@mkendall07
Copy link
Member Author

@harpere
any updates here?

src/userSync.js Outdated
@@ -74,6 +75,8 @@ export function newUserSync(userSyncDependencies) {
utils.logMessage(`Invoking image pixel user sync for bidder: ${bidderName}`);
// Create image object and add the src url
utils.triggerPixel(trackingPixelUrl);
// track that bidder has been synced
setBidderSynced(bidderName);
Copy link
Member Author

Choose a reason for hiding this comment

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

@harpere for now, let's drop these as we are only storing keys for S2S bidders and not client side. Later on we can integrate them, possibly by appending s2s${biddercode} to differentiate.

@mkendall07 mkendall07 merged commit 9da2dba into master Sep 18, 2017
outoftime pushed a commit to Genius/Prebid.js that referenced this pull request Sep 21, 2017
* tag '0.29.0' of https://github.com/prebid/Prebid.js: (29 commits)
  Prebid 0.29.0 Release
  Fix for not syncing bidders.  (prebid#1598)
  fix amp example pages (prebid#1597)
  closes prebid#1298 (prebid#1583)
  Fixed the broken tests. (prebid#1602)
  Rubicon Bidder Factory (prebid#1587)
  Trustx adapter (prebid#1488)
  Add nurl to markup (prebid#1601)
  Pass bidRequest to createBid (prebid#1600)
  Add Kumma adapter (prebid#1512)
  Serverbid alias (prebid#1560)
  Add user sync to process for approving adapter PRs (prebid#1457)
  fix travis build (prebid#1595)
  Rubicon project improvement/user sync (prebid#1549)
  Adding Orbitsoft adapter (prebid#1378)
  Fix renderer test for new validation rule (prebid#1592)
  Allow SET_TARGETING to be used in AnalyticsAdapter (prebid#1577)
  Add support for video stream context (prebid#1483)
  Invalidate bid if matching bid request not found (prebid#1575)
  allow adapters to set default adserverTargeting for specific bid (prebid#1568)
  ...
@matthewlane matthewlane deleted the rubicon-project-improvement/user-sync branch October 6, 2017 23:54
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.

6 participants