feat: introduce hashids permalink keys (#19324)

* feat: introduce hashids permalink keys

* implement dashboard permalinks

* remove shorturl notice from UPDATING.md

* lint

* fix test

* introduce KeyValueResource

* make filterState optional

* fix test

* fix resource names

(cherry picked from commit f4b71abb22)
This commit is contained in:
Ville Brofeldt
2022-03-24 21:53:09 +02:00
committed by Ville Brofeldt
parent 18f82411c9
commit a6a2def6d3
39 changed files with 344 additions and 367 deletions

View File

@@ -15,7 +15,9 @@
# specific language governing permissions and limitations
# under the License.
import json
from typing import Iterator
from unittest.mock import patch
from uuid import uuid3
import pytest
from flask_appbuilder.security.sqla.models import User
@@ -24,8 +26,9 @@ from sqlalchemy.orm import Session
from superset import db
from superset.dashboards.commands.exceptions import DashboardAccessDeniedError
from superset.key_value.models import KeyValueEntry
from superset.key_value.types import KeyValueResource
from superset.key_value.utils import decode_permalink_id
from superset.models.dashboard import Dashboard
from superset.models.slice import Slice
from tests.integration_tests.base_tests import login
from tests.integration_tests.fixtures.client import client
from tests.integration_tests.fixtures.world_bank_dashboard import (
@@ -35,7 +38,7 @@ from tests.integration_tests.fixtures.world_bank_dashboard import (
from tests.integration_tests.test_app import app
STATE = {
"filterState": {"FILTER_1": "foo",},
"filterState": {"FILTER_1": "foo"},
"hash": "my-anchor",
}
@@ -48,7 +51,22 @@ def dashboard_id(load_world_bank_dashboard_with_slices) -> int:
return dashboard.id
def test_post(client, dashboard_id: int):
@pytest.fixture
def permalink_salt() -> Iterator[str]:
from superset.key_value.shared_entries import get_permalink_salt, get_uuid_namespace
from superset.key_value.types import SharedKey
key = SharedKey.DASHBOARD_PERMALINK_SALT
salt = get_permalink_salt(key)
yield salt
namespace = get_uuid_namespace(salt)
db.session.query(KeyValueEntry).filter_by(
resource=KeyValueResource.APP, uuid=uuid3(namespace, key),
)
db.session.commit()
def test_post(client, dashboard_id: int, permalink_salt: str) -> None:
login(client, "admin")
resp = client.post(f"api/v1/dashboard/{dashboard_id}/permalink", json=STATE)
assert resp.status_code == 201
@@ -56,7 +74,8 @@ def test_post(client, dashboard_id: int):
key = data["key"]
url = data["url"]
assert key in url
db.session.query(KeyValueEntry).filter_by(uuid=key).delete()
id_ = decode_permalink_id(key, permalink_salt)
db.session.query(KeyValueEntry).filter_by(id=id_).delete()
db.session.commit()
@@ -76,7 +95,7 @@ def test_post_invalid_schema(client, dashboard_id: int):
assert resp.status_code == 400
def test_get(client, dashboard_id: int):
def test_get(client, dashboard_id: int, permalink_salt: str):
login(client, "admin")
resp = client.post(f"api/v1/dashboard/{dashboard_id}/permalink", json=STATE)
data = json.loads(resp.data.decode("utf-8"))
@@ -86,5 +105,6 @@ def test_get(client, dashboard_id: int):
result = json.loads(resp.data.decode("utf-8"))
assert result["dashboardId"] == str(dashboard_id)
assert result["state"] == STATE
db.session.query(KeyValueEntry).filter_by(uuid=key).delete()
id_ = decode_permalink_id(key, permalink_salt)
db.session.query(KeyValueEntry).filter_by(id=id_).delete()
db.session.commit()