Skip to content

Commit

Permalink
webapp: Implement basic snapshot tests (#75)
Browse files Browse the repository at this point in the history
This was supposed to work on production data extract, but it turned out
that there's no easy way to extract data conditionally and put it in for
of sql insert statements. So instead, just take fixtures and urls from
our integration tests and run snapshot testing on these.

IMO it's too early to put snapshots into the repository, so use case for
these tests is mostly local development, and for this purpose they are
hidden between snapshot-tests feature, and snapshots directory is added
go .gitignore. To use them, just run `make snapshot-tests` before and
after your changes.

While here, switch integration test fixtures to fixed timestamps to make
them suitable for snapshots.
  • Loading branch information
AMDmi3 committed Nov 28, 2024
1 parent b8fd501 commit 7b7f05b
Show file tree
Hide file tree
Showing 27 changed files with 891 additions and 31 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
/repology-webapp/tests/snapshot_tests/snapshots
44 changes: 44 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ COVERAGE_FLAGS=-Cinstrument-coverage -Zcoverage-options=condition

cov: llvm-cov

snapshot-tests:
env INSTA_UPDATE=unseen cargo test --features=snapshot-tests snapshot_tests::

insta:
cargo insta review

clean:
rm -rf repology-webapp/tests/snapshot_tests/snapshots

grcov:
rm -rf target/coverage-profile
mkdir -p target/coverage-output-grcov
Expand Down
7 changes: 7 additions & 0 deletions repology-webapp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ edition = "2021"

[features]
coverage = [] # used to calculate coverage correctly (see https://github.com/rust-lang/rust/issues/110486)
snapshot-tests = [] # enable snapshot tests

[profile.dev.package]
insta.opt-level = 3
similar.opt-level = 3

[dependencies]
anyhow = "1.0.93"
Expand Down Expand Up @@ -39,4 +44,6 @@ url-escape = "0.1.1"

[dev-dependencies]
float-cmp = "0.10.0"
insta = "1.41.1"
repology-webapp-test-utils = { path = "../repology-webapp-test-utils" }
tower-service = "0.3.3"
16 changes: 8 additions & 8 deletions repology-webapp/tests/integration_tests/fixtures/log_data.sql
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
INSERT INTO runs(id, type, repository_id, status, start_ts, finish_ts, num_lines, num_warnings, num_errors) VALUES
(1, 'fetch', 1, 'running', now() - interval '1h', NULL, NULL, NULL, NULL),
(2, 'fetch', 1, 'successful', now() - interval '1h', now() + interval '5 second', 1, 2, 3);
(1, 'fetch', 1, 'running', '2024-01-01 00:00:00', NULL, NULL, NULL, NULL),
(2, 'fetch', 1, 'successful', '2024-01-01 00:00:00', '2124-01-01 00:00:00', 1, 2, 3);

INSERT INTO log_lines(run_id, lineno, timestamp, severity, message) VALUES
(1, 1, now() + interval '5 second', 'notice', 'Hello, world!'),
(1, 2, now() + interval '5 second', 'warning', 'Hello, world!'),
(1, 3, now() + interval '5 second', 'error', 'Hello, world!'),
(2, 1, now() + interval '5 second', 'notice', 'Hello, world!'),
(2, 2, now() + interval '5 second', 'warning', 'Hello, world!'),
(2, 3, now() + interval '5 second', 'error', 'Hello, world!');
(1, 1, '2024-01-01 00:00:01', 'notice', 'Hello, world!'),
(1, 2, '2024-01-01 00:00:02', 'warning', 'Hello, world!'),
(1, 3, '2024-01-01 00:00:03', 'error', 'Hello, world!'),
(2, 1, '2024-01-01 00:00:01', 'notice', 'Hello, world!'),
(2, 2, '2024-01-01 00:00:02', 'warning', 'Hello, world!'),
(2, 3, '2024-01-01 00:00:03', 'error', 'Hello, world!');
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
INSERT INTO maintainers(id, maintainer, orphaned_at) VALUES
(1, '[email protected]', now() - interval '7 day');
(1, '[email protected]', '2024-01-01 00:00:00'),
(2, '[email protected]', '2124-01-01 00:00:00');

INSERT INTO maintainers(id, maintainer, num_packages, num_projects, counts_per_repo, num_projects_per_category) VALUES
(2, '[email protected]', 10, 10, '{"freebsd":[10,11,12,13,14,15]}'::jsonb, '{"games":10}'::jsonb),
(3, 'fallback-mnt-foo@repology', 1, 1, '{"freebsd":[1,1,1,1,1,1]}'::jsonb, '{"games":10}'::jsonb),
(4, '[email protected]', 10, 10, '{"freebsd":[10,11,12,13,14]}'::jsonb, '{"games":10}'::jsonb);
(3, '[email protected]', 10, 10, '{"freebsd":[10,11,12,13,14,15]}'::jsonb, '{"games":10}'::jsonb),
(4, 'fallback-mnt-foo@repology', 1, 1, '{"freebsd":[1,1,1,1,1,1]}'::jsonb, '{"games":10}'::jsonb),
(5, '[email protected]', 10, 10, '{"freebsd":[10,11,12,13,14]}'::jsonb, '{"games":10}'::jsonb);
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
INSERT INTO maintainer_repo_metapackages_events(repository_id, maintainer_id, ts, metapackage_id, type, data) VALUES
(1, 1, now() + interval '5 second', 1, 'added', '{}'::jsonb),
(1, 1, now() + interval '5 second', 1, 'removed', '{}'::jsonb),
(1, 1, now() + interval '5 second', 1, 'uptodate', '{"version": "111"}'::jsonb),
(1, 1, now() + interval '5 second', 1, 'outdated', '{"version": "222", "newest_versions": ["333", "444"]}'::jsonb),
(1, 1, now() + interval '5 second', 1, 'outdated', '{"version": "555"}'::jsonb),
(1, 1, now() + interval '5 second', 1, 'ignored', '{"version": "666"}'::jsonb);
-- same time as we're also testing stable ordering by type
(1, 1, '2124-01-01 00:00:00', 1, 'added', '{}'::jsonb),
(1, 1, '2124-01-01 00:00:00', 1, 'removed', '{}'::jsonb),
(1, 1, '2124-01-01 00:00:00', 1, 'uptodate', '{"version": "111"}'::jsonb),
(1, 1, '2124-01-01 00:00:00', 1, 'outdated', '{"version": "222", "newest_versions": ["333", "444"]}'::jsonb),
(1, 1, '2124-01-01 00:00:00', 1, 'outdated', '{"version": "555"}'::jsonb),
(1, 1, '2124-01-01 00:00:00', 1, 'ignored', '{"version": "666"}'::jsonb);
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,44 @@ INSERT INTO repositories(
'orphaned',
'Orphaned',
'legacy',
now() - interval '2 week',
now() - interval '1 week',
'2023-01-01 00:00:00',
'2024-01-01 00:00:00',
'{}'::jsonb,
0,
NULL
),
(
2,
'orphaned_in_future',
'orphaned_in_future',
'Orphaned in future',
'legacy',
'2023-01-01 00:00:00',
'2124-01-01 00:00:00',
'{}'::jsonb,
0,
NULL
),
(
3,
'stripped',
'stripped',
'Stripped',
'active',
now() - interval '2 week',
now() + interval '5 second',
'2023-01-01 00:00:00',
'2124-01-01 00:00:00',
'{}'::jsonb,
1,
NULL
),
(
3,
4,
'good',
'good',
'Good',
'active',
now() - interval '2 week',
now() + interval '5 second',
'2023-01-01 00:00:00',
'2124-01-01 00:00:00',
'{"repolinks":[{"url":"https://example.com/goodrepo","desc":"Repository homepage"}]}'::jsonb,
1,
'{0,1,7,9,19}'::integer[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
INSERT INTO repository_events(repository_id, ts, metapackage_id, type, data) VALUES
(1, now() + interval '5 second', 1, 'added', '{}'::jsonb),
(1, now() + interval '5 second', 1, 'removed', '{}'::jsonb),
(1, now() + interval '5 second', 1, 'uptodate', '{"version": "111"}'::jsonb),
(1, now() + interval '5 second', 1, 'outdated', '{"version": "222", "newest_versions": ["333", "444"]}'::jsonb),
(1, now() + interval '5 second', 1, 'outdated', '{"version": "555"}'::jsonb),
(1, now() + interval '5 second', 1, 'ignored', '{"version": "666"}'::jsonb);
-- same time as we're also testing stable ordering by type
(1, '2124-01-01 00:00:00', 1, 'added', '{}'::jsonb),
(1, '2124-01-01 00:00:00', 1, 'removed', '{}'::jsonb),
(1, '2124-01-01 00:00:00', 1, 'uptodate', '{"version": "111"}'::jsonb),
(1, '2124-01-01 00:00:00', 1, 'outdated', '{"version": "222", "newest_versions": ["333", "444"]}'::jsonb),
(1, '2124-01-01 00:00:00', 1, 'outdated', '{"version": "555"}'::jsonb),
(1, '2124-01-01 00:00:00', 1, 'ignored', '{"version": "666"}'::jsonb);
8 changes: 8 additions & 0 deletions repology-webapp/tests/integration_tests/maintainer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ async fn test_maintainer(pool: PgPool) {
html_ok "allow_empty_tags,warnings_fatal",
contains "Gone maintainer",
);
check_response!(
pool,
"/maintainer/[email protected]",
status NOT_FOUND,
content_type "text/html",
html_ok "allow_empty_tags,warnings_fatal",
contains "Gone maintainer",
);

check_response!(
pool,
Expand Down
8 changes: 8 additions & 0 deletions repology-webapp/tests/snapshot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2024 Dmitry Marakasov <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#![cfg(feature = "snapshot-tests")]
#![feature(coverage_attribute)]
#![coverage(off)]

mod snapshot_tests;
23 changes: 23 additions & 0 deletions repology-webapp/tests/snapshot_tests/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: Copyright 2024 Dmitry Marakasov <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

use sqlx::PgPool;

use super::uri_snapshot_test;

#[sqlx::test(migrator = "repology_common::MIGRATOR", fixtures("api_data"))]
async fn test_api_v1_project(pool: PgPool) {
uri_snapshot_test(pool.clone(), "/api/v1/project/nonexistent").await;
uri_snapshot_test(pool.clone(), "/api/v1/project/full").await;
uri_snapshot_test(pool.clone(), "/api/v1/project/minimal").await;
uri_snapshot_test(pool.clone(), "/api/v1/project/vulnerable").await;
}

#[sqlx::test(
migrator = "repology_common::MIGRATOR",
fixtures("common_repositories", "projects_data")
)]
async fn test_api_v1_projects(pool: PgPool) {
uri_snapshot_test(pool.clone(), "/api/v1/projects/pkg_foo/").await;
uri_snapshot_test(pool.clone(), "/api/v1/projects/?search=bar").await;
}
Loading

0 comments on commit 7b7f05b

Please sign in to comment.