summaryrefslogtreecommitdiff
path: root/server/szurubooru/tests/func/test_metrics.py
diff options
context:
space:
mode:
Diffstat (limited to 'server/szurubooru/tests/func/test_metrics.py')
-rw-r--r--server/szurubooru/tests/func/test_metrics.py459
1 files changed, 459 insertions, 0 deletions
diff --git a/server/szurubooru/tests/func/test_metrics.py b/server/szurubooru/tests/func/test_metrics.py
new file mode 100644
index 0000000..c33be62
--- /dev/null
+++ b/server/szurubooru/tests/func/test_metrics.py
@@ -0,0 +1,459 @@
+import pytest
+from szurubooru import db, model
+from szurubooru.func import metrics
+
+
+def test_serialize_metric(tag_category_factory, tag_factory):
+ cat = tag_category_factory(name="cat")
+ tag = tag_factory(names=["tag1"], category=cat)
+ metric = model.Metric(tag=tag, min=1, max=2)
+ db.session.add(metric)
+ db.session.flush()
+ result = metrics.serialize_metric(metric)
+ assert result == {
+ "version": 1,
+ "min": 1,
+ "max": 2,
+ "exact_count": 0,
+ "range_count": 0,
+ "tag": {
+ "names": ["tag1"],
+ "category": "cat",
+ "description": None,
+ "usages": 0,
+ },
+ }
+
+
+def test_serialize_post_metric(post_factory, tag_factory, metric_factory):
+ tag = tag_factory(names=["mytag"])
+ post = post_factory(id=456, tags=[tag])
+ metric = metric_factory(tag)
+ post_metric = model.PostMetric(post=post, metric=metric, value=-12.3)
+ db.session.add_all([post, tag, metric, post_metric])
+ db.session.flush()
+ result = metrics.serialize_post_metric(post_metric)
+ assert result == {
+ "tag_name": "mytag",
+ "post_id": 456,
+ "value": -12.3,
+ }
+
+
+def test_serialize_post_metric_range(post_factory, tag_factory, metric_factory):
+ tag = tag_factory(names=["mytag"])
+ post = post_factory(id=456, tags=[tag])
+ metric = metric_factory(tag)
+ post_metric_range = model.PostMetricRange(
+ post=post, metric=metric, low=-1.2, high=3.4)
+ db.session.add_all([post, tag, metric, post_metric_range])
+ db.session.flush()
+ result = metrics.serialize_post_metric_range(post_metric_range)
+ assert result == {
+ "tag_name": "mytag",
+ "post_id": 456,
+ "low": -1.2,
+ "high": 3.4
+ }
+
+
+def test_try_get_metric_by_tag_name(tag_factory, metric_factory):
+ tag = tag_factory(names=["mytag"])
+ metric = metric_factory(tag)
+ db.session.add_all([tag, metric])
+ db.session.flush()
+ assert metrics.try_get_metric_by_tag_name("unknown") is None
+ assert metrics.try_get_metric_by_tag_name("mytag") is metric
+
+
+def test_try_get_post_metric(
+ post_factory, metric_factory, post_metric_factory):
+ metric1 = metric_factory()
+ metric2 = metric_factory()
+ post = post_factory(tags=[metric1.tag, metric2.tag])
+ post_metric = post_metric_factory(post=post, metric=metric1)
+ db.session.add_all([post, metric1, metric2, post_metric])
+ db.session.flush()
+ assert metrics.try_get_post_metric(post, metric2) is None
+ assert metrics.try_get_post_metric(post, metric1) is post_metric
+
+
+def test_try_get_post_metric_range(
+ post_factory, metric_factory, post_metric_range_factory):
+ metric1 = metric_factory()
+ metric2 = metric_factory()
+ post = post_factory(tags=[metric1.tag, metric2.tag])
+ post_metric_range = post_metric_range_factory(post=post, metric=metric1)
+ db.session.add_all([post, metric1, metric2, post_metric_range])
+ db.session.flush()
+ assert metrics.try_get_post_metric_range(post, metric2) is None
+ assert metrics.try_get_post_metric_range(post, metric1) is post_metric_range
+
+
+def test_get_all_metrics(metric_factory):
+ metric1 = metric_factory()
+ metric2 = metric_factory()
+ metric3 = metric_factory()
+ db.session.add_all([metric1, metric2, metric3])
+ db.session.flush()
+ all_metrics = metrics.get_all_metrics()
+ assert len(all_metrics) == 3
+ assert metric1 in all_metrics
+ assert metric2 in all_metrics
+ assert metric3 in all_metrics
+
+
+def test_get_all_metric_tag_names(tag_factory, metric_factory):
+ tag1 = tag_factory(names=["abc", "def"])
+ tag2 = tag_factory(names=["ghi"])
+ metric1 = metric_factory(tag=tag1)
+ metric2 = metric_factory(tag=tag2)
+ db.session.add_all([metric1, metric2])
+ db.session.flush()
+ assert metrics.get_all_metric_tag_names() == ["abc", "def", "ghi"]
+
+
+def test_create_metric(tag_factory):
+ tag = tag_factory()
+ db.session.add(tag)
+ new_metric = metrics.create_metric(tag, 1, 2)
+ assert new_metric is not None
+ db.session.flush()
+ assert tag.metric is not None
+ assert tag.metric.min == 1
+ assert tag.metric.max == 2
+
+
+def test_create_metric_with_existing_metric(tag_factory):
+ tag = tag_factory()
+ tag.metric = model.Metric()
+ with pytest.raises(metrics.MetricAlreadyExistsError):
+ metrics.create_metric(tag, 1, 2)
+
+
+def test_create_metric_with_invalid_params(tag_factory):
+ tag = tag_factory()
+ with pytest.raises(metrics.InvalidMetricError):
+ metrics.create_metric(tag, 2, 1)
+
+
+def test_update_or_create_metric(tag_factory):
+ tag = tag_factory()
+ db.session.add(tag)
+ new_metric = metrics.update_or_create_metric(tag, {"min": 1, "max": 2})
+ assert new_metric is not None
+ db.session.flush()
+ assert tag.metric is not None
+ assert tag.metric.min == 1
+ assert tag.metric.max == 2
+ assert tag.metric.version == 1
+
+ new_metric = metrics.update_or_create_metric(tag, {"min": 3, "max": 4})
+ assert new_metric is None
+ db.session.flush()
+ assert tag.metric.min == 3
+ assert tag.metric.max == 4
+ assert tag.metric.version == 2
+
+
+@pytest.mark.parametrize("params", [
+ {"min": 1}, {"max": 2}, {"min": 2, "max": 1}
+])
+def test_update_or_create_metric_with_invalid_params(tag_factory, params):
+ tag = tag_factory()
+ with pytest.raises(metrics.InvalidMetricError):
+ metrics.update_or_create_metric(tag, params)
+
+
+# Post metrics
+
+def test_update_or_create_post_metric_without_tag(post_factory, metric_factory):
+ post = post_factory()
+ metric = metric_factory()
+ with pytest.raises(metrics.PostMissingTagError):
+ metrics.update_or_create_post_metric(post, metric, 1.5)
+
+
+def test_update_or_create_post_metric_with_value_out_of_range(
+ post_factory, metric_factory):
+ metric = metric_factory()
+ post = post_factory(tags=[metric.tag])
+ with pytest.raises(metrics.MetricValueOutOfRangeError):
+ metrics.update_or_create_post_metric(post, metric, -99)
+
+
+def test_update_or_create_post_metric_create(post_factory, metric_factory):
+ metric = metric_factory()
+ post = post_factory(tags=[metric.tag])
+ db.session.add(metric)
+ db.session.flush()
+ post_metric = metrics.update_or_create_post_metric(post, metric, 1.5)
+ assert post_metric.value == 1.5
+
+
+def test_update_or_create_post_metric_update(post_factory, metric_factory):
+ metric = metric_factory()
+ post1 = post_factory(tags=[metric.tag])
+ post2 = post_factory(tags=[metric.tag])
+ post_metric1 = model.PostMetric(post=post1, metric=metric, value=1.2)
+ post_metric2 = model.PostMetric(post=post2, metric=metric, value=5.6)
+ db.session.add_all([post1, post2, post_metric1, post_metric2])
+ db.session.flush()
+ assert post_metric1.version == 1
+ assert post_metric2.version == 1
+
+ metrics.update_or_create_post_metric(post1, metric, 3.4)
+ db.session.flush()
+
+ assert db.session.query(model.PostMetric).count() == 2
+ assert post_metric1.value == 3.4
+ assert post_metric1.version == 2
+ assert post_metric2.value == 5.6
+ assert post_metric2.version == 1
+
+
+def test_update_or_create_post_metrics_missing_tag(
+ post_factory, tag_factory, metric_factory):
+ post = post_factory()
+ tag = tag_factory(names=["tag1"])
+ metric = metric_factory(tag)
+ db.session.add(metric)
+ db.session.flush()
+ data = [{"tag_name": "tag1", "value": 1.5}]
+ with pytest.raises(metrics.PostMissingTagError):
+ metrics.update_or_create_post_metrics(post, data)
+
+
+@pytest.mark.parametrize("params", [
+ [{}],
+ [{"tag_name": "tag"}],
+ [{"value": 1.5}]
+])
+def test_update_or_create_post_metrics_with_missing_fields(
+ params, post_factory):
+ post = post_factory()
+ with pytest.raises(metrics.InvalidMetricError):
+ metrics.update_or_create_post_metrics(post, params)
+
+
+def test_update_or_create_post_metrics_with_invalid_tag(
+ post_factory, tag_factory):
+ tag = tag_factory(names=["tag1"])
+ post = post_factory(tags=[tag])
+ db.session.add(tag)
+ db.session.flush()
+ data = [{"tag_name": "tag1", "value": 2}]
+ with pytest.raises(metrics.MetricDoesNotExistsError):
+ metrics.update_or_create_post_metrics(post, data)
+
+
+def test_update_or_create_post_metrics(
+ post_factory, tag_factory, metric_factory):
+ tag1 = tag_factory(names=["tag1"])
+ tag2 = tag_factory(names=["tag2"])
+ post = post_factory(tags=[tag1, tag2])
+ metric1 = metric_factory(tag1)
+ metric2 = metric_factory(tag2)
+ db.session.add_all([metric1, metric2])
+ db.session.flush()
+
+ data = [
+ {"tag_name": "tag1", "value": 1.2},
+ {"tag_name": "tag2", "value": 3.4},
+ ]
+ metrics.update_or_create_post_metrics(post, data)
+ db.session.flush()
+
+ assert len(post.metrics) == 2
+ assert post.metrics[0].value == 1.2
+ assert post.metrics[1].value == 3.4
+
+
+def test_update_or_create_post_metrics_with_trim(
+ post_factory, tag_factory, metric_factory, post_metric_factory):
+ tag1 = tag_factory(names=["tag1"])
+ tag2 = tag_factory(names=["tag2"])
+ post = post_factory(tags=[tag1, tag2])
+ metric1 = metric_factory(tag1)
+ metric2 = metric_factory(tag2)
+ post_metric = post_metric_factory(post=post, metric=metric1, value=1.2)
+ db.session.add_all([post, tag1, tag2, metric1, metric2, post_metric])
+ db.session.flush()
+ assert len(post.metrics) == 1
+ assert post.metrics[0].metric == metric1
+ assert post.metrics[0].value == 1.2
+
+ data = [
+ {"tag_name": "tag2", "value": 3.4},
+ ]
+ metrics.update_or_create_post_metrics(post, data)
+ db.session.flush()
+
+ assert len(post.metrics) == 1
+ assert post.metrics[0].metric == metric2
+ assert post.metrics[0].value == 3.4
+
+
+# Post metric ranges
+
+def test_update_or_create_post_metric_range_without_tag(
+ post_factory, metric_factory):
+ post = post_factory()
+ metric = metric_factory()
+ with pytest.raises(metrics.PostMissingTagError):
+ metrics.update_or_create_post_metric_range(post, metric, 2, 3)
+
+
+@pytest.mark.parametrize("low, high", [
+ (-99, 1), (1, 99),
+])
+def test_update_or_create_post_metric_range_with_values_out_of_range(
+ low, high, post_factory, metric_factory):
+ metric = metric_factory()
+ post = post_factory(tags=[metric.tag])
+ with pytest.raises(metrics.MetricValueOutOfRangeError):
+ metrics.update_or_create_post_metric_range(post, metric, low, high)
+
+
+def test_update_or_create_post_metric_range_create(
+ post_factory, metric_factory):
+ metric = metric_factory()
+ post = post_factory(tags=[metric.tag])
+ db.session.add(metric)
+ db.session.flush()
+ post_metric_range = metrics.update_or_create_post_metric_range(
+ post, metric, 2, 3)
+ assert post_metric_range.low == 2
+ assert post_metric_range.high == 3
+
+
+def test_update_or_create_post_metric_range_update(
+ post_factory, metric_factory):
+ metric = metric_factory()
+ post = post_factory(tags=[metric.tag])
+ post_metric_range = model.PostMetricRange(
+ post=post, metric=metric, low=2, high=3)
+ db.session.add(post_metric_range)
+ db.session.flush()
+ assert post_metric_range.version == 1
+
+ metrics.update_or_create_post_metric_range(post, metric, 4, 5)
+ db.session.flush()
+
+ assert post_metric_range.low == 4
+ assert post_metric_range.high == 5
+ assert post_metric_range.version == 2
+
+
+def test_update_or_create_post_metric_ranges_missing_tag(
+ post_factory, tag_factory, metric_factory):
+ post = post_factory()
+ tag = tag_factory(names=["tag1"])
+ metric = metric_factory(tag)
+ db.session.add(metric)
+ db.session.flush()
+ data = [{"tag_name": "tag1", "low": 2, "high": 3}]
+ with pytest.raises(metrics.PostMissingTagError):
+ metrics.update_or_create_post_metric_ranges(post, data)
+
+
+@pytest.mark.parametrize("params", [
+ [{}],
+ [{"tag_name": "tag"}],
+ [{"tag_name": "tag", "low": 2}],
+ [{"low": 2, "high": 3}],
+])
+def test_update_or_create_post_metric_ranges_with_missing_fields(
+ params, post_factory, tag_factory):
+ tag = tag_factory(names=["tag"])
+ post = post_factory(tags=[tag])
+ with pytest.raises(metrics.InvalidMetricError):
+ metrics.update_or_create_post_metric_ranges(post, params)
+
+
+def test_update_or_create_post_metric_ranges_with_invalid_tag(
+ post_factory, tag_factory):
+ tag = tag_factory(names=["tag1"])
+ post = post_factory(tags=[tag])
+ db.session.add(tag)
+ db.session.flush()
+ data = [{"tag_name": "tag1", "low": 2, "high": 3}]
+ with pytest.raises(metrics.MetricDoesNotExistsError):
+ metrics.update_or_create_post_metric_ranges(post, data)
+
+
+def test_update_or_create_post_metric_ranges_with_invalid_values(
+ post_factory, tag_factory, metric_factory):
+ tag = tag_factory(names=["tag1"])
+ post = post_factory(tags=[tag])
+ metric = metric_factory(tag=tag)
+ db.session.add_all([metric, tag])
+ db.session.flush()
+ data = [
+ {"tag_name": "tag1", "low": 4, "high": 2},
+ ]
+ with pytest.raises(metrics.InvalidMetricError):
+ metrics.update_or_create_post_metric_ranges(post, data)
+
+
+def test_update_or_create_post_metric_ranges(
+ post_factory, tag_factory, metric_factory):
+ tag1 = tag_factory(names=["tag1"])
+ tag2 = tag_factory(names=["tag2"])
+ post = post_factory(tags=[tag1, tag2])
+ metric1 = metric_factory(tag1)
+ metric2 = metric_factory(tag2)
+ db.session.add_all([metric1, metric2])
+ db.session.flush()
+
+ data = [
+ {"tag_name": "tag1", "low": 2, "high": 3},
+ {"tag_name": "tag2", "low": 4, "high": 5},
+ ]
+ metrics.update_or_create_post_metric_ranges(post, data)
+ db.session.flush()
+
+ assert len(post.metric_ranges) == 2
+ assert post.metric_ranges[0].low == 2
+ assert post.metric_ranges[0].high == 3
+ assert post.metric_ranges[1].low == 4
+ assert post.metric_ranges[1].high == 5
+
+
+def test_update_or_create_post_metric_ranges_with_trim(
+ post_factory, tag_factory, metric_factory, post_metric_range_factory):
+ tag1 = tag_factory(names=["tag1"])
+ tag2 = tag_factory(names=["tag2"])
+ post = post_factory(tags=[tag1, tag2])
+ metric1 = metric_factory(tag1)
+ metric2 = metric_factory(tag2)
+ post_metric_range = post_metric_range_factory(
+ post=post, metric=metric1, low=1, high=2)
+ db.session.add_all([post, tag1, tag2, metric1, metric2, post_metric_range])
+ db.session.flush()
+ assert len(post.metric_ranges) == 1
+ assert post.metric_ranges[0].metric == metric1
+ assert post.metric_ranges[0].low == 1
+ assert post.metric_ranges[0].high == 2
+
+ data = [
+ {"tag_name": "tag2", "low": 3, "high": 4},
+ ]
+ metrics.update_or_create_post_metric_ranges(post, data)
+ db.session.flush()
+
+ assert len(post.metric_ranges) == 1
+ assert post.metric_ranges[0].metric == metric2
+ assert post.metric_ranges[0].low == 3
+ assert post.metric_ranges[0].high == 4
+
+
+def test_delete_metric(metric_factory):
+ metric1 = metric_factory()
+ metric2 = metric_factory()
+ db.session.add_all([metric1, metric2])
+ db.session.flush()
+ assert db.session.query(model.Metric).count() == 2
+ metrics.delete_metric(metric2)
+ db.session.flush()
+ assert db.session.query(model.Metric).count() == 1