Skip to content

Commit

Permalink
Merge branch 'aspicer/strict' into ch-24.3
Browse files Browse the repository at this point in the history
  • Loading branch information
aspicer committed Nov 7, 2024
2 parents b8bc040 + 5fc9138 commit 509fd77
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ export function AuthorizedUrlList({
}
center
data-attr="toolbar-open"
disabledReason={
keyedURL.url.includes('*')
? 'Wildcard domains cannot be launched'
: undefined
}
>
Launch
</LemonButton>
Expand Down
67 changes: 67 additions & 0 deletions frontend/src/scenes/experiments/ExperimentCodeSnippets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,36 @@ interface SnippetProps {
variant: string
}

export function AndroidSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
return (
<>
<CodeSnippet language={Language.Kotlin} wrap>
{`if (PostHog.getFeatureFlag("${flagKey}") == "${variant}") {
// do something
} else {
// It's a good idea to let control variant always be the default behaviour,
// so if something goes wrong with flag evaluation, you don't break your app.
}`}
</CodeSnippet>
</>
)
}

export function IOSSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
return (
<>
<CodeSnippet language={Language.Swift} wrap>
{`if (PostHogSDK.shared.getFeatureFlag("${flagKey}") as? String == "${variant}") {
// do something
} else {
// It's a good idea to let control variant always be the default behaviour,
// so if something goes wrong with flag evaluation, you don't break your app.
}`}
</CodeSnippet>
</>
)
}

export function NodeJSSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
return (
<>
Expand Down Expand Up @@ -59,6 +89,43 @@ export function JSSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
)
}

export function ReactSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
return (
<>
<CodeSnippet language={Language.JavaScript} wrap>
{`// You can either use the useFeatureFlagVariantKey hook,
// or you can use the feature flags component - https://posthog.com/docs/libraries/react#feature-flags-react-component
// Method one: using the useFeatureFlagVariantKey hook
import { useFeatureFlagVariantKey } from 'posthog-js/react'
function App() {
const variant = useFeatureFlagVariantKey('${flagKey}')
if (variant === '${variant}') {
// do something
}
}
// Method two: using the feature flags component
import { PostHogFeature } from 'posthog-js/react'
function App() {
return (
<PostHogFeature flag='${flagKey}' match='${variant}'>
<div>
{/* the component to show */}
</div>
</PostHogFeature>
)
}
// You can also test your code by overriding the feature flag:
posthog.featureFlags.override({'${flagKey}': '${variant}'})`}
</CodeSnippet>
</>
)
}

