mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-28 09:16:49 +01:00
Add tests for FOSS (#1600)
* Add tests for FOSS * Ignore ee specific tests * Exclude more ee only tests * conditional tests, nice * Add ee_available to settings * fix test * Fix test * Test commit * Fix test again * Remove EE_MISSING in favor of EE_AVAILABLE completely * Rename bottom-notice.html to overlays.html, to better reflect purpose * Add greeting * Fix ee import Co-authored-by: Michael Matloka <dev@twixes.com>
This commit is contained in:
parent
5a6853654c
commit
2421793228
62
.github/workflows/ci-backend.yml
vendored
62
.github/workflows/ci-backend.yml
vendored
@ -209,4 +209,64 @@ jobs:
|
||||
touch frontend/dist/index.html
|
||||
touch frontend/dist/layout.html
|
||||
touch frontend/dist/shared_dashboard.html
|
||||
python manage.py test posthog --keepdb -v 2 --exclude-tag=skip_on_multitenancy
|
||||
python manage.py test --keepdb -v 2 --exclude-tag=skip_on_multitenancy
|
||||
|
||||
foss:
|
||||
name: FOSS tests (ee removed)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:12
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports: ['5432:5432']
|
||||
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Install requirements.txt dependencies with pip
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements.txt
|
||||
python -m pip install freezegun
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
|
||||
- name: Remove ee
|
||||
run: |
|
||||
rm -rf ee/
|
||||
|
||||
- name: Check migrations
|
||||
env:
|
||||
SECRET_KEY: '6b01eee4f945ca25045b5aab440b953461faf08693a9abbf1166dc7c6b9772da' # unsafe - for testing only
|
||||
DATABASE_URL: 'postgres://postgres:postgres@localhost:${{ job.services.postgres.ports[5432] }}/postgres'
|
||||
REDIS_URL: 'redis://localhost'
|
||||
run: python manage.py makemigrations --check --dry-run
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
SECRET_KEY: '6b01eee4f945ca25045b5aab440b953461faf08693a9abbf1166dc7c6b9772da' # unsafe - for testing only
|
||||
DATABASE_URL: 'postgres://postgres:postgres@localhost:${{ job.services.postgres.ports[5432] }}/postgres'
|
||||
run: |
|
||||
mkdir -p frontend/dist
|
||||
touch frontend/dist/index.html
|
||||
touch frontend/dist/layout.html
|
||||
touch frontend/dist/shared_dashboard.html
|
||||
python manage.py test -v 2 --exclude-tag=ee
|
||||
|
@ -4,7 +4,7 @@
|
||||
{% include "head.html" %}
|
||||
</head>
|
||||
<body>
|
||||
{% include "bottom-notice.html" %}
|
||||
{% include "overlays.html" %}
|
||||
<script>
|
||||
if (typeof Object.entries === 'undefined') {
|
||||
let div = document.createElement("div");
|
||||
|
@ -106,7 +106,7 @@ color: var(--blue)
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{% include "bottom-notice.html" %}
|
||||
{% include "overlays.html" %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -4,16 +4,19 @@ from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
||||
from dateutil import parser
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.utils import timezone
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from ee.clickhouse.process_event import process_event_ee # type: ignore
|
||||
from posthog.ee import check_ee_enabled
|
||||
from posthog.models import Team
|
||||
from posthog.tasks.process_event import process_event
|
||||
from posthog.utils import PersonalAPIKeyAuthentication, cors_response, get_ip_address, load_data_from_request
|
||||
|
||||
if settings.EE_AVAILABLE:
|
||||
from ee.clickhouse.process_event import process_event_ee # type: ignore
|
||||
|
||||
|
||||
def _datetime_from_seconds_or_millis(timestamp: str) -> datetime:
|
||||
if len(timestamp) > 11: # assuming milliseconds / update "11" to "12" if year > 5138 (set a reminder!)
|
||||
|
@ -1,11 +1,12 @@
|
||||
import posthoganalytics
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import login, password_validation
|
||||
from django.db import transaction
|
||||
from rest_framework import generics, permissions, serializers
|
||||
|
||||
from posthog.api.user import UserSerializer
|
||||
from posthog.models import Team, User
|
||||
from posthog.models.user import EE_MISSING, MULTI_TENANCY_MISSING
|
||||
from posthog.models.user import MULTI_TENANCY_MISSING
|
||||
|
||||
|
||||
class TeamSignupSerializer(serializers.Serializer):
|
||||
@ -45,7 +46,7 @@ class TeamSignupSerializer(serializers.Serializer):
|
||||
)
|
||||
|
||||
posthoganalytics.identify(
|
||||
user.distinct_id, properties={"email": user.email, "realm": realm, "ee_available": not EE_MISSING},
|
||||
user.distinct_id, properties={"email": user.email, "realm": realm, "ee_available": settings.EE_AVAILABLE},
|
||||
)
|
||||
|
||||
return user
|
||||
|
@ -151,7 +151,7 @@ class TestTeamUser(BaseTest):
|
||||
|
||||
class TestTeamSignup(APIBaseTest):
|
||||
@tag("skip_on_multitenancy")
|
||||
@patch("posthog.api.team.EE_MISSING", True)
|
||||
@patch("posthog.api.team.settings.EE_AVAILABLE", False)
|
||||
@patch("posthog.api.team.MULTI_TENANCY_MISSING", True)
|
||||
@patch("posthog.api.team.posthoganalytics.identify")
|
||||
@patch("posthog.api.team.posthoganalytics.capture")
|
||||
|
@ -10,12 +10,9 @@ from rest_framework.fields import BooleanField
|
||||
from .team import Team
|
||||
from .utils import generate_random_token
|
||||
|
||||
EE_MISSING = False
|
||||
MULTI_TENANCY_MISSING = False
|
||||
try:
|
||||
if settings.EE_AVAILABLE:
|
||||
from ee.models.license import License
|
||||
except ImportError:
|
||||
EE_MISSING = True
|
||||
|
||||
try:
|
||||
from multi_tenancy.models import TeamBilling # type: ignore
|
||||
@ -107,12 +104,12 @@ class User(AbstractUser):
|
||||
|
||||
@property
|
||||
def ee_available(self) -> bool:
|
||||
return not EE_MISSING
|
||||
return settings.EE_AVAILABLE
|
||||
|
||||
@property
|
||||
def billing_plan(self) -> Optional[str]:
|
||||
# If the EE folder is missing no features are available
|
||||
if EE_MISSING:
|
||||
if not settings.EE_AVAILABLE:
|
||||
return None
|
||||
|
||||
# If we're on multi-tenancy grab the team's price
|
||||
|
@ -188,6 +188,8 @@ if STATSD_HOST:
|
||||
MIDDLEWARE.insert(0, "django_statsd.middleware.StatsdMiddleware")
|
||||
MIDDLEWARE.append("django_statsd.middleware.StatsdMiddlewareTimer")
|
||||
|
||||
EE_AVAILABLE = False
|
||||
|
||||
# Append Enterprise Edition as an app if available
|
||||
try:
|
||||
from ee.apps import EnterpriseConfig
|
||||
@ -197,14 +199,15 @@ else:
|
||||
HOOK_EVENTS: Dict[str, str] = {}
|
||||
INSTALLED_APPS.append("rest_hooks")
|
||||
INSTALLED_APPS.append("ee.apps.EnterpriseConfig")
|
||||
EE_AVAILABLE = True
|
||||
|
||||
# Use django-extensions if it exists
|
||||
try:
|
||||
import django_extensions
|
||||
|
||||
INSTALLED_APPS.append("django_extensions")
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
INSTALLED_APPS.append("django_extensions")
|
||||
|
||||
INTERNAL_IPS = ["127.0.0.1", "172.18.0.1"] # Docker IP
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
|
@ -2,6 +2,7 @@ from datetime import timedelta
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import TransactionTestCase
|
||||
from django.utils.timezone import now
|
||||
from freezegun import freeze_time
|
||||
@ -31,7 +32,7 @@ class ProcessEvent(BaseTest):
|
||||
self.team.ingested_event = True # avoid sending `first team event ingested` to PostHog
|
||||
self.team.save()
|
||||
|
||||
with self.assertNumQueries(30):
|
||||
with self.assertNumQueries(30 if settings.EE_AVAILABLE else 28): # extra queries to check for hooks
|
||||
process_event(
|
||||
2,
|
||||
"",
|
||||
|
@ -31,12 +31,12 @@
|
||||
title: 'Welcome to PostHog',
|
||||
subtitle: 'Ask us anything in the chat window below 😊',
|
||||
primaryColor: '#1890ff',
|
||||
greeting: '',
|
||||
greeting: "Hi! Send us a message and we'll respond as soon as we can.",
|
||||
customer: {
|
||||
email: '{{ request.user.email }}',
|
||||
name: '{{ request.user.first_name }}'
|
||||
},
|
||||
newMessagePlaceholder: 'Start typing...',
|
||||
newMessagePlaceholder: 'Start typing…',
|
||||
baseUrl: 'https://app.papercups.io'
|
||||
},
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
from unittest.mock import Mock, call, patch
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.test import tag
|
||||
from django.utils.timezone import now
|
||||
from freezegun import freeze_time
|
||||
|
||||
from ee.models import License
|
||||
from posthog.api.test.base import BaseTest
|
||||
from posthog.models.user import User
|
||||
|
||||
@ -12,10 +12,11 @@ from posthog.models.user import User
|
||||
class TestUser(BaseTest):
|
||||
TESTS_API = True
|
||||
|
||||
@patch("posthog.models.user.EE_MISSING", True)
|
||||
@patch("posthog.settings.EE_AVAILABLE", False)
|
||||
def test_feature_available_no_ee(self):
|
||||
self.assertFalse(self.user.feature_available("whatever"))
|
||||
|
||||
@tag("ee")
|
||||
@patch("posthog.models.user.MULTI_TENANCY_MISSING", False)
|
||||
@patch("posthog.models.user.License.PLANS", {"price_1234567890": ["whatever"]})
|
||||
@patch("posthog.models.user.TeamBilling")
|
||||
@ -31,10 +32,13 @@ class TestUser(BaseTest):
|
||||
)
|
||||
self.assertFalse(self.user.feature_available("whatever"))
|
||||
|
||||
@tag("ee")
|
||||
@patch("posthog.models.user.License.PLANS", {"enterprise": ["whatever"]})
|
||||
@patch("ee.models.license.requests.post")
|
||||
@patch("posthog.models.user.MULTI_TENANCY_MISSING", True)
|
||||
def test_feature_available_self_hosted_has_license(self, patch_post):
|
||||
from ee.models import License
|
||||
|
||||
mock = Mock()
|
||||
mock.json.return_value = {"plan": "enterprise", "valid_until": now() + relativedelta(days=1)}
|
||||
patch_post.return_value = mock
|
||||
@ -42,14 +46,18 @@ class TestUser(BaseTest):
|
||||
self.assertTrue(self.user.feature_available("whatever"))
|
||||
self.assertFalse(self.user.feature_available("feature-doesnt-exist"))
|
||||
|
||||
@tag("ee")
|
||||
@patch("posthog.models.user.License.PLANS", {"enterprise": ["whatever"]})
|
||||
def test_feature_available_self_hosted_no_license(self):
|
||||
self.assertFalse(self.user.feature_available("whatever"))
|
||||
self.assertFalse(self.user.feature_available("feature-doesnt-exist"))
|
||||
|
||||
@tag("ee")
|
||||
@patch("posthog.models.user.License.PLANS", {"enterprise": ["whatever"]})
|
||||
@patch("ee.models.license.requests.post")
|
||||
def test_feature_available_self_hosted_license_expired(self, patch_post):
|
||||
from ee.models import License
|
||||
|
||||
mock = Mock()
|
||||
mock.json.return_value = {"plan": "enterprise", "valid_until": "2012-01-14T12:00:00.000Z"}
|
||||
patch_post.return_value = mock
|
||||
|
Loading…
Reference in New Issue
Block a user