Skip to content

Commit

Permalink
Merge branch 'master' into fix/test-runner-upgrade
Browse files Browse the repository at this point in the history
# Conflicts:
#	frontend/src/lib/components/PropertyFilters/PropertyFilters.stories.tsx
#	frontend/src/lib/components/PropertyGroupFilters/PropertyGroupFilters.stories.tsx
  • Loading branch information
benjackwhite committed Nov 22, 2023
2 parents 4f92d5b + 5b44c3b commit 7fa8e76
Show file tree
Hide file tree
Showing 1,475 changed files with 15,231 additions and 8,409 deletions.
41 changes: 35 additions & 6 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,25 @@ module.exports = {
},
ecmaVersion: 2018,
sourceType: 'module',
project: 'tsconfig.json'
project: 'tsconfig.json',
},
plugins: ['prettier', 'react', 'cypress', '@typescript-eslint', 'no-only-tests', 'jest', 'compat', 'posthog'],
plugins: [
'prettier',
'react',
'cypress',
'@typescript-eslint',
'no-only-tests',
'jest',
'compat',
'posthog',
'simple-import-sort',
],
rules: {
'no-console': ['error', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'no-only-tests/no-only-tests': 'error',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'react/prop-types': [0],
'react/react-in-jsx-scope': [0],
'react/no-unescaped-entities': [0],
Expand Down Expand Up @@ -112,6 +124,11 @@ module.exports = {
importNames: ['Tooltip'],
message: 'Please use Tooltip from @posthog/lemon-ui instead.',
},
{
name: 'antd',
importNames: ['Alert'],
message: 'Please use LemonBanner from @posthog/lemon-ui instead.',
},
],
},
],
Expand Down Expand Up @@ -231,6 +248,10 @@ module.exports = {
element: 'a',
message: 'use <Link> instead',
},
{
element: 'Alert',
message: 'use <LemonBanner> instead',
},
],
},
],
Expand All @@ -254,14 +275,22 @@ module.exports = {
rules: {
// The below complains needlessly about expect(api.createInvite).toHaveBeenCalledWith(...)
'@typescript-eslint/unbound-method': 'off',
}
},
},
{
// disable these rules for files generated by kea-typegen
files: ['*Type.ts', '*Type.tsx'],
files: ['*Type.ts', '*Type.tsx'], // Kea typegen output
rules: {
'no-restricted-imports': 'off',
'@typescript-eslint/ban-types': ['off'],
'@typescript-eslint/ban-types': 'off',
'simple-import-sort/imports': 'off',
'simple-import-sort/exports': 'off',
},
},
{
files: ['frontend/src/scenes/notebooks/Nodes/*'], // Notebooks code weirdly relies on its order of sorting
rules: {
'simple-import-sort/imports': 'off',
'simple-import-sort/exports': 'off',
},
},
{
Expand Down
1 change: 1 addition & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
// CSS Color Module Level 3 says currentColor, Level 4 candidate says currentcolor
// Sticking to Level 3 for now
camelCaseSvgKeywords: true,
ignoreKeywords: ['BlinkMacSystemFont'], // BlinkMacSystemFont MUST have this particular casing
},
],
// Sadly Safari only started supporting the range syntax of media queries in 2023, so let's switch to that
Expand Down
3 changes: 3 additions & 0 deletions cypress/e2e/featureFlags.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ describe('Feature Flags', () => {
cy.get('[data-attr=save-feature-flag]').first().click()

// after save there should be a delete button
cy.get('[data-attr="more-button"]').click()
cy.get('button[data-attr="delete-feature-flag"]').should('have.text', 'Delete feature flag')

// make sure the data is there as expected after a page reload!
Expand Down Expand Up @@ -83,11 +84,13 @@ describe('Feature Flags', () => {
cy.get('[data-attr=save-feature-flag]').first().click()

// after save there should be a delete button
cy.get('[data-attr="more-button"]').click()
cy.get('button[data-attr="delete-feature-flag"]').should('have.text', 'Delete feature flag')

cy.clickNavMenu('featureflags')
cy.get('[data-attr=feature-flag-table]').should('contain', name)
cy.get(`[data-row-key=${name}]`).contains(name).click()
cy.get('[data-attr="more-button"]').click()
cy.get('[data-attr=delete-feature-flag]').click()
cy.get('.Toastify').contains('Undo').should('be.visible')
})
Expand Down
5 changes: 3 additions & 2 deletions cypress/e2e/insights.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { urls } from 'scenes/urls'
import { randomString } from '../support/random'

import { decideResponse } from '../fixtures/api/decide'
import { savedInsights, createInsight, insight } from '../productAnalytics'
import { createInsight, insight, savedInsights } from '../productAnalytics'
import { randomString } from '../support/random'

// For tests related to trends please check trendsElements.js
// insight tests were split up because Cypress was struggling with this many tests in one file🙈
Expand Down
2 changes: 1 addition & 1 deletion ee/api/test/test_billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from typing import Any, Dict, List
from unittest.mock import MagicMock, patch
from uuid import uuid4
from zoneinfo import ZoneInfo

import jwt
from zoneinfo import ZoneInfo
from dateutil.relativedelta import relativedelta
from django.utils.timezone import now
from freezegun import freeze_time
Expand Down
23 changes: 17 additions & 6 deletions ee/api/test/test_organization.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime as dt
import random
from unittest.mock import ANY, patch
from unittest import mock
from unittest.mock import ANY, call, patch

from freezegun.api import freeze_time
from rest_framework import status
Expand Down Expand Up @@ -104,11 +105,21 @@ def test_delete_last_organization(self, mock_capture):
"Did not return a 404 on trying to delete a nonexistent org",
)

mock_capture.assert_called_once_with(
self.user.distinct_id,
"organization deleted",
organization_props,
groups={"instance": ANY, "organization": str(org_id)},
mock_capture.assert_has_calls(
[
call(
self.user.distinct_id,
"membership level changed",
properties={"new_level": 15, "previous_level": 1},
groups=mock.ANY,
),
call(
self.user.distinct_id,
"organization deleted",
organization_props,
groups={"instance": mock.ANY, "organization": str(org_id)},
),
]
)

def test_no_delete_organization_not_owning(self):
Expand Down
11 changes: 10 additions & 1 deletion ee/billing/billing_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
import structlog
from django.utils import timezone
from rest_framework.exceptions import NotAuthenticated
from sentry_sdk import capture_exception

from ee.billing.billing_types import BillingStatus
from ee.billing.quota_limiting import set_org_usage_summary, sync_org_quota_limits
from ee.models import License
from ee.settings import BILLING_SERVICE_URL
from posthog.cloud_utils import get_cached_instance_license
from posthog.models import Organization
from posthog.models.organization import OrganizationUsageInfo
from posthog.models.organization import OrganizationMembership, OrganizationUsageInfo

logger = structlog.get_logger(__name__)

Expand Down Expand Up @@ -114,6 +115,14 @@ def update_billing_distinct_ids(self, organization: Organization) -> None:
distinct_ids = list(organization.members.values_list("distinct_id", flat=True))
self.update_billing(organization, {"distinct_ids": distinct_ids})

def update_billing_customer_email(self, organization: Organization) -> None:
try:
owner_membership = OrganizationMembership.objects.get(organization=organization, level=15)
user = owner_membership.user
self.update_billing(organization, {"org_customer_email": user.email})
except Exception as e:
capture_exception(e)

def deactivate_products(self, organization: Organization, products: str) -> None:
res = requests.get(
f"{BILLING_SERVICE_URL}/api/billing/deactivate?products={products}",
Expand Down
23 changes: 23 additions & 0 deletions ee/billing/test/test_billing_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,26 @@ def test_update_billing_distinct_ids(self, billing_patch_request_mock: MagicMock
BillingManager(license).update_billing_distinct_ids(organization)
assert billing_patch_request_mock.call_count == 1
assert len(billing_patch_request_mock.call_args[1]["json"]["distinct_ids"]) == 2

@patch(
"ee.billing.billing_manager.requests.patch",
return_value=MagicMock(status_code=200, json=MagicMock(return_value={"text": "ok"})),
)
def test_update_billing_customer_email(self, billing_patch_request_mock: MagicMock):
organization = self.organization
license = super(LicenseManager, cast(LicenseManager, License.objects)).create(
key="key123::key123",
plan="enterprise",
valid_until=timezone.datetime(2038, 1, 19, 3, 14, 7),
)
User.objects.create_and_join(
organization=organization,
email="[email protected]",
password=None,
level=OrganizationMembership.Level.OWNER,
)
organization.refresh_from_db()
assert len(organization.members.values_list("distinct_id", flat=True)) == 2 # one exists in the test base
BillingManager(license).update_billing_customer_email(organization)
assert billing_patch_request_mock.call_count == 1
assert billing_patch_request_mock.call_args[1]["json"]["org_customer_email"] == "[email protected]"
2 changes: 1 addition & 1 deletion ee/clickhouse/models/test/__snapshots__/test_property.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
---
# name: test_parse_groups_persons_edge_case_with_single_filter
<class 'tuple'> (
'AND ( has(%(vglobalperson_0)s, replaceRegexpAll(JSONExtractRaw(person_props, %(kglobalperson_0)s), \'^"|"$\', \'\')))',
'AND ( has(%(vglobalperson_0)s, "pmat_email"))',
<class 'dict'> {
'kglobalperson_0': 'email',
'vglobalperson_0': <class 'list'> [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# name: ClickhouseTestExperimentSecondaryResults.test_basic_secondary_metric_results
'
/* user_id:133 celery:posthog.celery.sync_insight_caching_state */
/* user_id:131 celery:posthog.celery.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
Expand Down
Binary file modified frontend/__snapshots__/components-command-bar--actions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/components-command-bar--search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/components-networkrequesttiming--basic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--closable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--dismissable.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--info.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-banner--warning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/lemon-ui-lemon-button--as-links.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/posthog-3000-keyboard-shortcut--muted.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-batchexports--create-export.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-notebooks--notebooks-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-pipeline--pipeline-app-logs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-surveys--surveys-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-other-login--sso-error.png
Binary file modified frontend/__snapshots__/scenes-other-settings--settings-project.png
Binary file modified frontend/__snapshots__/scenes-other-settings--settings-user.png
20 changes: 11 additions & 9 deletions frontend/src/exporter/ExportedInsight/ExportedInsight.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { ChartDisplayType, InsightLogicProps, InsightModel } from '~/types'
import './ExportedInsight.scss'

import clsx from 'clsx'
import { BindLogic } from 'kea'
import { insightLogic } from 'scenes/insights/insightLogic'
import { FilterBasedCardContent } from 'lib/components/Cards/InsightCard/InsightCard'
import './ExportedInsight.scss'
import { Logo } from '~/toolbar/assets/Logo'
import { QueriesUnsupportedHere } from 'lib/components/Cards/InsightCard/QueriesUnsupportedHere'
import { TopHeading } from 'lib/components/Cards/InsightCard/TopHeading'
import { InsightLegend } from 'lib/components/InsightLegend/InsightLegend'
import { ExportOptions, ExportType } from '~/exporter/types'
import clsx from 'clsx'
import { SINGLE_SERIES_DISPLAY_TYPES } from 'lib/constants'
import { insightLogic } from 'scenes/insights/insightLogic'
import { isTrendsFilter } from 'scenes/insights/sharedUtils'
import { isDataTableNode } from '~/queries/utils'
import { QueriesUnsupportedHere } from 'lib/components/Cards/InsightCard/QueriesUnsupportedHere'

import { ExportOptions, ExportType } from '~/exporter/types'
import { Query } from '~/queries/Query/Query'
import { TopHeading } from 'lib/components/Cards/InsightCard/TopHeading'
import { isDataTableNode } from '~/queries/utils'
import { Logo } from '~/toolbar/assets/Logo'
import { ChartDisplayType, InsightLogicProps, InsightModel } from '~/types'

export function ExportedInsight({
insight,
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/exporter/Exporter.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useEffect } from 'react'
import { Meta, StoryFn, StoryObj } from '@storybook/react'
import { Exporter } from './Exporter'
import { useEffect } from 'react'

import { dashboard } from '~/exporter/__mocks__/Exporter.mocks'
import { ExportType } from '~/exporter/types'

import { Exporter } from './Exporter'

type Story = StoryObj<typeof Exporter>
const meta: Meta<typeof Exporter> = {
title: 'Exporter/Exporter',
Expand Down
21 changes: 12 additions & 9 deletions frontend/src/exporter/Exporter.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import '~/styles'
import './Exporter.scss'
import { useEffect } from 'react'
import { ExportedData, ExportType } from '~/exporter/types'
import { DashboardPlacement } from '~/types'
import { ExportedInsight } from '~/exporter/ExportedInsight/ExportedInsight'
import { Logo } from '~/toolbar/assets/Logo'
import { Dashboard } from 'scenes/dashboard/Dashboard'
import { useResizeObserver } from 'lib/hooks/useResizeObserver'
import { Link } from 'lib/lemon-ui/Link'

import clsx from 'clsx'
import { useValues } from 'kea'
import { teamLogic } from 'scenes/teamLogic'
import { useResizeObserver } from 'lib/hooks/useResizeObserver'
import { Link } from 'lib/lemon-ui/Link'
import { useEffect } from 'react'
import { Dashboard } from 'scenes/dashboard/Dashboard'
import { SessionRecordingPlayer } from 'scenes/session-recordings/player/SessionRecordingPlayer'
import { SessionRecordingPlayerMode } from 'scenes/session-recordings/player/sessionRecordingPlayerLogic'
import { teamLogic } from 'scenes/teamLogic'

import { ExportedInsight } from '~/exporter/ExportedInsight/ExportedInsight'
import { ExportedData, ExportType } from '~/exporter/types'
import { Logo } from '~/toolbar/assets/Logo'
import { DashboardPlacement } from '~/types'

import { exporterViewLogic } from './exporterViewLogic'

export function Exporter(props: ExportedData): JSX.Element {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/exporter/__mocks__/Exporter.mocks.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { FunnelLayout, ShownAsValue } from 'lib/constants'

import {
ChartDisplayType,
DashboardTile,
Expand All @@ -7,7 +9,6 @@ import {
InsightShortId,
InsightType,
} from '~/types'
import { FunnelLayout, ShownAsValue } from 'lib/constants'

export const dashboard: DashboardType = {
id: 1,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/exporter/exporterViewLogic.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { kea, path, props, selectors } from 'kea'
import { ExportedData } from './types'

import type { exporterViewLogicType } from './exporterViewLogicType'
import { ExportedData } from './types'

// This is a simple logic that is mounted by the Exporter view and then can be found by any nested callers
// This simplifies passing props everywhere.
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/exporter/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import '~/styles'
import './Exporter.scss'

import { createRoot } from 'react-dom/client'
import { loadPostHogJS } from '~/loadPostHogJS'
import { initKea } from '~/initKea'

import { Exporter } from '~/exporter/Exporter'
import { ExportedData } from '~/exporter/types'
import { initKea } from '~/initKea'
import { loadPostHogJS } from '~/loadPostHogJS'

import { ErrorBoundary } from '../layout/ErrorBoundary'

// Disable tracking for all exports and embeds.
Expand Down
1 change: 1 addition & 0 deletions frontend/src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import posthog from 'posthog-js'

import { ExportedData } from '~/exporter/types'

declare global {
Expand Down
12 changes: 5 additions & 7 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import '~/styles'

import { createRoot } from 'react-dom/client'
import { getContext } from 'kea'

import posthog from 'posthog-js'
import { PostHogProvider } from 'posthog-js/react'
import { createRoot } from 'react-dom/client'
import { App } from 'scenes/App'
import { initKea } from './initKea'

import { loadPostHogJS } from './loadPostHogJS'
import { initKea } from './initKea'
import { ErrorBoundary } from './layout/ErrorBoundary'

import { PostHogProvider } from 'posthog-js/react'
import posthog from 'posthog-js'
import { loadPostHogJS } from './loadPostHogJS'

loadPostHogJS()
initKea()
Expand Down
Loading

0 comments on commit 7fa8e76

Please sign in to comment.