export function RNSnippet({ flagKey, variant }: SnippetProps): JSX.Element {
return (
<>
Expand Down
117 changes: 90 additions & 27 deletions frontend/src/scenes/experiments/ExperimentImplementationDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { LemonSelect, Link } from '@posthog/lemon-ui'
import { IconGolang, IconJavascript, IconNodeJS, IconPHP, IconPython, IconRuby } from 'lib/lemon-ui/icons'
import {
IconAndroidOS,
IconAppleIOS,
IconGolang,
IconJavascript,
IconNodeJS,
IconPHP,
IconPython,
IconRuby,
} from 'lib/lemon-ui/icons'
import { useState } from 'react'

import { Experiment, MultivariateFlagVariant } from '~/types'

import {
AndroidSnippet,
GolangSnippet,
IOSSnippet,
JSSnippet,
NodeJSSnippet,
PHPSnippet,
PythonSnippet,
ReactSnippet,
RNSnippet,
RubySnippet,
} from './ExperimentCodeSnippets'
Expand All @@ -22,48 +34,81 @@ const UTM_TAGS = '?utm_medium=in-product&utm_campaign=experiment'
const DOC_BASE_URL = 'https://posthog.com/docs/'
const FF_ANCHOR = '#feature-flags'

export enum LibraryType {
Client = 'Client',
Server = 'Server',
}

const OPTIONS = [
{
value: 'JavaScript',
documentationLink: `${DOC_BASE_URL}libraries/js${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconJavascript,
Snippet: JSSnippet,
type: LibraryType.Client,
},
{
value: 'ReactNative',
documentationLink: `${DOC_BASE_URL}libraries/react-native${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconJavascript,
Snippet: RNSnippet,
value: 'Android',
documentationLink: `${DOC_BASE_URL}libraries/android${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconAndroidOS,
Snippet: AndroidSnippet,
type: LibraryType.Client,
},
{
value: 'Go',
documentationLink: `${DOC_BASE_URL}libraries/go${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconGolang,
Snippet: GolangSnippet,
type: LibraryType.Server,
},
{
value: 'iOS',
documentationLink: `${DOC_BASE_URL}libraries/ios${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconAppleIOS,
Snippet: IOSSnippet,
type: LibraryType.Client,
},
{
value: 'Node.js',
documentationLink: `${DOC_BASE_URL}libraries/node${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconNodeJS,
Snippet: NodeJSSnippet,
type: LibraryType.Server,
},
{
value: 'PHP',
documentationLink: `${DOC_BASE_URL}libraries/php${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconPHP,
Snippet: PHPSnippet,
},
{
value: 'Ruby',
documentationLink: `${DOC_BASE_URL}libraries/ruby${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconRuby,
Snippet: RubySnippet,
},
{
value: 'Golang',
documentationLink: `${DOC_BASE_URL}libraries/go${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconGolang,
Snippet: GolangSnippet,
type: LibraryType.Server,
},
{
value: 'Python',
documentationLink: `${DOC_BASE_URL}libraries/python${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconPython,
Snippet: PythonSnippet,
type: LibraryType.Server,
},
{
value: 'React',
documentationLink: `${DOC_BASE_URL}libraries/react${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconJavascript,
Snippet: ReactSnippet,
type: LibraryType.Client,
},
{
value: 'React Native',
documentationLink: `${DOC_BASE_URL}libraries/react-native${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconJavascript,
Snippet: RNSnippet,
type: LibraryType.Client,
},
{
value: 'Ruby',
documentationLink: `${DOC_BASE_URL}libraries/ruby${UTM_TAGS}${FF_ANCHOR}`,
Icon: IconRuby,
Snippet: RubySnippet,
type: LibraryType.Server,
},
]

Expand All @@ -80,16 +125,34 @@ export function CodeLanguageSelect({
className="min-w-[7.5rem]"
onSelect={selectOption}
value={selectedOptionValue}
options={OPTIONS.map(({ value, Icon }) => ({
value,
label: value,
labelInMenu: (
<div className="flex items-center space-x-2">
<Icon />
<span>{value}</span>
</div>
),
}))}
options={[
{
title: 'Client libraries',
options: OPTIONS.filter((option) => option.type == LibraryType.Client).map(({ Icon, value }) => ({
value,
label: value,
labelInMenu: (
<div className="flex items-center space-x-2">
<Icon />
<span>{value}</span>
</div>
),
})),
},
{
title: 'Server libraries',
options: OPTIONS.filter((option) => option.type == LibraryType.Server).map(({ Icon, value }) => ({
value,
label: value,
labelInMenu: (
<div className="flex items-center space-x-2">
<Icon />
<span>{value}</span>
</div>
),
})),
},
]}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
funnel_breakdown_group_test_factory,
assert_funnel_results_equal,
)
from posthog.hogql_queries.insights.funnels.test.test_funnel import PseudoFunnelActors
from posthog.hogql_queries.legacy_compatibility.filter_to_query import filter_to_query
from posthog.models.action import Action
from posthog.models.filters import Filter
from posthog.models.instance_setting import override_instance_config
from posthog.queries.funnels.funnel_strict_persons import ClickhouseFunnelStrictActors
from posthog.schema import FunnelsQuery
from posthog.test.base import (
APIBaseTest,
Expand All @@ -43,7 +43,7 @@ class BaseTestFunnelStrictStepsBreakdown(
ClickhouseTestMixin,
funnel_breakdown_test_factory( # type: ignore
FunnelOrderType.STRICT,
ClickhouseFunnelStrictActors,
PseudoFunnelActors,
_create_action,
_create_person,
),
Expand Down Expand Up @@ -184,15 +184,15 @@ class BaseTestStrictFunnelGroupBreakdown(
ClickhouseTestMixin,
funnel_breakdown_group_test_factory( # type: ignore
FunnelOrderType.STRICT,
ClickhouseFunnelStrictActors,
PseudoFunnelActors,
),
):
__test__ = False


class BaseTestFunnelStrictStepsConversionTime(
ClickhouseTestMixin,
funnel_conversion_time_test_factory(FunnelOrderType.ORDERED, ClickhouseFunnelStrictActors), # type: ignore
funnel_conversion_time_test_factory(FunnelOrderType.ORDERED, PseudoFunnelActors), # type: ignore
):
maxDiff = None
__test__ = False
Expand All @@ -205,7 +205,7 @@ class BaseTestFunnelStrictSteps(ClickhouseTestMixin, APIBaseTest):
def _get_actor_ids_at_step(self, filter, funnel_step, breakdown_value=None):
filter = Filter(data=filter, team=self.team)
person_filter = filter.shallow_clone({"funnel_step": funnel_step, "funnel_step_breakdown": breakdown_value})
_, serialized_result, _ = ClickhouseFunnelStrictActors(person_filter, self.team).get_actors()
_, serialized_result, _ = PseudoFunnelActors(person_filter, self.team).get_actors()

return [val["id"] for val in serialized_result]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@

from posthog.constants import INSIGHT_FUNNELS, FunnelOrderType
from posthog.hogql_queries.insights.funnels.funnels_query_runner import FunnelsQueryRunner
from posthog.hogql_queries.insights.funnels.test.test_funnel import PseudoFunnelActors
from posthog.hogql_queries.legacy_compatibility.filter_to_query import filter_to_query

from posthog.models.action import Action
from posthog.models.filters import Filter
from posthog.models.property_definition import PropertyDefinition
from posthog.queries.funnels.funnel_unordered_persons import (
ClickhouseFunnelUnorderedActors,
)
from posthog.hogql_queries.insights.funnels.test.conversion_time_cases import (
funnel_conversion_time_test_factory,
)
Expand Down Expand Up @@ -49,7 +47,7 @@ class TestFunnelUnorderedStepsBreakdown(
ClickhouseTestMixin,
funnel_breakdown_test_factory( # type: ignore
FunnelOrderType.UNORDERED,
ClickhouseFunnelUnorderedActors,
PseudoFunnelActors,
_create_action,
_create_person,
),
Expand Down Expand Up @@ -638,7 +636,7 @@ class TestUnorderedFunnelGroupBreakdown(
ClickhouseTestMixin,
funnel_breakdown_group_test_factory( # type: ignore
FunnelOrderType.UNORDERED,
ClickhouseFunnelUnorderedActors,
PseudoFunnelActors,
),
):
pass
Expand All @@ -648,7 +646,7 @@ class TestFunnelUnorderedStepsConversionTime(
ClickhouseTestMixin,
funnel_conversion_time_test_factory( # type: ignore
FunnelOrderType.UNORDERED,
ClickhouseFunnelUnorderedActors,
PseudoFunnelActors,
),
):
maxDiff = None
Expand All @@ -659,7 +657,7 @@ class TestFunnelUnorderedSteps(ClickhouseTestMixin, APIBaseTest):
def _get_actor_ids_at_step(self, filter, funnel_step, breakdown_value=None):
filter = Filter(data=filter, team=self.team)
person_filter = filter.shallow_clone({"funnel_step": funnel_step, "funnel_step_breakdown": breakdown_value})
_, serialized_result, _ = ClickhouseFunnelUnorderedActors(person_filter, self.team).get_actors()
_, serialized_result, _ = PseudoFunnelActors(person_filter, self.team).get_actors()

return [val["id"] for val in serialized_result]

Expand Down

0 comments on commit 509fd77

Please sign in to comment.