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

feat(cdp): test site function javascript #26943

Merged
merged 4 commits into from
Dec 17, 2024
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
4 changes: 2 additions & 2 deletions posthog/cdp/site_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def get_transpiled_function(hog_function: HogFunction) -> str:
"""
let processEvent = undefined;
if ('onEvent' in source) {
processEvent = function processEvent(globals) {
processEvent = function processEvent(globals, posthog) {
if (!('onEvent' in source)) { return; };
const inputs = buildInputs(globals);
const filterGlobals = { ...globals.groups, ...globals.event, person: globals.person, inputs, pdi: { distinct_id: globals.event.distinct_id, person: globals.person } };
Expand Down Expand Up @@ -123,7 +123,7 @@ def get_transpiled_function(hog_function: HogFunction) -> str:
}

return {
processEvent: processEvent
processEvent: (globals) => processEvent(globals, posthog)
}
}

Expand Down
73 changes: 67 additions & 6 deletions posthog/cdp/test/test_site_functions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import subprocess
import tempfile
from inline_snapshot import snapshot
Expand Down Expand Up @@ -71,7 +72,7 @@ def test_get_transpiled_function_basic(self):
};return exports;})();
let processEvent = undefined;
if ('onEvent' in source) {
processEvent = function processEvent(globals) {
processEvent = function processEvent(globals, posthog) {
if (!('onEvent' in source)) { return; };
const inputs = buildInputs(globals);
const filterGlobals = { ...globals.groups, ...globals.event, person: globals.person, inputs, pdi: { distinct_id: globals.event.distinct_id, person: globals.person } };
Expand All @@ -98,7 +99,7 @@ def test_get_transpiled_function_basic(self):
}

return {
processEvent: processEvent
processEvent: (globals) => processEvent(globals, posthog)
}
}

Expand Down Expand Up @@ -129,12 +130,12 @@ def test_get_transpiled_function_with_template_input(self):
assert '__getGlobal("person")' in result

def test_get_transpiled_function_with_filters(self):
self.hog_function.hog = "export function onEvent(event) { console.log(event.event); }"
self.hog_function.hog = "export function onEvent(globals) { console.log(globals); }"
self.hog_function.filters = {"events": [{"id": "$pageview", "name": "$pageview", "type": "events", "order": 0}]}

result = self.compile_and_run()

assert "console.log(event.event);" in result
assert "console.log(globals);" in result
assert "const filterMatches = " in result
assert '__getGlobal("event") == "$pageview"' in result
assert "const filterMatches = !!(!!((__getGlobal" in result
Expand Down Expand Up @@ -249,7 +250,7 @@ def test_get_transpiled_function_with_complex_filters(self):
action.steps = [{"event": "$pageview", "url": "https://example.com"}] # type: ignore
action.save()

self.hog_function.hog = "export function onEvent(event) { console.log(event.event); }"
self.hog_function.hog = "export function onEvent(globals) { console.log(globals); }"
self.hog_function.filters = {
"events": [{"id": "$pageview", "name": "$pageview", "type": "events"}],
"actions": [{"id": str(action.pk), "name": "Test Action", "type": "actions"}],
Expand All @@ -258,7 +259,7 @@ def test_get_transpiled_function_with_complex_filters(self):

result = self.compile_and_run()

assert "console.log(event.event);" in result
assert "console.log(globals);" in result
assert "const filterMatches = " in result
assert '__getGlobal("event") == "$pageview"' in result
assert "https://example.com" in result
Expand All @@ -283,3 +284,63 @@ def test_get_transpiled_function_with_mappings(self):
assert 'if (!!(!!((__getGlobal("event") == "$autocapture")))) {' in result
assert "const newInputs = structuredClone(inputs);" in result
assert 'newInputs["greeting"] = concat("Hallo, ", __getProperty' in result

def test_run_function_onload(self):
self.hog_function.hog = "export function onLoad({ inputs, posthog }) { console.log(inputs.message); }"
self.hog_function.filters = {"events": [{"id": "$pageview", "name": "$pageview", "type": "events", "order": 0}]}
self.hog_function.inputs = {"message": {"value": "Hello World {person.properties.name}"}}

result = self.compile_and_run()
assert "Hello World" in result

response = self._execute_javascript(
result
+ "().init({ posthog: { get_property: () => ({name: 'Bob'}) }, callback: () => { console.log('Loaded') } })"
)
assert "Hello World Bob\nLoaded" == response.strip()

def test_run_function_onevent(self):
self.hog_function.hog = "export function onEvent({ inputs }) { console.log(inputs.message); }"
# self.hog_function.filters = {"events": [{"id": "$pageview", "name": "$pageview", "type": "events", "order": 0}]}
self.hog_function.inputs = {"message": {"value": "Hello World {event.properties.id}"}}
self.hog_function.mappings = [
{
"inputs": {"greeting": {"value": "Hallo, {person.properties.nonexistent_property}!"}},
"filters": {"events": [{"id": "$pageview", "name": "$pageview", "type": "events"}]},
}
]

result = self.compile_and_run()
assert "Hello World" in result

globals = {
"event": {"event": "$pageview", "properties": {"id": "banana"}},
"groups": {},
"person": {"properties": {"name": "Bob"}},
}
response = self._execute_javascript(
result
+ "().init({ posthog: { get_property: () => ({name: 'Bob'}) }, callback: () => { console.log('Loaded') } }).processEvent("
+ json.dumps(globals)
+ ")"
)
assert "Loaded\nHello World banana" == response.strip()

globals = {
"event": {"event": "$autocapture", "properties": {"id": "banana"}},
"groups": {},
"person": {"properties": {"name": "Bob"}},
}
response = self._execute_javascript(
result
+ "().init({ posthog: { get_property: () => ({name: 'Bob'}) }, callback: () => { console.log('Loaded') } }).processEvent("
+ json.dumps(globals)
+ ")"
)
assert "Loaded" == response.strip()

def _execute_javascript(self, js) -> str:
with tempfile.NamedTemporaryFile(delete=False) as f:
f.write(js.encode("utf-8"))
f.flush()
return subprocess.check_output(["node", f.name]).decode("utf-8")
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
FROM events LEFT JOIN (
SELECT person_id AS cohort_person_id, 1 AS matched, cohort_id
FROM static_cohort_people
WHERE in(cohort_id, [8])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id)
WHERE in(cohort_id, [11])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id)
WHERE and(1, equals(__in_cohort.matched, 1))
LIMIT 100
'''
Expand All @@ -66,7 +66,7 @@
FROM events LEFT JOIN (
SELECT person_id AS cohort_person_id, 1 AS matched, cohort_id
FROM static_cohort_people
WHERE in(cohort_id, [9])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id)
WHERE in(cohort_id, [12])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id)
WHERE and(1, equals(__in_cohort.matched, 1))
LIMIT 100
'''
Expand Down
8 changes: 4 additions & 4 deletions posthog/models/test/test_remote_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ def test_renders_js_including_site_functions(self):
const source = (function () {let exports={};"use strict";;return exports;})();
let processEvent = undefined;
if ('onEvent' in source) {
processEvent = function processEvent(globals) {
processEvent = function processEvent(globals, posthog) {
if (!('onEvent' in source)) { return; };
const inputs = buildInputs(globals);
const filterGlobals = { ...globals.groups, ...globals.event, person: globals.person, inputs, pdi: { distinct_id: globals.event.distinct_id, person: globals.person } };
Expand All @@ -704,7 +704,7 @@ def test_renders_js_including_site_functions(self):
}

return {
processEvent: processEvent
processEvent: (globals) => processEvent(globals, posthog)
}
}

Expand All @@ -723,7 +723,7 @@ def test_renders_js_including_site_functions(self):
const source = (function () {let exports={};"use strict";;return exports;})();
let processEvent = undefined;
if ('onEvent' in source) {
processEvent = function processEvent(globals) {
processEvent = function processEvent(globals, posthog) {
if (!('onEvent' in source)) { return; };
const inputs = buildInputs(globals);
const filterGlobals = { ...globals.groups, ...globals.event, person: globals.person, inputs, pdi: { distinct_id: globals.event.distinct_id, person: globals.person } };
Expand All @@ -750,7 +750,7 @@ def test_renders_js_including_site_functions(self):
}

return {
processEvent: processEvent
processEvent: (globals) => processEvent(globals, posthog)
}
}

Expand Down
Loading