Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions assets/js/services/local-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ function getInfluxDBUrls() {
initializeStorageItem('urls', JSON.stringify(DEFAULT_STORAGE_URLS));
}

return JSON.parse(localStorage.getItem(urlStorageKey));
const storedUrls = JSON.parse(localStorage.getItem(urlStorageKey));
// Backfill any new default keys missing from stored data (e.g., when new
// products like core/enterprise are added after a user's first visit).
return { ...DEFAULT_STORAGE_URLS, ...storedUrls };
}

// Get the current or previous URL for a specific product or a custom url
Expand All @@ -131,8 +134,8 @@ function getInfluxDBUrl(product) {
const urlsString = localStorage.getItem(urlStorageKey);
const urlsObj = JSON.parse(urlsString);

// Return the URL of the specified product
return urlsObj[product];
// Return the URL of the specified product, falling back to the default
return urlsObj[product] ?? DEFAULT_STORAGE_URLS[product];
}

/*
Expand Down
80 changes: 80 additions & 0 deletions cypress/e2e/influxdb-url.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/// <reference types="cypress" />

/**
* InfluxDB URL localStorage E2E Test Suite
*
* Tests that the InfluxDB URL replacement logic in influxdb-url.js handles
* localStorage correctly, including stale data from returning visitors.
*
* Regression tests for https://github.com/influxdata/docs-v2/issues/6960
* where stale localStorage missing the `core` key caused JavaScript to
* replace rendered hostnames with "undefined" in code blocks.
*/

const STORAGE_KEY = 'influxdata_docs_urls';
const TEST_PAGE = '/influxdb3/core/plugins/';
const EXPECTED_PRODUCT_KEYS = [
'oss',
'cloud',
'core',
'enterprise',
'serverless',
'dedicated',
'clustered',
];

describe('InfluxDB URL - localStorage', function () {
it('should not render "undefined" in code blocks when localStorage is missing product keys', function () {
// Simulate a returning visitor whose localStorage was created before
// core/enterprise products were added — missing those keys entirely.
const staleUrls = {
oss: 'http://localhost:8086',
cloud: 'https://us-west-2-1.aws.cloud2.influxdata.com',
prev_oss: 'http://localhost:8086',
prev_cloud: 'https://us-west-2-1.aws.cloud2.influxdata.com',
custom: '',
};

cy.visit(TEST_PAGE, {
onBeforeLoad(win) {
win.localStorage.setItem(STORAGE_KEY, JSON.stringify(staleUrls));
},
});

// The api-endpoint block should show the default Core host, not "undefined"
cy.get('.article--content pre.api-endpoint')
.first()
.should('contain', 'localhost:8181')
.and('not.contain', 'undefined');

// No code block in the article should contain "undefined" as a bare host
cy.get('.article--content pre:not(.preserve)').each(($el) => {
cy.wrap($el).invoke('text').should('not.match', /undefined\/api\//);
});
});

it('should backfill all expected product URL keys into localStorage', function () {
cy.visit(TEST_PAGE, {
onBeforeLoad(win) {
// Start with no stored URLs — forces initialization
win.localStorage.removeItem(STORAGE_KEY);
},
});

// After the page loads and JS initializes, localStorage should contain
// all expected product keys with non-empty URL values.
cy.window().then((win) => {
const stored = JSON.parse(win.localStorage.getItem(STORAGE_KEY));
expect(stored).to.be.an('object');

EXPECTED_PRODUCT_KEYS.forEach((key) => {
expect(stored, `stored URLs should have key "${key}"`).to.have.property(
key
);
expect(stored[key], `"${key}" should be a non-empty string`).to.be.a(
'string'
).and.not.be.empty;
});
});
});
});
Loading